Vielleicht erinnern sich viele Oldtimer an eine Epidemie von Artikeln mit Überschriften wie "% etwas% in 30 Zeilen JS". Und auch der darauf folgende epische Beitrag „
Spiel in 0 Codezeilen auf reinem JS “, nach dem die Epidemie abrupt nachließ. Da ich mir völlig bewusst war, dass ich dieses Meisterwerk niemals übertreffen würde, beschloss ich dennoch fünf Jahre später, meine fünf Cent zu beenden.
Meine Damen und Herren, wir bieten Ihnen das Spiel „Tic-Tac-Toe“ bei null Zeilen von JS und im Gegensatz zu dem oben erwähnten Spiel auch bei null Zeilen von CSS (einschließlich Inline-Stilen) an. Nur nacktes HTML, nur Hardcore.
→
Link zum SpielEs sieht hässlich aus, funktioniert aber in jedem Browser. Unter dem Schnitt werde ich Ihnen sagen, warum das Spiel ohne JS im Abschnitt "Friday JS" war, sowie andere schmutzige Details. Ich werde Amerika jedoch niemandem öffnen. Wenn Sie ein erfahrener Programmierer sind, können Sie nicht einmal unter den Schnitt gehen
Eigentlich ist alles sehr dumm. Das Spiel besteht aus fast 6.000 Seiten statischen HTML-Codes, die miteinander verknüpft sind. Wenn Sie in eine Zelle des Spielfelds stöbern, gehen Sie zu der Seite, auf der der Umzug in diese Zelle bereits erfolgt ist. Offensichtlich ist das Schreiben von 6.000 Seiten mit Ihren Händen ein unterdurchschnittliches Vergnügen. Daher (Überraschung!) Werden die Seiten von JS-Skripten mit NodeJS generiert.
Lyrischer ExkursNachdem ich die vorherige Zeile geschrieben hatte, fragte ich mich plötzlich, ob der Ausdruck "JS-Skript" keine Tautologie ist, wie "CD-ROM" oder "VIP-Person". Einerseits scheint es so zu sein. Andererseits ist JS immer noch keine Abkürzung, sondern eine etwas andere Abkürzung. In der Post geht es jedoch immer noch nicht um Philologie, da der lyrische Exkurs endet und der lyrische Angriff beginnt.
Zunächst erstellen wir den sogenannten Spielbaum - die Gesamtheit aller möglichen Spielzustände und Übergänge zwischen ihnen. Der Anfangszustand des Spiels in meinem Code ist wie folgt:
const initialState = { player: PLAYER_X, field: Array.from(Array(9)).map(() => EMPTY_CELL), moves: {} }
Es enthält Informationen darüber, wer jetzt an der Reihe ist und wie der Zustand des Spielfelds ist. In Zukunft wird es auch Informationen darüber enthalten, welche Schritte ausgeführt werden können und zu welchen Zuständen sie führen werden, sowie einige andere angenehme Dinge.
Dann fangen wir an, ich entschuldige mich für die Tautologie, aus dem Ausgangszustand und machen folgendes:
- Wir prüfen, ob der Staat endgültig ist (Sieg der Kreuze, Sieg der Token, Unentschieden).
- Wenn ja, fügen Sie dem Statusobjekt Informationen dazu hinzu und beenden Sie den Vorgang.
- Wenn nicht, gehen Sie alle Zellen im Feld durch.
- Erstellen Sie für jede leere Zelle im Feld einen neuen Spielstatus, in dem der aktuelle Spieler in diese Zelle gezogen und der Zug an den nächsten Spieler übergeben wurde.
moves
Feld " moves
des aktuellen Status einen Datensatz einer möglichen Bewegung hinzu. Der Schlüssel zu diesem Eintrag ist der Zellenindex, und der Wert ist die Verknüpfung zum neuen Status.- Wir wiederholen diesen Algorithmus rekursiv für alle neu aufgetretenen Zustände.
Tatsächlich ist mein Code etwas komplizierter, ich habe aus Gewohnheit die Rekursion in eine Schleife entfaltet, und anstatt auf andere Zustände in
moves
verweisen, werden ihre Zeichenfolgenschlüssel in einem bestimmten assoziativen Array gespeichert. Aber das sind alle Details.
Dann generieren wir aus jedem Spielstatusobjekt eine HTML-Seite. Wenn wir durch das
moves
, füllen wir die leeren Zellen des Feldes mit Links zu den Seiten, die den in diese Zellen ausgeführten Bewegungen entsprechen. Dann verwandeln wir das eindimensionale Array des Feldes in eine zweidimensionale HTML-Tabelle. Wir fügen alle möglichen angenehmen Dinge hinzu, wie Anweisungen, die der Spieler geht, und Links zur Startseite - und voila!
Neben dem Modus, in dem sowohl die Kreuze als auch die Nullen von einer Person platziert werden, besteht in meinem Mega-Indie-Hit auch die Möglichkeit, gegen das eiserne Gehirn zu spielen. Dies wird wie folgt erreicht:
- Zunächst wird rekursiv (eigentlich nicht) für jeden Spielstatus das erwartete Ergebnis des Spiels berechnet - dasjenige, das erreicht wird, wenn beide Seiten perfekt spielen.
- Dann wird der Spielbaum wie folgt geändert: Anstelle des Zuges des Spielers machen wir jetzt zwei Züge gleichzeitig. Der zweite Schritt ist der Schritt der künstlichen Intelligenz. Außerdem wird aus allen möglichen Antworten auf den Zug des Spielers diejenige mit dem besten erwarteten Ergebnis ausgewählt. Durch Stöbern in einer leeren Zelle geht der Spieler sofort zu der Position, an der ein Kreuz (oder ein Zeh) in dieser Zelle und ein Zeh (oder ein Kreuz) in einer anderen Zelle erschienen sind.
- Alle Spielpositionen, die Zügen entsprechen, die die KI nicht macht, werden rücksichtslos verworfen.
- Dann wird HTML aus den verbleibenden Positionen in einem separaten Ordner generiert - genau wie bei zwei Spielern.
Nach ähnlichen Prinzipien können Sie jedes Spiel mit einem nicht sehr großen Baum implementieren. Wenn ich jedoch auf diese Weise Schach machen möchte, scheint es mir, dass der Github sich weigern wird, dies zu hosten =)
Apropos Github: Sie können dort den gesamten Code sehen (der Link befindet sich auf der Hauptseite des Spiels). Das ist im Allgemeinen alles. Auf Wiedersehen, Mädchen und Jungen. Wir sehen uns wieder.
PS Das Ersetzen von Zeilenumbrüchen von Windows-Stil zu Unix-Stil ist eine sehr lange Zeit, wenn es um 6.000 Dateien geht. Ich bedauerte, dass ich mich zum Zeitpunkt des Schreibens des Codes nicht darum gekümmert hatte, aber ich hielt es immer noch mutig aus.