====== Tic Tac Toe ====== * Legen Sie einen neuen Ordner 'tictactoe' and und speichern Sie darin die Dateien [[.:raster-basics|der Basis]] für ein Raster Spiel. * Speichern Sie im gleichen Ordner auch folgende beiden Bilder (gemacht mit dem sehr zu empfehlenden OpenSource-Programm [[https://inkscape.org/|Inkscape]]: * {{lehrkraefte:blc:informatik:ffprg1-2024:cross.svg?linkonly}} und {{lehrkraefte:blc:informatik:ffprg1-2024:dot.svg?linkonly}} * Fügen Sie in der Datei ''raster.css'' folgenden CSS-Code hinzu: .wert1 { background-image: url("cross.svg"); background-size: cover; } .wert2 { background-image: url("dot.svg"); background-size: cover; } * In der Datei ''mygame.js'' * entfernen Sie den Aufruf von ''Raster.addColorRules'', * passen Sie die Grösse auf 3 mal 3 an, * fügen Sie eine Variable ''currentPlayer'' hinzu, die angibt, welcher Spieler (1 oder 2) gerade am Zug ist. * Beginnen Sie das Spiel im ''clickCallback'' zu programmieren (mit den Variablen ''meinRaster'' und ''currentPlayer''). Dabei soll einfach abwechselnd auf leeren Feldern gezogen werden können. * Fügen Sie eine weitere Variable ''cellsPlayed'' hinzu, die zählt, wie viele Zellen schon belegt sind. * Programmieren Sie eine Unterfunktion ''reset'', die das Spiel und alle nötigen Variablen zurücksetzt. * Wenn geklickt wird und alle Zellen schon voll sind, soll das Spiel neu starten. window.addEventListener('load', function() { let meinRaster = new Raster(3,3); let currentPlayer = 1; let cellsPlayed = 0; function reset() { currentPlayer = 1; cellsPlayed = 0; for (let x=0; x<3; x++) { for (let y=0; y<3; y++) { meinRaster.setValue(x,y,0); } } } // Callback für einen Klick definieren meinRaster.clickCallback = function(x, y) { if (cellsPlayed==9) { reset(); return; } let v = meinRaster.getValue(x,y); if (v!=0) { return; } meinRaster.setValue(x,y,currentPlayer); currentPlayer = 3-currentPlayer; cellsPlayed++; } }); ===== Gewinn überprüfen ===== In der Datei ''mygame.js'', fügen Sie eine weitere Unterfunktion ''winner'' hinzu, die folgende Werte zurückgibt: * 0, wenn niemand 3 in einer Reihe hat * 1 oder 2, wenn Spieler 1 oder Spieler 2 gewonnen hat. Hinweise: * Schreiben Sie zusätzlich eine Funktion ''sindsDrei(x,y,vx,vy)'', die ''true'' ergibt, wenn drei gleiche Werte >=1 vom Startpunkt x,y, in Richtung des Vektors (vx,vy) anzutreffen sind. Sonst ''false''. * Rufen Sie die Funktion ''sindsDrei'' in der Funktion ''winner'' unter anderem in einer for-schlaufe auf. function sindsDrei(x,y,vx,vy) { let w = meinRaster.getValue(x,y); if (w==0) return false; for (let i=0; i<3; i++) { if (meinRaster.getValue(x,y)!=w) return false; x+=vx; y+=vy; } return true; } function winner() { for (let i=0; i<3; i++) { if (sindsDrei(i,0,0,1)) return meinRaster.getValue(i,0); // Vertikal if (sindsDrei(0,i,1,0)) return meinRaster.getValue(0,i); // Horizontal } if (sindsDrei(0,0,1,1)) return meinRaster.getValue(0,0); // Diagonale in Richtung (1,1) if (sindsDrei(2,0,-1,1)) return meinRaster.getValue(2,0); // Diagonale in Richtung (-1,1) return 0; } ===== Zellen markieren ===== Ziel ist es, die gewinnende Dreierreihe zu markieren. * Fügen Sie dazu in der Datei ''raster.css'' zwei weitere Klassen ''wert3'' und ''wert4'' hinzu, um das Aussehen der gewinnenden Zellen für Spieler 1 und 2 festzulegen. * In der Funktion ''sindsDrei'', fügen Sie unmittelbar vor dem ''return true'' noch eine Schlaufe hinzu, die den Wert der gewinndenden Zellen um 2 erhöht. .wert3 { background-image: url("cross.svg"); background-color: lightcoral; background-size: cover; } .wert4 { background-image: url("dot.svg"); background-color: skyblue; background-size: cover; } for (let i=0; i<3; i++) { x-=vx; y-=vy; meinRaster.setValue(x,y,w+2); }