4-Gewinnt
Vorbereitung
Laden Sie sich folgendes zip-File herunter: 06-connect-4.zip
Das Archiv enthält mehrere Unterverzeichnisse mit dem Spiel.
Spielfeld generieren, CSS-Tricks
- Studieren Sie den HTML, CSS und JS-Code im Verzeichnis
01-connect-4und testen Sie diesen Code. Studieren Sie auch die Ausgabe auf der Console. - Schaffen Sie es, dass die Farbe eines Felds auf rot (oder blau) gesetzt wird, wenn man darauf klickt?
- Verstehen Sie den Zusammenhang zwischen der Zeile
div.className = feldklassen[wert];und der CSS-Datei. - Wenn Sie möchten, finden Sie besseren CSS-Code für die Felder (angefangen bei den Farben). Es sind mit CSS auch runde Felder bzw. Hintergrundbilder möglich.
Spielfeld Zustand speichern und manipulieren
So wie es im Moment programmiert ist, ist die Information über den Feldzustand an zwei Orten gespeichert: Im Attribut wert und in der Klasse des jeweiligen Elements (eine von feldleer, feldeins und feldzwei).
Zum Auslesen und Setzen dieser Werte ist das aber unpraktisch.
- Schreiben Sie eine Funktion
getWert(div)die den Wert als Zahl zurück gibt (benutzen Sie dieNumber()-Funktion, damit man nicht den String (Zeichenkette) erhält. - Schreiben Sie eine Funtion
setWert(div, wert), die daswert-Attribut setzt und auch die entsprechende Klasse. - Testen Sie die Funktion, indem Sie damit das Feld jeweils «eins weiter» schalten beim Klicken.
- Implementieren Sie eine
reset-Funktion, die alle Felder auf grau setzt (verwenden Sie dazu folgendes):
for (let div of spieldfeld.children) { // ... }
- Implementieren Sie eine Funktion
getDiv(spalte, zeile), die das richtige Element aus den 42 Elementen zurückliefert mitspielfeld.children.item(nummer), wobeinummernatürlich ausspalteundzeileberechnet werden muss.
Spielablauf
- Überlegen Sie sich, was alles bekannt sein muss, um einen beliebigen Spielzustand im «Vier gewinnt» zu beschreiben und wie man dies in Variablen speichern könnte.
- Fügen Sie diese Variablen im Code hinzu und initialisieren Sie diese in der
reset-Funktion. - Bei einem klick auf ein Feld soll überprüft werden, ob überhaupt noch ein Stein in die entsprechende Spalte gesetzt werden kann, und wenn ja, auf welcher Höhe.
- Die Farben sollen immer abwechseln.
Spielende überprüfen
Das Spiel kann auf zwei Arten enden:
- Alle Plätze sind besetzt
- Jemand hat vier in einer Reihe
Der erste Fall kann relativ einfach überprüft werden, indem einfach gezählt wird, wie viele Steine schon gesetzt wurden.
Der zweite Fall hat viel mehr Fleisch am Knochen. Überlegen Sie sich Strategien dazu.
Mögliche Lösung
// Zugriff auf Feld etwas vereinfachen: function getValueAt(x,y) { // wenn x,y nicht auf dem Brett, 0 züruckgeben // sonst den Wert vom Feld x,y } // Gibt die Anzahl gleicher Felder an, wenn man bei (startx, starty) startet und in Richtung (dx,dy) weiter geht. // Ist das Startfeld schon 0, wird sofort 0 zurückgegeben function count(startx, starty, dx, dy) { let wert = getValueAt(startx,starty); // Wert auf Startfeld if (wert==0) return 0; // Keine Nuller zählen let anzahl = 0; while (wert==getValueAt(startx,starty)) { // Immer noch das Gleiche? anzahl++; startx+=dx; // Vorwärts starty+=dy; } return anzahl; } // Liefert true, wenn die Position (x, y) Teil eines Vierers ist function pruefen(x, y) { let dirs = [[1,0], [1,1], [0,1], [-1,1]]; // Trigonometrisch, 45 Grad Schritte. for (let d of dirs) { let anzahl = count(x, y, d[0], d[1]) + count(x, y, -d[0], -d[1]) - 1; if (anzahl>=4) { return true; } } return false; }
Popup-Nachricht / Gewinnsteine markieren
Um das Spielende anzuzeigen, könnte ein «Popup» verwendet werden.
- Z.B. ein div, das normalerweise mit
display:none;formatiert ist - Oder ein
<dialog>.
Um die Gewinnsteine zu markieren, erweitern Sie die Funktion pruefen um einen Parameter (z.B. mark=false), der angibt, ob die Felder markiert werden sollen.
Fügen Sie eine zusätzliche Klasse in der CSS-Datei an, die angibt, wie die Felder markiert werden sollen, z.B. durch eine CSS-Animation mit filter:brightness(150%)…
Computergegner
Idee: Bis zu einer gewissen Tiefe alle möglichen Züge durchprobieren und jeweils den besten davon auswählen und dessen Bewertung zurückgeben. Ist die maximale Tiefe erreicht, wird die Spielsituation heuristisch bewertet.
Eine mögliche, minimale Implementation finden Sie hier: 04-computer-opponent.zip