Skip to content

OwnYourData/lawine

Repository files navigation

Lawine

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.

Spielregeln

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

Schnellstart mit Docker

# im Projektordner
docker compose up --build

Dann im Browser öffnen: http://localhost:3000

Alternativ ohne Compose:

docker build -t lawine .
docker run --rm -p 3000:3000 lawine

Lokal ohne Docker

npm install
npm start          # http://localhost:3000
npm test           # Engine-Selbsttests

Der Port lässt sich per Umgebungsvariable ändern: PORT=8080 npm start.

Architektur

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.

Wichtige Design-Entscheidung zur Auflösung

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

Computer-Gegner (KI)

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.

Online-Modus

Im Modus Online spielen zwei Geräte über denselben Server:

  1. Beide öffnen die Seite und wählen oben Online.
  2. Spieler 1 gibt seinen Namen ein und klickt Raum erstellen → es erscheint ein 4-stelliger Raum-Code.
  3. 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.

Tests

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.

Lizenz

Veröffentlicht unter der Apache License 2.0 — © 2026 Christoph Fabianek.

About

Lawine — Kettenreaktions-Spiel (ZX81-Klassiker) als Webanwendung

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors