Webumsetzung des ZX81-Klassikers Lawine — ein Kettenreaktionsspiel auf einem quadratischen Feld. Die Feldgröße ist wählbar: 4×4 (Standard), 6×6 oder 8×8. Drei Modi: 2 Spieler (Hotseat, beide an einem Gerät), gegen KI (Computer-Gegner in drei Stärkegraden) und Online (zwei Geräte über einen Raum-Code). Umgeschaltet wird oben über der Anzeige; die Spielernamen lassen sich per Klick umbenennen.
- Abwechselnd setzt jeder Spieler 1 Stein in seiner Farbe.
- Gesetzt werden darf nur auf ein leeres oder ein eigenes Feld.
- Erreicht ein Feld so viele Steine, wie es orthogonale Nachbarn hat (Diagonalen zählen nicht → Ecke 2, Rand 3, Innenfeld 4; unabhängig von der Feldgröße), explodiert es: je 1 Stein springt auf jedes Nachbarfeld, das Ausgangsfeld wird leer.
- Springt ein Stein auf ein gegnerisches Feld, färben sich dessen Steine in die eigene Farbe um.
- Eine Explosion kann die nächste auslösen — das ist die Lawine.
- Ab der 2. Runde gilt: Wer keine eigenen Steine mehr auf dem Feld hat, verliert. (Vorher wird nicht geprüft, da der zweite Spieler zu Beginn 0 Steine hätte.)
# im Projektordner
docker compose up --buildDann im Browser öffnen: http://localhost:3000
Alternativ ohne Compose:
docker build -t lawine .
docker run --rm -p 3000:3000 lawinenpm install
npm start # http://localhost:3000
npm test # Engine-SelbsttestsDer Port lässt sich per Umgebungsvariable ändern: PORT=8080 npm start.
lawine/
├── public/
│ ├── index.html Aufbau der Oberfläche
│ ├── style.css Optik + Animationen (Explosions-Wellen)
│ ├── engine.js REINE Spiellogik (Regeln, Kaskade, Sieg) – ohne DOM
│ ├── ai.js Computer-Gegner (Negamax + Alpha-Beta, ohne DOM)
│ └── main.js Rendering, Eingabe, Animation, Modus-/KI-/Online-Steuerung
├── server.js Express-Static-Server + WebSocket-Server (+ /health)
├── rooms.js Server-Spiellogik für Online-Räume (nutzt engine.js)
├── test/engine.test.js Selbsttests der Engine
├── test/ai.test.js Selbsttests der KI
├── test/online.test.js Integrationstest des Online-Modus
├── Dockerfile
├── docker-compose.yml
└── package.json
Die Spiellogik in engine.js ist bewusst DOM-frei und als ES-Modul gebaut.
Dadurch läuft exakt derselbe Code im Browser, in den Node-Tests und später
serverseitig (für KI oder Online-Modus). Node/Express wurde als Basis gewählt,
damit sich diese Erweiterungen ohne Technologiewechsel im selben Container
ergänzen lassen.
Eine Lawine wird immer durch den Zug eines Spielers ausgelöst. Jedes Feld, das während der Kaskade überläuft, hat zuvor Steine dieses Spielers erhalten und gehört damit ihm. Deshalb sind alle Verteilungen einer Kaskade eindeutig einem Spieler zugeordnet — es gibt keine Reihenfolge-Konflikte, selbst wenn mehrere Felder gleichzeitig explodieren. Ein Endlosschleifen-Schutz bricht die Kaskade ab, sobald ein Spieler keine Steine mehr besitzt (= Sieg).
Im Modus gegen KI steuert der Computer Spieler 2. Die KI (ai.js) sucht mit
Negamax + Alpha-Beta-Pruning über eine Stellungsbewertung aus Material
(Steindifferenz), Position (Ecken/Ränder sind stabiler) und Verwundbarkeit
(Felder kurz vor der kritischen Masse neben Gegnersteinen). Drei Stufen:
- Leicht – Suchtiefe 1, mit etwas Zufall (gut zum Reinkommen).
- Mittel – Suchtiefe 2.
- Schwer – Suchtiefe 3.
Ein KI-Zug im Mittelspiel wird in wenigen Millisekunden berechnet.
Im Modus Online spielen zwei Geräte über denselben Server:
- Beide öffnen die Seite und wählen oben Online.
- Spieler 1 gibt seinen Namen ein und klickt Raum erstellen → es erscheint ein 4-stelliger Raum-Code.
- Spieler 2 gibt den Code ein und klickt Beitreten. Sobald beide verbunden sind, startet die Partie (Spieler 1 beginnt).
Die Kommunikation läuft über WebSockets. Der Server ist autoritativ: er
hält den Spielzustand pro Raum und validiert jeden Zug mit derselben engine.js
wie der Client (Reihenfolge, erlaubte Felder, Sieg). Zugverlauf und Lawine werden
als Zustands-Frames an beide Clients gesendet, sodass die Animation synchron
läuft. Verbindet man sich von anderen Geräten, muss der Server unter der
entsprechenden Adresse erreichbar sein (bei Docker den Port veröffentlichen; im
selben Netzwerk z. B. http://<Host-IP>:3000). Für Zugriff über HTTPS von außen
ist ein Reverse-Proxy nötig, der auch WebSocket-Upgrades weiterreicht.
npm test prüft die Engine (kritische Masse, Setzregeln, Explosion, Umwandlung,
Kaskade inkl. Steinerhaltung, Siegerkennung, Endlosschleifen-Schutz), die KI
(legale Züge, Erkennen von Gewinnzügen, Spielstärke gegen Zufallsgegner,
Rechenzeit) und den Online-Modus (Raum erstellen/beitreten, Zugvalidierung,
Sieg-Broadcast, Neustart). Zusätzlich wurden 2000 Zufallspartien gespielt — alle
terminieren sauber.
Veröffentlicht unter der Apache License 2.0 — © 2026 Christoph Fabianek.