Spiele(reien) mit und durch PHP *

November 2012

Dezember 2012

Dezember 2012

Februar 2014
* Um Screens, Beschreibungen und Besonderheiten der Projekte zu sehen, bitte eine Vorschaubox anklicken.
Worttausch bei "Der Wolf und die 7 Geißlein" | November 2012
Eines Tages kam ich mit einer Facette der Macht PHP's in Berührung, die mich wieder einmal faszinierte. Es fing ganz harmlos an: mit dem "string", einem der 8 PHP-Datentypen. "string" = Zeichenkette, die aus Buchstaben, Ziffern und/ oder Sonderzeichen bestehen kann. Zum Beispiel aus den Zeichen "g", "e", "i" und "ß"...
... oder sogar: aus dem kompletten Text eines Märchens, samt HTML-Tags! Wieso das so faszinierend ist? Weil man mit PHP-Strings seeehr viel machen kann. Strings können in Variablen ($) gespeichert werden... um dann ganz viele verschiedene Sachen mit ihnen anzustellen.Doch bevor es hier zu theoretisch wird:
Worum geht's bei diesem Spiel, und was passiert?
Es geht um das schöne Märchen "Der Wolf und die 7 Geißlein": Ein gieriger Wolf schafft es durch List und Tücke, 7 Geißlein zu fressen... zum Glück überleben sie! Es ist ein Märchen, in dem oft das Wort "Geiß" bzw. ein zusammengesetztes Wort mit "Geiß-" vorkommt. So wird das Märchen dem Spieler zunächst präsentiert:

Das Märchen handelt von einer Mutter Geiß und ihren Kindern. Da ist es nur natürlich, dass das Wort bzw. der Wortstamm "Geiß" wiederholt werden. Da ich aber einen Aufhänger brauche, um meine geplante PHP-Spielerei begründen zu können, frage ich nach ca. 2/3 des Textes, ob das ständige "Geiß" nicht nerve... und biete an, das Wort auszutauschen.

Der Spieler kann jetzt ein Wort seiner Wahl in das Textfeld eingeben, das anstelle des "Geiß" verwendet werden soll, und dann den Button "Wort auswechseln" klicken. Was das PHP daraufhin wirklich macht, wird gleich erklärt. Einfach & verständlich, doch PHP-funktionell nicht korrekt ausgedrückt: die Funktion sucht nach Geiß, "schneidet" es aus, und "klebt" an dessen Stelle des Spielers Wort.




Dann erscheint der geänderte Märchentext, der so gestaltet ist wie der Ausgangstext. - Die Aufforderung, am Anfang einen Großbuchstaben zu nehmen, hat nur mit der Optik zu tun. Ob Groß- oder Kleinbuchstaben oder Zahlen (oder gar nichts) eingegeben werden, spielt für die Funktionalität keine Rolle. Nehmen wir an, der Spieler gibt Peter ein... so bekommt er folgendes Ergebnis:

