Blu Mania
Denkspiel auf 100 Feldern: Ein Klick dreht Reihe und Spalte um — färbt das Brett Level für Level wieder ganz rot.
BlueMania ist ein Denkspiel mit einer einzigen, schnell erklärten Regel — und trotzdem wird es von Level zu Level erstaunlich knifflig. Vor euch liegt ein Brett aus 100 Steinen. Klickt ihr einen davon an, wechseln alle Steine seiner Reihe und alle Steine seiner Spalte die Farbe: aus Rot wird Blau und umgekehrt. Eure Aufgabe ist es, das Brett wieder vollständig rot zu bekommen.
Zu Beginn färbt sich das Brett Stein für Stein rot ein, dann macht der Computer seinen Zug und hinterlässt ein blaues Kreuz. Das bekommt ihr mit einem einzigen Klick zurückgedreht. Ab Level 4 legt der Computer zwei Züge vor, ab Level 9 drei, und so geht es weiter — die Zahl in der Anzeige „Vorgabe“ verrät euch, wie viele es gerade sind. Für das ganze Spiel habt ihr 250 Züge; wer die ersten 61 Level schafft, bekommt 100 Züge geschenkt und kann bis Level 75 weiterspielen.
Neben dem Anklicken gibt es drei Tastenkürzel: s startet ein neues Spiel, z setzt den laufenden Level auf den Ausgangszustand zurück, und a zeigt die vollständige Anleitung. Der beste erreichte Punktestand wird im Browser gespeichert und beim nächsten Besuch wieder angezeigt — er verlässt euren Rechner nicht.
Mathematisch ist BlueMania mit Spielen wie Lights Out und Lights Out 2 verwandt: Auch dort schaltet ein Klick mehrere Felder gleichzeitig um. Die Reihenfolge der Züge spielt dabei keine Rolle, und jeder Stein muss entweder gar nicht oder genau einmal angeklickt werden — zweimal derselbe Klick hebt sich auf. Wer diesen Gedanken einmal verinnerlicht hat, findet die Lösung deutlich schneller. Ein weiteres Knobelspiel derselben Machart ist unser Mastermind.
Das Spiel hat uns Jürgen Heise geschickt. In der Variable bilderpfad im Script tragt ihr den Pfad zu den drei Bildern ein, wenn ihr sie auf eure eigene Homepage laden möchtet — der Pfad muss mit einem Schrägstrich enden. Hier sind die Bilder zum Herunterladen (rechte Maustaste, „Bild speichern unter …“):

