Seite anzeigenÄltere VersionenLinks hierherCopy this pageFold/unfold allNach oben Diese Seite ist nicht editierbar. Du kannst den Quelltext sehen, jedoch nicht verändern. Kontaktiere den Administrator, wenn du glaubst, dass hier ein Fehler vorliegt. ## Client-Side Vier Gewinnt [[wpde>Vier_gewinnt|Vier gewinnt]] ist ein Spiel mit 6x7 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). {{:talit:web:webapps:client:pasted:20250204-140319.png?nolink&300|Vier Gewinnt}} ### 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 6x7 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 6x7 Felder. * Horizontale Zentrierung des Spielfelds ([[https://wiki.selfhtml.org/wiki/CSS/Tutorials/Ausrichtung/Inhalte_zentrieren#horizontale_Zentrierung|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 ([[https://wiki.selfhtml.org/wiki/CSS/Tutorials/Einstieg/Webseiten_responsiv_umbauen|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 [[gf_informatik:web:js]]. #### 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`: <code html> <script src="connect4.js" async></script> </code> #### Zustand Der Zustand (en. _state_) des Spiels soll in einem Javascript-Objekt (wie ein Python-Dictionary) gespeichert werden: <code javascript> 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" } </code> 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: <code javascript> 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++; } </code> 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. Um den Code etwas zu strukturieren, hilft es, die obigen Aufgaben als _Funktionsaufrufe_ hinzuschreiben, und diese erst anschliessend zu implementieren. Die `dropPiece` Funktion könnte also so aussehen: <code javascript> /** Drops a piece in the given column and updates the game state accordingly. */ function dropPiece(grid, status, game, column) { // Check if move is valid. if (game.state != "playing") { return; // or throw new Error("can't play in this game") } // Compute the lowest empty row in the selected column. let row = computeEmptyRow(game, column); let cell = row * 7 + column; // Update game state. game.board[cell] = game.next; // Check for winner / tie, will set game.state if game ended. checkWinner(game, cell); // Swap active player if (game.state == "playing") { togglePlayer(game); } // Update the HTML view. updateHtml(grid, game); // Update game status area to reflect active player / winner / tie updateStatus(status, game); } </code> #### 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 mit der [[https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent|textContent]] Eigenschaft. Für die Formatierung mit CSS speichern wir den Zustand zudem in einem Attribut `data-state`. Sobald die Formatierung funktioniert, können wir den Text auch wieder entfernen. <code javascript tictactoe.js> let color = game.board[cell]; // 1, or 2 button.textContent = color; // remove once CSS formatting works button.setAttribute('data-state', color); </code> In [[gf_informatik:web:css|CSS]] können wir mit einem [[https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors|geeigneten Selektor]] die Zellen formatieren, die einen bestimmten Attributwert haben: <code css tictactoe.css> button[data-state="1"] { background-color: red; } button[data-state="2"] { background-color: yellow; } </code> 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. talit/web/webapps/client.txt Zuletzt geändert: 2025-04-13 10:47von hof