Was macht das PHP im Hintergrund...? Wie wird "Geiß" ersetzt durch des Spielers Wort?
Es gibt 2 Dateien: die maerchen.html und die maerchen.php. Erstere enthält das bebilderte Märchen. Der Märchentext ist eingeschlossen in ein Formular mit dem Kopf: <form action="maerchen.php" method="post">. Hier wird also festgelegt, wohin die Daten (Eingabe des Spielers) gesendet werden sollen: an die maerchen.php. (Bei meinem Märchenquiz, siehe oben PHP-Spielerei 3, werden die Daten innerhalb der .php versendet)
Wie oben beschrieben, wird der Spieler mitten im Märchentext zur Eingabe eines Ersetze-Worts aufgefordert. Dementsprechend gibt es ein Text-Eingabefeld mit dem für später wichtigen name="wortwahl" und den Submit-Button "Wort ersetzen". Sobald der Spieler ein Wort eingegeben hat und den Button geklickt, sendet das Formular das Ersetze-Wort an die maerchen.php und setzt damit die PHP-Funktion in Gang.
Hier in der .php-Datei ist zuerst die Variable $text definiert, die aus dem Märchentext samt Bildern und HTML-Tags besteht und durch die heredoc-Syntax als String gekennzeichnet wird: <<<. Nach diesem Operator folgt der Bezeichner EOT, der den Beginn des Variablen-Inhalts anzeigt. In der nächsten Zeile startet das Märchentext-HTML. Nach dem letzten schließenden p-Tag des Textes zeigt das erneute Setzen von EOT; (End Of Text) das Ende des Variablen-Inhalts an:
$text=<<<EOT
<h3>Der Wolf und die sieben Geißlein</h3>
<img class="bild" src="images/geiss.jpg" />
<p><span id="startworte">Es war einmal...</span> eine alte Geiß, die hatte
sieben junge Geißlein, und hatte sie lieb, [...]
(und weiter kompletter HTML-Quelltext, 1 zu 1 wie in maerchen.html, doch OHNE "Stop!..."-Absatz)
[...] Brunnen herum.</p>
EOT;
$text=<<<EOT
<h3>Der Wolf und die sieben Geißlein</h3>
<img class="bild" src="images/geiss.jpg" />
<p><span id="startworte">Es war einmal...</span> eine alte Geiß, die hatte sieben junge Geißlein, und [...]
(und weiter kompletter HTML-Quelltext, 1 zu 1 wie in maerchen.html, doch OHNE "Stop!..."-Absatz)
[...] Brunnen herum.</p>
EOT;
Von der Überschrift "Der Wolf..." an bis zum letzten Wort des Märchens ist der Quelltext nun als String in die Variable $text gefüllt. Der "Stop!..."-Absatz samt Texteingabefeld und Submit-Button "Wort auswechseln" ist hier natürlich nicht mehr enthalten - im veränderten Märchentext wird er nicht mehr angezeigt, hier ist das "Geiß" ja schon ausgetauscht.
Nachdem mit dem schließenden EOT; die Definition der Variable $text abgeschlossen ist, kommt es zum wirklich spannenden Teil des PHP-Codes, der die eigentliche "Suchen & Ersetzen"-Arbeit macht:
2 $ersetzestring=$_POST["wortwahl"];
3 $auseinandergenommen = explode($suchstring,$text);
4 $runde=1;
5 foreach($auseinandergenommen as $versatzstueck)
6 {
7 echo $versatzstueck.$ersetzestring;
8 $runde++;
9 }
10 ?>
Zuerst werden vier Variablen definiert. Zeile 1: der Suchstring "Geiß"", das auszuschneidende Wort. Zeile 2: der Ersetzestring $_POST["wortwahl"], also die Worteingabe des Spielers, die aus der maerchen.html gesendet wird. Das Texteingabefeld in der maerchen.html hatte deshalb den eindeutigen name="wortwahl" bekommen.
Zeile 3: Die Variable $auseinandergenommen wird aus der PHP-Funktion explode generiert. Explode "zerschneidet" den Text: es durchsucht die Variable $text (zweiter Parameter in der explode-Klammer); oben in erster "Code-Box" definiert mit heredoc: $text enthält komplett den Märchentext samt Tags und Images, wie erläutert.
explode durchsucht den Text nun bis zum ersten Vorkommen des $suchstring Geiß (erster Parameter in Klammer) und macht einen Schnitt. Nach Geiß der nächste Schnitt. Dann sucht es wieder Geiß, schneidet davor und danach, sucht das nächste... Als Ergebnis enthält die Variable $auseinandergenommen ein Array mit den Textfragmenten, die jeweils zwischen Geiß liegen PLUS alle HTML-Tags. Die "Geiß" fallen weg, sie "explodieren".
Als vierte und letzte Variable wird die $runde auf 1 gesetzt. - Die foreach-Schleife (Zeile 5 - 9) durchläuft das Array: durch den Befehl $auseinandergenommen as $versatzstueck wird jedem Array-Bestandteil, also jedem Textfragment, die Variable $versatzstueck zugewiesen.
In den geschweiften Klammern { } wird mit dem Befehl echo die Wiedergabe im HTML angewiesen: ein Versatzstück plus Ersetzestring - das Aneinandersetzen beider wird durch den Punkt . befohlen. Die $runde iteriert durch das ++, das heißt, der Befehl echo wird so lange ausgeführt, bis das Array mit den Textfragmenten durchlaufen ist.
Das wiederum heißt: so lange, bis alle Textteile plus jeweils Ersetzestring im HTML ausgegeben wurden. Der Spieler sieht also den Text mit dem von ihm gewählten Wort. Style und Bilder des ursprünglichen Textes sind 1 zu 1 übernommen, da echo auch die Tags beinhaltet und das Style-Sheet greift.

Zucker- & Vitaminshop: Cupcakes und Früchte bestellbar!
In meiner dritten Woche PHP-Unterricht gestaltete und schrieb ich diesen erstaunlichen Shop. "Erstaunlich", weil ich den PHP-Code nicht mehr bis ins Detail nachvollziehen kann geschweige denn umschreiben könnte. Dieser Shop bietet neben der Startseite Bestellseiten für Cupcakes und für Früchte. Details und Eigenschaften der Produkte finden sich auf den "Erklär"-Seiten; es gibt Warenkorb und Kasse. - Die herrlichen Produkte sind handgezeichnet mit Illustrator.

Wie geht so ein Einkauf vor sich?
Die Startseite bietet Links zur Cupcake- und Früchte-Bestellseite. Die Bestellseite für Cupcakes zeigt die 4 zur Auswahl stehenden Cupcakes, ihre Artikelnummer, den Namen und den Stückpreis. In das Eingabefeld "Menge" kann die Anzahl eingetragen werden. Wird mit der Maus über die Bilder der Artikel gefahren, erscheint ein Detailbild des Cakes. Klickt man auf das grüne "Mehr erfahren?" in der Überschrift, öffnet sich die Cupcake-Erklärseite. Hier wird jeder Cake gezeigt und beschrieben, je durch Klick auf dessen Namen.

Zurück beim Bestellformular, kann, sofern noch nicht geschehen, die je gewünschte Menge bei den je gewünschten Cakes eingetragen werden. Der Button "In den Warenkorb" führt zur Übersichtsseite der bisherigen Bestellung, die warenkorb.php. Hier sind die Artikelnummern der eben gewählten Produkte, ihre Sortenbezeichnung, die jeweilige Menge, der Einzelpreis, und darunter die Gesamtmenge der Artikel sowie der Gesamtpreis angegeben.
Nun kann der Button "Jetzt bestellen" geklickt werden, oder man geht zurück zum Cupcake- oder Früchte Bestellformular oder zur Startseite. Nehmen wir an, der Einkäufer geht noch zu den Früchten und wählt zwei Artikel dazu. Wenn er dann in den Warenkorb geht, sind zu den vorher bestellten Cupcakes die Früchte hinzugekommen; d. h., auch Gesamtmenge und Gesamtpreis haben sich erhöht.

Nun kann er auf "Jetzt bestellen" klicken. Es öffnet sich eine Seite mit Formular, wo Name, Adresse und Email eingetragen werden. Wenn der Einkäufer auf "Absenden und Bestellung abschließen" klickt, öffnet sich die Bestätigungsseite der Bestellung: der Einkäufer wird namentlich angesprochen, ihm wird gezeigt, was er zu welchem Wert bestellt hat, und ihm wird mitgeteilt, wann er in etwa mit der Ware zu rechnen hat. Von hier aus kann er erneut zum Warenkorb zurückkehren. Dieser ist nun leer, und der Einkäufer hat die Wahl, wiederum zur Shop Startseite, zum Früchte oder zum Cupcake Bestellformular zu gehen.
How does it work? Anmerkungen zum PHP-Code
Ein Shopsystem in der Realität zu programmieren ist eine höchst komplexe Sache. Und auch bei diesem Zucker- & Vitaminshop, bei dem nicht "in Echt" bestellt werden kann, ist die Komplexität des Codes beeindruckend. Seine Funktionsweise hier detailliert zu erklären, würde den Rahmen sprengen. Auf einiges aber soll eingegangen werden.

1. Kommunikation der Dateien untereinander & Datensendung
Alle Dateien kommunizieren miteinander. Das muss in einem Shop so sein: Eingaben des Nutzers müssen "sich gemerkt" werden; d. h., sie müssen auch beim Klicken durch die Seiten gespeichert werden und dürfen nicht wieder verlorengehen, auch wenn der Einkäufer die Benutzeroberfläche wechselt. Das "Merken" eingegebener Daten wird durch das Setzen von Cookies erreicht; zu diesem Zweck wird am Kopf jeder Datei eine Session eröffnet: <?php session_start(); ?>
Eingegebene Daten des Nutzers werden durch die POST-Methode innerhalb der zusammengehörigen PHP-Dateien gesendet. Das Formular zur Eingabe der gewünschten Cupcakes zum Beispiel gibt den Befehl, die eingegebenen Daten (jeweilige Anzahl der Cakes) an die warenkorb.php zu senden: <form action="warenkorb.php" method="POST"> Innerhalb des Formulars ist ein Submit-Button gesetzt, der hier die Aufschrift "In den Warenkorb" trägt.
Sobald eine Eingabe gemacht ist, zum Beispiel die Zahl 3 für 3 x Minzcréme Cupcake, und dann der Submit-Button geklickt, wird diese "3" an die warenkorb.php gesendet. Da das Texteingabefeld für diesen Cake mit einem eindeutigen Key bezeichnet ist, "weiß" der Warenkorb, dass sich die "3" auf genau diesen Cake bezieht (siehe unten Codeabschnitt Zeile 6).
2. Auslesung von Artikeldaten beim Bestellformular
Normale Web-Shops haben Datenbanken im Hintergrund. Hier sind alle Artikeldaten gespeichert sowie alle Daten der Einkäufer; jeder einzelne Einkauf: wer hat wann was bestellt. Der Einkauf an sich funktioniert nicht ohne die Kommunikation mit der Datenbank. Anstelle einer Datenbank gibt es hier im Zucker- & Vitaminshop eine wichtige Datei, die den Datenspeicher darstellt und in alle zugehörigen Dateien inkludiert ist: die artikel.inc2.php.
Der Befehl zum Einbinden dieses Datenspeichers (über dem <!DOCTYPE html> Tag der Datei) sieht so aus:
session_start();
include("artikel.inc2.php");
?>
Die inkludierte Datei enthält alle Informationen zu den Produkten wie z. B. Beschreibung und Einzelpreis. Hier sind die beiden Produktgruppen Cupcakes und Früchte in mehrdimensionalen Arrays dargestellt. Der einzelne Cupcake ist dann zum Beispiel ein "Ast", ein untergeordnetes Array des "Baumes" Cupcake-Array. Auf die Arrays werden aus den jeweiligen Dateien heraus zugegriffen, ihre Daten werden ausgelesen.
So zum Beispiel, um die Tabelle auf dem Cupcake-Bestellformular mit Daten zu füllen - also Artikelnummer, Sortenname, Stückpreis. Wenn nun der Shop erweitert würde, mehr Produkte hinzukämen und als Arrays im Datenspeicher angelegt, würde sich die Tabelle automatisch verlängern. So bleibt es flexibel; z. B. auch, wenn sich ein Preis ändert oder ein Produkt nicht mehr verfügbar ist. Das HTML kann unangetastet bleiben; nur die inkludierte Datei wird modifiziert.

Das input type="text", also das Eingabefeld für die Menge des zu bestellenden Cakes, wird während der Auslesung der anderen Artikeldaten auf "0" gesetzt (Zeile 6). Die Auslesung der Daten selbst ist mit einer foreach-Schleife umgesetzt und dem anschließenden Befehl list. Die ausgelesenen Daten werden je mit dem echo Befehl in eine Tabelle gerendert ausgegeben. Der Codeabschnitt zur Darstellung der Tabelle sieht so aus:
2 {
3 list($key,$sorte,$preis,$beschreibung) = $ausgabe;
4 {
5 echo "<tr><td id=\"sorten\" text-align='left'>$key</td><td id=\"sorten\">$sorte</td>";
6 echo "<td><input style='text-align:right' type='text' size='1' name='$key' value='0'>";
7 echo "</td><td id=\"sorten\">";
8 echo number_format($preis, 2, ",", ".");
9 echo " Eurodollars";
10 echo </td></tr>";
11 } // schließende Klammer des list-Befehls
12 } // schließende Klammer der foreach-Schleife
Gemäß des list-Befehls sollen alle verfügbaren Daten des Cakes aus den jeweiligen Arrays aus der artikel.inc2.php ausgelesen werden. $key ist die Artikelnummer, z. B. cc-1, der Schlüssel des Arrays. Er kommt an die erste Stelle in der Produkttabelle. $sorte ist der Artikelname, z. B. Kirschküchlein. $preis ist die Zahlenfolge des Preises. $beschreibung wird nun auch durch list ausgelesen, jedoch nicht per echo-Befehl in die Tabelle ausgegeben.
3. Auslesung von Artikeldaten auf Produkt-Erklär-Seite
Auf den zwei Erklärseiten der Cupcakes und Früchte hingegen werden die Beschreibungen ausgelesen und dargestellt. Hier gibt es ein Formular mit dem Kopf <form action="<?php echo $_SERVER["PHP_SELF"]; ?>"method="post">, das in eine Tabelle eingebettet ist. Die action des Formulars sagt aus, dass Daten hier nicht an eine andere Datei gesendet werden.
Die Tabelle enthält die Artikelbilder. Javascript ermöglicht die Detailansicht bei Hover: bei onmouseover wird die Bildquelle ausgetauscht, das Detailbild wird sichtbar; bei onmouseout wird als Bildquelle wieder die Gesamtansicht des Produktes befohlen. Jedes Bild hat einen Button unter sich mit dem Namen des Cakes. Bei Klick darauf erscheint darunter eine Beschreibung des Kuchens. Auch diese Texte sind nicht im HTML der sichtbaren Seite verankert. Sie werden aus der inkludierten Datei ausgelesen. Wie geht das?