Alle Steine rot färben — klickt einen Stein an, dann wechseln seine Reihe und seine Spalte die Farbe. © J. Heise, 1994–2009, Internet-Version 1.11s, www.YogiFotos.de
So funktioniert das Script
Das Script hat vier Aufgaben: Es baut das Spielbrett aus 100 Bildern auf, führt den Zug des Spielers aus, prüft nach jedem Zug, ob der Level geschafft ist, und lässt den Computer die Vorgabe für den nächsten Level würfeln. Der Spielzustand steckt in zwei einfachen Zahlenlisten, und alles zusammen liegt in einer sofort ausgeführten Funktion, damit die vielen Variablennamen nicht mit anderen Scripts kollidieren.
Das Spielbrett
for (let i = 0; i <= 99; i++) {
const stein = new Image(20, 20);
stein.id = "bm-b" + i;
stein.src = bilderpfad + "blau.jpg";
stein.addEventListener("click", function () { Zug(i); });
brett.appendChild(stein);
steine[i] = stein;
}
Die 100 Steine werden nicht ins HTML geschrieben, sondern in einer Schleife erzeugt und in den Behälter bm-brett gehängt. Der bekommt im Stylesheet display: grid mit zehn Spalten zu 20 Pixeln — damit ordnen sich die Bilder von allein zu einem 10 × 10-Raster. Früher stand hier eine verschachtelte Tabelle mit document.write; das Ergebnis ist dasselbe, der Weg dorthin nur deutlich kürzer.
Wichtig ist die Zeile mit addEventListener: Jeder Stein bekommt seine eigene kleine Klickfunktion, und weil i mit let deklariert ist, merkt sich jede dieser Funktionen ihren eigenen Wert. Mit var hätten am Ende alle 100 Steine die Nummer 100 gemeldet — ein Klassiker unter den JavaScript-Stolperfallen.
Der Zug
const a = Math.floor(z / 10); // Reihe
const b = z % 10; // Spalte
for (let i = 0; i <= 9; i++) {
const wert = 10 * a + i;
Feld[wert] = -Feld[wert];
malen(wert);
}
Die Steine sind von 0 bis 99 durchnummeriert. Aus der Nummer lassen sich Reihe und Spalte direkt ausrechnen: Math.floor(z / 10) ist die Zehnerstelle, z % 10 die Einerstelle. Der Restwert-Operator % liefert den Rest einer Division — 47 geteilt durch 10 ergibt 4 Rest 7, also Reihe 4, Spalte 7.
Der Zustand jedes Steins steht in der Liste Feld, und zwar als 1 für Rot und −1 für Blau. Das ist der eigentliche Kniff des Scripts: Umschalten heißt dann einfach Vorzeichen wechseln, Feld[wert] = -Feld[wert]. Eine zweite, fast gleiche Schleife erledigt danach die Spalte; die Bedingung if (a !== i) verhindert, dass der angeklickte Stein selbst zweimal gedreht wird — er gehört ja zu Reihe und Spalte zugleich.
Ist der Level geschafft?
function Auswertung() {
gebraucht++;
Zuege--;
for (let i = 0; i <= 99; i++) {
if (Feld[i] === -1) {
feldVorrat.value = Zuege;
ani = 0;
return;
}
}
Punkte++;
...
}
Nach jedem Zug läuft das Script einmal über alle 100 Felder. Findet es auch nur eine −1, ist noch mindestens ein Stein blau: Der Zugvorrat wird aktualisiert, das Brett per ani = 0 wieder freigegeben, und return beendet die Funktion sofort. Erst wenn die Schleife komplett durchläuft, ohne fündig zu werden, ist alles rot und ein Punkt verdient.
ani ist eine Sperre: Solange sie auf 1 steht, ignoriert Zug() jeden Klick. Das verhindert, dass man während der Startanimation oder in der Sekunde zwischen zwei Leveln dazwischenfunkt.
Die Vorgabe des Computers
Anz++;
wieoft = Math.floor(Math.sqrt(Anz));
for (let ii = 1; ii <= wieoft; ii++) {
do {
neu = 0;
a = Math.floor(Math.random() * 10);
b = Math.floor(Math.random() * 10);
for (let j = 1; j <= ii; j++) {
if (a + 10 * b === merker[j]) { neu = 1; }
}
} while (neu === 1);
merker[ii] = a + 10 * b;
...
}
Der Schwierigkeitsgrad steckt in einer einzigen Zeile: Math.floor(Math.sqrt(Anz)). Die Wurzel aus der Levelnummer, abgerundet — daher die Sprünge bei 4, 9, 16, 25 und so weiter, genau wie in der Anleitung beschrieben. Wer das Spiel schneller schwer machen möchte, ersetzt die Wurzel zum Beispiel durch Math.floor(Anz / 3) + 1.
Math.random() liefert eine Zufallszahl zwischen 0 und knapp 1; mal 10 genommen und abgerundet ergibt das eine Zahl von 0 bis 9. Die do … while-Schleife würfelt so lange weiter, bis ein Zug herauskommt, der in dieser Vorgabe noch nicht vorkam — sonst würden sich zwei gleiche Züge gegenseitig aufheben und der Level wäre zu leicht. Zum Schluss merkt sich Feldalt den fertigen Ausgangszustand, damit die Taste z ihn jederzeit wiederherstellen kann.
Tastatur und Bestwert
function TasteGedrueckt(Ereignis) {
const ziel = Ereignis.target;
if (ziel && (ziel.tagName === "INPUT" || ziel.tagName === "TEXTAREA")) { return; }
const taste = (Ereignis.key || "").toLowerCase();
if (taste === "z") { zuruecksetzen(); }
if (taste === "s") { neuesSpiel(); }
if (taste === "a") { hilfe(); }
}
Früher wurden hier Tastencodes verglichen — 83 für „S“, 115 für „s“ und so weiter. Heute liefert Ereignis.key das Zeichen direkt; toLowerCase() macht Groß- und Kleinschreibung gleichwertig. Die erste Zeile ist neu hinzugekommen: Sie sorgt dafür, dass das Spiel nicht reagiert, wenn ihr gerade in einem Eingabefeld tippt.
try { localStorage.setItem("BM", String(Punkte)); } catch (e) {}
Der persönliche Bestwert lag ursprünglich in einem Cookie mit zehn Jahren Laufzeit. Cookies werden bei jedem Seitenaufruf mitgeschickt — für eine Punktzahl völlig unnötig. localStorage bleibt dagegen im Browser. Das try … catch darum ist Absicht: In manchen Browsereinstellungen ist der Speicher gesperrt und wirft einen Fehler; so läuft das Spiel dann eben ohne Bestwert weiter, statt stehenzubleiben.
Script für die eigene Homepage
Kopiert euch den kompletten Code und fügt ihn an der Stelle eurer Seite ein, an der das Script erscheinen soll. Er läuft ohne weitere Dateien und ohne fremde Server.
Mehr aus der Kategorie Spiele
-
ASCII Minesweeper
-
Asteroids
-
Ausweichen
-
Ballspiel
-
Bennys Quiz
-
Blackjack
-
BreakOut
-
Buchstaben zählen
-
Buchstabenpuzzle
-
Checkbox Spiel
-
Concentration
-
Der längste Drücker
-
Die Türme von Hanoi
-
Einmaleins Trainer
-
Escape
-
Galgenmännchen
-
Galgenmännchen 2
-
Game Over Game
-
Glücks Klick
-
Glücksbuttons
-
Ich sehe was
-
Kniffel
-
Labyrinth
-
Liebesrechner
-
Lights Out
-
Lights Out 2
-
Mastermind
-
Minesweeper
-
Mühle