Layout

Lektion 8 - Counterspiel

Ein Counterspiel, bei dem man etwas zählen muss, kann man auch sehr schön in PHP programmieren. Da einfaches zählen aber langweilig ist, werden wir eine maximale Zeit angeben. Außerdem soll auch nicht nur ein Bild gezählt werden, sondern drei verschiedene, um die Optik ein wenig zu verwirren. Wenn man alles in der Zeit richtig gezählt hat, gewinnt man, verzählt man sich oder ist über der Zeit, verliert man.

Wie viele DoReMi Puppen sind liegen geblieben?
Du hast 10 Sekunden Zeit, sie zu zählen.

Puppe Puppe Puppe Puppe Puppe

 

8.1 Inkrementieren und Dekrementieren

Bevor wir uns an die Programmierung des Spiels wagen, sollten wir erst wieder ein bißchen Theorie hinter uns bringen. In PHP gibt es eine Möglichkeit, Variablen, die Zahlen als Werte haben, um 1 zu erhöhen oder zu senken.

$Zahl = 5;
    echo $Zahl." ";
$Zahl++;
    echo $Zahl." ";
$Zahl++;
    echo $Zahl." ";
$Zahl--;
    echo $Zahl;

Wenn du diesen Code ausführst, erhälst du die Ausgabe 5 6 7 6. Zuerst wird hier der Variablen $Zahl der Wert 5 zugewiesen. Dieser Wert wird mittels $Zahl++ inkrementiert, d. h. um 1 erhöht, und $Zahl ist nun 6. Anschließend wird $Zahl noch einmal inkrementiert und erhält dadurch den Wert 7. Zum Schluss wird die Variable mit $Zahl-- dekrementiert, also um 1 gesenkt. Und wozu soll so etwas gut sein?

 

8.2 Die for-Schleife

In Lektion 5 hast du die foreach-Schleife kennengelernt, mit der man ein Array vollständig auslesen kann. Mit der for-Schleife kannst du die Anzahl von Durchläufen steuern und benötigst kein Array.

for ($i=1; $i<5; $i++) {

    echo $i." ";

}

Der Funktion 'for' werden 3 Parameter mitgegeben, getrennt durch ein Semikolon. In dem ersten passiert eine einfache Zuweisung: $i=1. Wir bestimmen eine Variable $i (sie könnte auch $Zahl oder ganz anders heißen) und weisen ihr den Wert 1 zu. Im 2. Parameter bestimmen wir die Durchlaufsbedingung der Schleife: i<5. Das heißt: So lange $i kleiner als 5 ist, durchlaufe die Schleife erneut. Im dritten Parameter $i++ wird bestimmt, was mit $i bei jedem erneuten Durchlauf geschehen soll. Dabei haben wir zwei Möglichkeiten. Entweder inkrementieren mit $i++ oder dekrementieren mit $i--. Wurden die Anweisungen innerhalb der Schleife, in diesem Falle nur echo $i." "; befolgt und die abschließende Klammer erreicht, springt das Skript wieder zum Start der Schleife, inkrementiert $i und überprüft, ob die Durchlaufbedingungen erfüllt sind. In dem Beispiel würde ein Durchlauf wie folgt aussehen:
Beim Start der Schleife wird überprüft, ob 1 kleiner als 5 ist. Das trifft zu, also wird die 1 ausgegeben. Beim nächten Durchlauf wird $i inkrementiert und überprüft, ob nun 2 kleiner als 5 ist, was ebenfalls zutrifft. Das gleiche geschieht bei den weiteren durchläufen. $i wird zu 3 inkrementiert, anschließend zu 4. Die bisherige Ausgabe ist also 1 2 3 4. Nun springt das Skript wieder zum Start, inkrementiert $i und vergleicht, ob $i, nun 5, kleiner als 5 ist. Das trifft nicht mehr zu, die Schleife wird verlassen und der weitere Code darunter ausgeführt.

 

8.3 Vorbereitungen des Spiels

Nun geht es ans Spiel. Speicher die 3 DoReMi Puppen unter den Namen 'puppe1', 'puppe2' und 'puppe3' in einen Unterordner mit dem Namen 'bilder'. Anschließend schreibst du die Seite des Spiels und speicherst sie, wie deine anderen Seiten, in dem Hauptordner. Wichtig ist, dass du den Pfad von der Seite zu den Bildern kennst.

// Die Seite counter.php

if ($_GET['action'] != "spielen") {

    echo "Wie viele DoReMi Puppen sind liegen geblieben?<br>
    Du hast 10 Sekunden Zeit, sie zu zählen."
;

    // Der Code zum Puppen ausgeben kommt hier hin

    echo "<form action='index.php?Seite=counter.php&action=spielen'                     method='POST'>

    <input type='text' name='Zahl' size='2'> <input type='submit' name='Antwort'     value='So viele!'>

    </form>"
;

} else {

    // Die Antwort des Spiels

}

Was hier passiert, solltest du mittlerweile im Schlaf können. Wenn man die Seite betritt, siehst man das Spiel mit seinem Formular. Sobald es abgeschickt wird erhält die Variable $_GET['action'] den Wert 'spielen' und der else-Teil der if-Abfrage, also die Antwort des Spiels wird ausgeführt.

 

8.4 Die Funktion time()

Mit Hilfe der Funktion time() kann man den Server fragen, wie spät es ist, allerdings wird er dir keine Uhrzeit liefern. Seit dem 1.1.1970 werden die Sekunden gezählt, die bis zum jetzigen Augenblick vergangen sind. Als du diese Seite geladen hast, waren das z.B. genau 1540236447 Sekunden. Die Anzahl der Sekunden seit '70 nennt man Timestamp.

$ZeitJetzt = time();

$ZeitZukunft = $ZeitJetzt + 10;

$ZeitVergangenheit = $ZeitJetzt - 60*60*2

Mit der aktuellen Zeit in Sekunden kann man gut rechnen. Addieren wir 10 hinzu, so wird $ZeitZukunft in genau 10 Sekunden nicht mehr in der Zukunft liegen, da beim Laden der Seite der aktuellen Zeit 10 hinzugefügt wurden und in der Variablen $ZeitZukunft unveränderlich gespeichert wurde. Beim erneuten Laden der Seite wird $ZeitZukunft jedoch wieder überschrieben.
Wir brauchen die Sekunden nicht immer auszurechnen, das kann der Server schließlich selbst. 60 Sekunden sind eine Minute, das wiederum mal 60 ergibt eine Stunde, denn eine Stunde hat 60 Minuten. Und dies mal 2 genommen ergibt 2 Stunden. Rechnest du 60*60*2 aus, was der Server macht, erhälst du 7200 (Sekunden). Beachte aber, dass auch hier Punktrechnung vor Strichrechnung gilt!

 

8.5 Der Code des Spiels

Wir wollen ein Spiel programmieren, bei dem man etwas auf Zeit zählen muss. Was brauchen wir dafür alles?

Als erstes etwas, das gezählt werden soll, und das jedesmal ein anderes Ergebnis der Zählung hat: Wir brauchen also jedesmal eine unterschiedliche Anzahl von Bilder, die beim Spiel angezeigt werden. Außerdem brauchen wir das richtige Ergebnis, um es mit der Eingabe des Spieles vergleichen zu können. Und natürlich die Zeit, zu der der Spieler das Spiel begonnen hat, um sie anschließend mit der aktuellen Zeit nach Beenden des Spiels vergleichen zu können.

// Der Code zum Puppen ausgeben

$Puppen = array("bild1", "0", "bild1", "bild2", "0", "bild2", "bild3", "0", "bild3", "bild3", "0");

for ($i=0; $i<15; $i++) {

    srand ((float) microtime() * 10000000);
        $rand_keys = array_rand ($Puppen);

    if ($Puppen[$rand_keys] != "0") {
        echo "<img src='bilder/".$Puppen[$rand_keys].".gif'> ";
        $AnzahlPuppen++;
    }
}

$_SESSION['Puppies'] = $AnzahlPuppen;
$_SESSION['SpielerZeit'] = time();