Die Buttons sehen im HTML so aus: <input id="button1" type="submit" value="Kirschküchlein" name="beschr"> Am wichtigsten: value und name. Jeder Button jedes Kuchens hat einen anderen value: den Kuchennamen; doch alle haben denselben name: beschr. Das mag verwirrend klingen, doch hier geht es ja nur um die Buttons! Der folgende Code zeigt, wie die Artikelbeschreibung des angeklickten Cakes aus dem Datenspeicher in das Textfeld kommen.
Zuerst wird geprüft, ob ein Submit geklickt wurde (Zeile 1). Wenn ja, wird der Variablen $beschr. der Inhalt der Post-Variablen $_POST["beschr".]. zugewiesen (Zeile 3), dessen value: also z. b. Kirschküchlein oder Sahne-Caramel. Der Code "weiß" jetzt, um welchen Cake es geht; der Cake-Name ist in die Variable $beschr gefüllt.
Mit $beschr wird jetzt die switch-Anweisung durchgeführt (ab Zeile 5) - geswitcht wird der case. Z. B. im case "Kirschküchlein", d. h. wenn "Kirschküchlein" in $beschr steht, wird eine Variable $zeig (Zeile 8) gefüllt: $zeig = $cupcake_feld["cc-1"][3]; Diese Anweisung bedeutet: geh zum Array Cupcake, dann zum Küchlein mit dem Key cc-1, nimm dort den dritten Inhalt. Dies ist die Cake-Beschreibung. echo $zeig; sagt: "printe" die Beschreibung im HTML.
2 {
3 $beschr = $_POST["beschr"];
4
5 switch ($beschr)
6 {
7 case "Kirschküchlein":
8 $zeig = $cupcake_feld["cc-1"][3];
9 echo $zeig;
10 break;
11 case "Minzcreme-Praliné":
12 $zeig = $cupcake_feld["cc-2"][3];
13 echo $zeig;
14 break;
15 case "Schoko-Zuckersterne":
16 $zeig = $cupcake_feld["cc-3"][3];
17 echo $zeig;
18 break;
19 case "Sahne-Caramel":
20 $zeig = $cupcake_feld["cc-4"][3];
21 echo $zeig;
22 } // schließende Klammer der switch-Anweisung
23
24 } // schließende Klammer der if-Anweisung
Nach jeder case-Anweisung gibt es ein break; zum ersten Mal in Zeile 10: das sagt dem Code, brich hier ab und geh zum nächsten case. Im HTML dargestellt wird in dem Moment nur die Beschreibung des Cakes, dessen Button geklickt wurde; wird ein neuer Button geklickt, wird der komplette Code wieder durchlaufen und eine neue Beschreibung gezeigt.
Die Cupcakes und Früchte - fotorealistische Vektorillustrationen
Als ich im Jahre 2012 sehr viel Zeit hatte, fing ich an, Obst, Gemüse, Pflanzen, Tiere und Küchlein mit Illustrator nachzuzeichnen. Als Grundlage nahm ich Fotos. Ein Gegenstand nahm viele Tage in Anspruch, und ich entwickelte eine gewisse Meisterschaft im lebensnahen Zeichnen; jemand hielt z. B. meine Erdbeere für ein Foto. - Im PHP-Kurs, einige Monate später, war es deshalb klar für mich, was mein Übungs-Shop anbieten sollte: Cupcakes und Früchte.
Märchenquiz der Gebrüder Grimm | Dezember 2012
In diesem PHP-basierten Quiz werden 8 Fragen zu 8 berühmten Märchen gestellt. Aufhänger bzw. Motivation für dieses Quiz war damals das Kennenlernen der PHP-post-Methode im Zusammenhang mit der Switch-Case-Fallentscheidung... Bzw. If-Else-Schleife: diese Aktionsmethode, allerdings pur Javascript, kommt ebenfalls beiBerndt zum Einsatz.
Hier im Märchenquiz dient sie dazu, dem Spieler zu antworten. Sobald dieser nämlich auf eine Märchenfrage geantwortet hat, antwortet der PHP-Code ihm. Das mag jetzt noch etwas abstrakt klingen... man lese unten weiter.

