lehrkraefte:blc:informatik:ffprg1-2023:js-connect-4:start

4-Gewinnt

Vorbereitung

Laden Sie sich folgendes zip-File herunter: 06-connect-4.zip

Das Archiv enthält mehrere Unterverzeichnisse mit dem Spiel.

  • 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.

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.
  • Ü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.

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.

// 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;
}

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%)

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

  • lehrkraefte/blc/informatik/ffprg1-2023/js-connect-4/start.txt
  • Last modified: 2023/05/16 09:49
  • by Ivo Blöchliger