Wir definieren ein Array mit verschiedenen Elementen: die drei DoReMi Puppen Bilder und der 0. Da wir dort gleich zufällig Elemente auswählen werden, packen wir die gleichen Elemente mehrmals hinzu, damit die Wahrscheinlichkeit der Auswahl unterschiedlich wird. Ein Array $Puppen = array ("bild1", "bild2", "bild3", "0"); würde es genauso tun. Hier ist die Wahrscheinlichkeit für bild 1 nun 2:11, für bild2 auch 2:11, für bild3 3:11 und für die 0 4:11.
In der folgenden for-Schleife werden nun Bilder ausgegeben (oder eben nicht) und die Anzahl der Bilder gezählt. Bei jedem Durchlauf wird mittels der Funktion array_rand() (siehe Lektion 7) ein Element aus dem Array $Puppen ausgewählt und in der Variablen $Puppe gespeichert. Als nächstes wird mit einer if-Abfrage der Wert von $Puppe verglichen. Wenn aus dem Array nicht zufällig eine 0 ausgewählt wurde, wird die Anweisung innerhalb der Abfrage ausgeführt. Wurde z.B. 'bild2' ausgewählt, wird das Bild nun mit <img src='bilder/bild2.gif'> auf der Seite des Spiels angezeigt.
Nun müssen wir noch wissen, ob es ein Bild gibt, das zum Vergleichswert hinzugefügt werden muss. Dafür nehmen wir wieder eine Hilfsvariable, die hier $AnzahlPuppen heißt, und die bei jedem Schleifendurchlauf, bei dem die if-Abfrage ausgeführt wird, um 1 erhöhlt wird.
Beim ersten Durchlauf gibt es die Variable $AnzahlPuppen noch nicht, und Variablen, die es zunächst nicht gibt, haben immer der Wert 0 beim ersten Aufruf.
Die Schleife wird hier insgesamt 15 mal durchlaufen (mit den $i Werten von 0 bis 14), also werden auf der Seite nach Beenden der Schleife 0 bis 15 Puppen angezeigt, je nachdem, ob die Funktion array_rand() 15 mal die 0, 15 mal ein Bild oder beides verschiedenhäufig ausgewählt hat.

Zu guter Letzt müssen wir die Anzahl der Puppen aus $AnzahlPuppen speichern. Wir könnten sie beim nachfolgendem Formular über das Form Tag übergeben: <form action='index.php?Seite=counter.php&action=spielen&AnzahlPuppen=".$AnzahlPuppen."' method='POST'>. Oder über ein verstecktes Formularfeld: <input type='hidden' name=AnzahlPuppen' value='".$AnzahlPuppen."'>. Aber wenn der Spieler sich den Quelltext nun ansehen würde, könnte er das Ergebnis sehen, deshalb verstecken wir die Anzahl in einer Session Variablen, die er nicht sehen kann. Genauso schreiben wir die aktuelle Zeit in eine Session, zu der der Spieler die Seite geladen, also das Spiel betreten und zu zählen begonnen hat. (Diese könnte man hingegen problemlos via $_GET oder $_POST übertragen, wie es dir beliebt).

 

8.6 Überprüfung des Ergebnisses

Der Spieler hat gezählt, das Ergebnis in das Eingabefeld eingetragen und den Button "So viele!" geklickt. Jetzt müssen wir überprüfen, ob er richtig gezählt hat und ob er das innerhalb der vorgegebenen Zeit geschafft hat.

// Die Antwort des Spiels

$Zeit = time();

$Sekunden = $Zeit - $_SESSION['SpielerZeit'];

if (($Sekunden < 10) AND ($Zahl == $_SESSION['Puppies'])) {

    echo "Für ".$_SESSION['Puppies']." Puppen hast du ".$Sekunden." Sekunden           gebraucht. Geschafft!";

}
if (($Sekunden > 10) AND ($Zahl == $_SESSION['Puppies'])) {

    echo $Sekunden." Sekunden waren für ".$_SESSION['Puppies']." Puppen leider zu     viel!";

}
if ($Zahl != $_SESSION['Puppies']) {

    echo "Oh nein Es waren leider ".$_SESSION['Puppies']." Puppen und nicht                 ".$Zahl.".";

}

