**Dies ist eine alte Version des Dokuments!**
Client-Side Vier Gewinnt
Vier_gewinnt ist ein Spiel mit 6×7 Feldern. Die Spieler:innen werfen abwechslungsweise ein Stein ihrer Farbe in Spalten mit leeren Feldern. Das Spiel ist beendet, wenn ein Spieler vier Felder in horizontaler, vertikaler oder diagonaler Richtung besetzen kann, oder wenn keine freien Felder übrig sind (unentschieden).
Auftrag A: Struktur & Formatierung
Erstelle HTML & CSS, um ein Vier-Gewinnt-Spiel darzustellen:
- Erstelle einen neuen Ordner, in dem die ganze Web-App enthalten sein wird!
- Erstelle erst nur das HTML in
connect4.html
!- Eine gute Möglichkeit wäre ein Container-Element mit 42
<button>
Kind-Elementen, die mit einem Grid-Layout auf 6×7 Felder formatiert werden können. - Eine andere Möglichkeit wäre, die Matrix zu verschachteln mit einem Container, der sechs Zeilen-Elemente mit je sieben Feldern enthält.
- Formatiere anschliessend mit CSS!
- Muss:
- Layout des Spielfelds auf 6×7 Felder.
- Horizontale Zentrierung des Spielfelds (selfhtml)
- Ansprechende Formatierung (Hintergrundfarbe, Schriftgrösse, Abstände, abgerundete Ecken…)
- Nice-to have:
- Runde Löcher: z.B. mit
border-radius: 50%;
- 3D-Effekt mit
box-shadow
. - Responsive (Spielfeld passt sich der Grösse des Browserfensters an)
- Mobile funktioniert gut (selfhtml)
- Halt, nicht einfach im Internet abschreiben!
Auftrag B: Spiel-Logik
Das Ziel dieses Auftrags ist, dass zu zweit im Browser Vier gewinnt gespielt werden kann. Dazu nutzen wir JavaScript.
Javascript einbinden
Die Javascript-Datei (z.B. connect4.js
) muss im HTML-Code eingebunden werden. Damit die Datei erst ausgeführt wird, wenn das HTML aufgebaut ist, markieren wir sie mit async
:
<script src="connect4.js" async></script>
Zustand
Der Zustand (en. state) des Spiels soll in einem Javascript-Objekt (wie ein Python-Dictionary) gespeichert werden:
game = { "state": "playing", // or "waiting" or "won" or "tie" "board": [ // game board, 0 for empty cells, 1 or 2 for filled cells. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], "next": 1, // 1 or 2, the player whose turn it is, the winner if state is "won" }
Alle Änderungen des Spiels sollen zuerst auf diesem Spiel-Modell durchgeführt werden. Anschliessend wird das Spiel vom HTML dargestellt (en. rendering).
Verhalten
Jeder button
benötigt einen Click-Handler, der ausgeführt wird, wenn die spielende Person darauf klickt. Mit Code ähnlich dem Folgenden kann jedem Button ein Handler zugewiesen werden:
let index = 0 for (let button of document.getElementsByTagName("button")) { const column = index % 7; button.addEventListener("click", () => dropPiece(game, column)); // TODO: write a dropPiece function index++; }
Der Click-Handler:
- findet heraus, welches das unterste leere Feld in der Spalte ist.
- überprüft, ob der Spielzug legal ist (Spalte frei, Spiel noch nicht beendet?)
- setzt das Feld auf die Farbe des Spielers.
- … überprüft ob das Spiel zu Ende ist
- entweder, weil ein Spieler gewonnen hat,
- oder weil keine freien Felder übrig sind
- … schaltet die Farbe des Spielers um.
Darstellung in HTML
Wenn der Spielzustand geändert worden ist, wird das HTML (genauer: das HTML Document Object Model (DOM)) entsprechend angepasst:
Um die Darstellung des Spiels zu ändern, setzen wir den Text des Buttons. Für die Formatierung mit CSS speichern wir den Zustand zudem in einem Attribut data-state
:
- tictactoe.js
let color = game.board[cell]; // 1, or 2 button.innerText = color; // remove once CSS formatting works button.setAttribute('data-state', color);
In CSS können wir mit einem geeigneten Selektor die Zellen formatieren, die einen bestimmten Attributwert haben:
- tictactoe.css
button[data-state="1"] { background-color: red; } button[data-state="2"] { background-color: yellow; }
Für Benachrichtigungen (z.B. über das Ende des Spiels) kann man die Funktion alert(message)
nützen, die ein Browser-Popup anzeigt. Schöner ist es, einen Bereich im HTML zu definieren, der Meldungen anzeigt.