====== 4-Gewinnt ======
**Vorbereitung**
Laden Sie sich folgendes zip-File herunter: {{lehrkraefte:blc:informatik:ffprg1-2023:js-connect-4: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-4'' und 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 die ''Number()''-Funktion, damit man nicht den String (Zeichenkette) erhält.
* Schreiben Sie eine Funtion ''setWert(div, wert)'', die das ''wert''-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 mit ''spielfeld.children.item(nummer)'', wobei ''nummer'' natürlich aus ''spalte'' und ''zeile'' berechnet 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 ''