Die richtige Anzahl der Puppen haben wir bereits. Was noch fehlt, ist die Zeit, die der Spieler benötigt hat. Dazu finden wir mit $Zeit = time(); zunächst heraus, wie spät es jetzt ist. In $_SESSION['SpielerZeit'] haben wir den Timestamp mit dem Aufruf der Seite gespeichert, als der Spieler zu zählen begann. Wenn wir die Zeit vom aktuellen Timestamp abziehen, erhalten wir die Sekunden, die vom ersten Laden des Spiels bis zum Einreichen des Ergebnis vergangen sind. Und diese speichern wir in der Variablen Sekunden.

Nun müssen wir einiges vergleichen. Hat der Spieler weniger als 10 Sekunden gebraucht und richtig gezählt, hat er gewonnen. Hat er richtig gezählt, aber zu lange gebraucht, sagen wir ihm, er habe verloren. Nun bleibt nur noch eine Möglichkeit zum Überprüfen übrig: der Spieler hat sich verzählt. Wieder teilen wir ihm mit, dass er verloren hat.


hr

8.7 Übungen

8.7.1 Schreibe die for-Schleife so um, dass die Variale $i bei jedem erneuten Durchlauf dekrementiert wird und die Zahlen 4 3 2 1 ausgegeben werden.

8.7.2 Baue dieses Spiel wie folgt in deine Übungsseite ein:

  • Erläutere die Spielregeln auf einer Eingangsseite, auf der du den Spieler auf das Spiel vorbereitest. Füge einen Link auf die Seite ein, der zum eigentlichen Spiel führt.
  • Wenn man nicht eingeloggt ist, soll es spätestens auf der Antwortseite angezeigt werden.
  • Es sollen 5 verschiedene Bilder mit unterschiedlicher Wahrscheinlichkeit angezeigt werden können.
  • Angezeit werden können sollen insgesamt 0 bis 40 Bilder.
  • Der Spieler soll 20 Sekunden Zeit zum zählen bekommen.
  • Wenn der Spieler gewinnt, soll er entweder 50 € oder eine Trading Card gewinnen.
  • Wenn der Spieler gewonnen hat, lasse dir wie in Lektion 7 eine E-mail zukommen.

8.7.3 Auf der Webseite Virtual_Max's Cafe findest du unter Applets - Games einige Java Spiele, die du dir für deine Webseite herunterladen kannst. Bei den Spielen MemoryCheck oder PuzzleMaker kannst du eine Seite festlegen, die sich öffnet, wenn das Spiel beendet wurde. Baue nun das Puzzle oder das Memory Spiel folgendermaßen in deine Übungsseite ein:

  • Erläutere die Spielregeln auf einer Eingangsseite und füge einen Link auf die Seite ein, der zum eigentlichen Spiel führt.
  • Wenn man nicht eingeloggt ist, soll es spätestens auf der Antwortseite angezeigt werden.
  • Wenn die Seite mit dem Spiel geladen wurde, weise einer Session den Wert des aktuellen Timestamp zu.
  • Schreibe eine Antwortseite, die aufgerufen wird, wenn das Spiel beendet wurde, auf der überprüft wird, wie viele Sekunden der Spieler gebraucht hat.
  • Überlege dir eine angemessene Zeit, in der das Spiel zu schaffen ist. Wenn der Spieler das Spiel innhalb der Zeit geschafft hat, soll er etwas bekommen. Lasse dir dann eine E-Mail zuschicken.

8.7.4 Beim Programmieren ist es wichtig sich zu überlegen, was alles schief laufen kann und nach Möglichkeit alle möglichen Fehler abzufangen und damit auszuschalten. Das schwierigste ist dabei nicht das Abfangen mittels if-Abfrage, sondern das Auffinden der möglichen Fehlerquellen. Diese Fehler (=> unerwünschte Schummeleien zum Erhaschen von doppelten und dreifachen Lohn) entstehen meistens, wenn dein Besucher den Button 'Neuladen' betätigt oder im Quelltext rumwühlt. Worin bestehen die Probleme?

« zurück Inhalt | Fragen       Kurs weiter »
Layout