Wie sind die Fragen aufgebaut?
Zu einem Märchen, z. B. der Froschkönig, wird eine Frage gestellt. Je nach Frage gibt es vier oder fünf Antwort-Alternativen, diese können durch Klick auf den Radiobutton gewählt werden. Beim Froschkönig trifft eine Antwort zu. Bei anderen Fragen wird verlangt, die zwei wahren Aussagen herauszufinden. Hier gilt es dann zunächst, die drei nicht wahren Aussagen per Ausschlussverfahren zu identifizieren.
Wie funktioniert so ein Frage-Antwort-Durchgang?
Der Spieler liest sich die Frage durch. Wie oben gezeigt, sollte er genau auf die Fragestellung achten. Unser Beispiel hier: Hänsel und Gretel. Die Frage lautet "Viele kluge Einfälle... einen davon hatte Hänsel NICHT. Welchen?" Dann werden die Einfälle erläutert, 4 an der Zahl. Jetzt muss der Spieler entscheiden und die Antwort markieren...

Wenn der Spieler falsch geraten bzw. sich falsch an das Märchen erinnert hat, kann er das im pinken Text unterhalb des Bild-Antworten-Blocks lesen. Er kann jetzt noch einmal wählen. Er kann sich auch alle Reaktionen auf alle Antworten durch Klick auf Radiobutton & Klick auf "Check" anzeigen lassen. Eine richtige Antwort ist in Grün geschrieben:

Was macht das PHP im Hintergrund?
Das wichtigste ist hier, dass jeder Frage-Antwort-Block ein PHP-Formular ist. Das sieht im Quelltext so aus: <form action="<?php echo $_SERVER["PHP_SELF"]; ?>"method="post">. "method="post" zeigt, dass hier Daten versendet werden können. Nur eben nicht "raus" in's Web, sondern das PHP sendet an sich selbst.
[Dieselbe Methode wird bei Mailanfragen und Sonstigem an Millionen Stellen im Web verwendet: wenn ein Nutzer z. B. eine Anfrage stellt, werden die Daten an den Server des Datenabfragenden gesendet.]
Zu jeder Antwortalternative gehört ein Radiobutton. Die Buttons liegen im Quelltext z. B. so: <input type="radio" value="falsch3" name="antwort"> Alle Radiobuttons haben denselben Namen: "antwort". Doch jeder einen anderen Wert, z. B. "falsch3" oder "richtig". So kann der Code dann identifizieren, welcher der 4 oder 5 Buttons geklickt wird.
Zuerst wird geprüft, ob überhaupt ein Button gewählt wurde: if (isset($_POST["antwort"])). Wenn ja, wird ihm die Post-Variable zugewiesen: {$antwort = $_POST["antwort"];. Jetzt weiß der Code, dass der Inhalt von "antwort" - also der jeweilige "value" des jeweiligen Radiobuttons - in die Post-Variable $antwort gefüllt werden soll.
Dann wird die Post-Variable $antwort geswitcht: switch ($antwort), die "case" werden durchlaufen: Welcher Button wurde geklickt? Jeder Button generiert eine unterschiedliche Raktion: durch "echo" werden die pinken bzw. grünen Texte ausgegeben, die dem Spieler sagen, wieso er falsch oder richtig liegt. - Der PHP-Code einer Frage auf einen Blick:

Alle Illustrationen zum Märchenquiz
Um das Quiz zu illustrieren, bediente ich mich der schönen Holzstiche Werner Klemkes, die ich relativ schlicht kolorierte. Die Holzstich-Drucke sind dem Buch "Die Kinder- und Hausmärchen der Brüder Grimm"; Beltz, Der Kinderbuchverlag, 2012; 1. Auflage 1962, entnommen. - Hier jeweils Vorlage und Endbild:
Schönes (Nonsens-) Quiz
in Arbeit