Als Kind habe ich das Intellivision-Spiel Advanced Dungeons and Dragons: Treasure of Tarmin gespielt . Die 3-D-Grafik versetzt Sie in eine Perspektive aus der ersten Person mit schockierendem Realismus:
Aber dann habe ich einen C-64 bekommen. Und ich konnte auf dem 40x25-Zeichenraster zeichnen, indem ich über den Bildschirm flog, die Farbe mit der Strg-Taste und einer Ziffer einstellte und Symbole an einer beliebigen Stelle platzierte (warum bash
ließ ich das nicht zu?) . Der Zeichensatz hatte dreieckige Komponenten und feste Blockkomponenten. So konnte ich überlegen, wie man durch dieses Medium eine Darstellung seiner Perspektive in einem Raster erzeugen könnte.
Ich habe diese Woche die fast drei Jahrzehnte alte Spezifikation über "Dungeon Construction Set" in spiralgebundenem Notizbuchpapier gefunden:
( UPDATE : Vorsichtige Leser werden bemerken, dass dies bei den schrägen Teilen nicht ganz zusammenhält. Die korrigierten Zahlen sind unten angegeben.)
Obwohl Treasure of Tarmin auf einem Gitter gespielt wurde, existierten die Wände nur an den Rändern von Gitterfeldern. Nachdem ich gelernt hatte, was Bytes sind, wurde mir klar, dass jedes Quadrat auf der Karte vier mögliche Zustände für jeden seiner Ränder haben könnte, wenn ich die Karte aus Bytes zusammensetze:
- Ungehindert
- Mauer
- Tür
- Etwas anderes?
Ich bin nie dazu gekommen, es zu schreiben (bis letzte Nacht). Ich dachte, es könnte Spaß machen, wenn andere es versuchen.
Ihre Aufgabe ist es also, einen auf dem Zeichenmodus basierenden Labyrinth-Renderer zu implementieren, der meine (korrigierte !!) Spezifikation implementiert, aber die Technologien von 2013 verwendet.
Eingang
Da die Spezifikation kein Rendering für Türen definiert, gehen wir einfach davon aus, dass die einzigen Optionen Wand-und-nicht-Wand sind. Der Einfachheit halber handelt es sich bei Ihrer Eingabe um eine Karte, die aus folgenden Zeichenfolgen besteht:
WN.. .N.. .N.. .N.. .N.E
W... .... .... ..S. ...E
W... .N.E W... .N.. ...E
W... .... .... .... ...E
W.S. ..S. ..S. ..S. ..SE
Das wäre eine 5x5 Karte. In der oberen linken Ecke (1,1) ist die W
est- und N
orth-Wand eingestellt. In der unteren rechten Ecke (5,5) ist die S
äußere und die äußere E
Wand festgelegt.
Ohne Kartennavigation macht das deutlich weniger Spaß. Stellen Sie Ihren Player also mindestens auf (1,1) nach Norden und bieten Sie ihm Folgendes an:
[F]orward, [B]ackward, turn [L]eft, turn [R]ight or [Q]uit?
Geben Sie bei jedem Schritt eine 16x15-Anzeige der Perspektive der ersten Person aus, wie in der Notebook-Papierspezifikation definiert. Damit Sie nicht zählen müssen, sind die Abmessungen der flachen Wände in den drei Abständen wie folgt:
14x13 (directly in front of you; e.g. wall is in same cell)
8x7 (one step away)
6x5 (two steps away)
Die Begrenzungsgrößen der schrägen Wände sind:
1x15 (your direct left or right; e.g. wall is in same cell)
3x13 (one step away)
1x7 (two steps away)
Klarstellungen
Benachbarte Zellen stimmen möglicherweise nicht mit geteilten Wänden überein. Die Südkante eines Quadrats könnte also eine Mauer sein, während die Nordkante des Quadrats südlich davon frei wäre. Im ursprünglichen Design betrachtete ich dies als ein Merkmal: Es ermöglicht interessante Ideen wie Einweg-Türen ... oder unsichtbare Wände, die erst erscheinen, nachdem Sie sie passiert haben. Befolgen Sie für diese Vereinfachung die gleiche Regel: Achten Sie beim Navigieren und Rendern nur auf den Kantenstatus in der Zelle , die Ihnen in der Blickrichtung am nächsten liegt .
Die Ansicht ist mit "Schattierung" viel besser. Wechseln Sie also für Ihre vollständigen Blöcke entweder Unicode 2593 ▓ und 2591 ░ oder verwenden Sie
X
und,+
wenn Ihre Implementierung ASCII ist.Unicode-Dreieck-Zeichen (25E2 ◢, 25E3 ◣, 25E4 ◤, 25E5 ◥) sind zum Zeichnen etwas lahm. Abgesehen davon, dass sie keine schattierten Varianten haben, strecken sie oft nur die Breite des Zeichens und nicht die volle Höhe ... selbst bei Schriften mit fester Breite. Sie können ganze Blöcke oder Schrägstriche oder etwas von Ihrer Wahl an den Stellen zeichnen, an denen ich Diagonalen haben wollte. Interessante kreative Lösungen, die Farbe einbeziehen und diese Zeichen anstelle von Schattierungen verwenden, werden geschätzt.
Sie können davon ausgehen, dass die äußersten Wände den Spielbereich begrenzen, sodass Sie sich nicht darum kümmern müssen, etwas außerhalb des Labyrinths zu rendern. Alle Wände, die weiter von Ihnen entfernt sind als die Spezifikation, werden ignoriert und lassen nur leeren Raum.
Die Schattierung der Wand, die Sie direkt vor sich sehen, wenn Sie bei (1,1) nach Norden blicken, sollte DUNKEL sein. Alternative Schattierung benachbarter Wände auf der Karte, sodass eine helle Wand niemals an eine dunkle Wand stoßen würde, wenn alle Wände vorhanden wären.
Eine C-64-Implementierung, die tatsächlich das tut, was ich ursprünglich beabsichtigt hatte ... mit den diagonalen Zeichen und allem ... wird jedes andere Eingabekriterium übertreffen. :-)
Beispiele
Für die oben angegebene Beispielkarte ...
Bei (1,3) nach Süden:
/
/+
/X+
/XX+
/XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
\XXX+
\XX+
\X+
\+
\
Bei (3,2) nach Süden:
/* blank line */
X /
X /+
X /++
X +++
X +++
X +++
X +++
X +++
X +++
X +++
X \++
X \+
X \
/* blank line */
Bei (3,2) nach Osten:
/* blank line */
/
/X
/XX
XXX
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
XXX
\XX
\X
\
/* blank line */
Bei (2,3) nach Norden:
/
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
\
quelle
X
s aus Ihrer Sicht3, 2
nach Süden erklären ?Antworten:
Commodore 64 Basic
Mann, das hat Spaß gemacht. Und schwer. C64 Basic ist fast nicht fehlerfrei, Sie können nicht einmal das
print
Debuggen verwenden, da der Bildschirm bereits zum Rendern des Dungeons verwendet wird. Sie wissen, dass Sie Spaß haben, wenn Sie Code wie schreiben55250 goto 55110
. Dijkstra wird mich töten.Das Programm verwendet zwei Farben und diagonale Zeichen.
Unnötig zu erwähnen, dass ich nicht Golf gespielt habe. Schließlich heißt es jetzt Code-Challenge . Es sind 7183 Bytes, wenn Sie interessiert sind.
Es ist langsam - bei der Standardgeschwindigkeit dauert es einige Sekunden, bis die Szene gerendert ist. Die maximale Kartengröße beträgt 10 x 10, sie kann jedoch durch Bearbeiten der Zeile 120 geändert werden.
Ich habe dies mit dem VICE- Emulator entwickelt und getestet . Der folgende Code wird in ASCII angezeigt, dh verschobenes PETSCII. Bei der Eingabe der Karte sollten Sie jedoch unverschobenes PETSCII verwenden .
Bildschirmfoto:
Code:
Bandbild: hier herunterladen .
Die Beispiele:
quelle
Ich musste jetzt einfach.
Bash, 12743 Zeichen
Bitte denken Sie daran, dass dies so ziemlich das erste war, was ich getan habe
bash
, als nur ein paar Befehle zusammenzupfeifen. Es wäre wahrscheinlich um einiges reduzierbar, wenn ich nicht alle Wände fest codiert hätte, aber es schien einfacher zu sein. Es hat überhaupt keine Konsistenz. Das Byte-Format für jedes Quadrat wird auf schreckliche Weise ausgewählt. Aber es funktioniert.Ich habe sogar Unterstützung für die Bewegung durch die Pfeiltasten hinzugefügt :)
Dies sind einige Screenshots für die Beispieleingabe (Beachten Sie, dass meine Karte bei (0 | 0) beginnt):
Abgesehen von der vierten sehen sie alle wie die Muster aus (siehe meinen Kommentar zum OP).Diese Screenshots wurden mit urxvt v9.15 mit 256-Farben-Unterstützung aufgenommen. Auf einem 88-Farben-Terminal würde es wahrscheinlich ziemlich beschissen aussehen, und Terminals ohne Unicode-Unterstützung funktionieren überhaupt nicht. Die Schriftart, die ich verwendete, war Source Code Pro von Adobe.
quelle
Hier ist meine Version in Python 3. Es ist so etwas wie 3k-Zeichen und könnte mit ein wenig Aufwand ein bisschen kleiner werden (es gibt viele Leerzeichen, die entfernt werden könnten, um damit zu beginnen).
Derzeit werden
+X/\
Zeichen als Zeichnungszeichen verwendet, es ist jedoch für das Zeichnen mit Unicode-Zeichen eingerichtet, wenn Sie eine Schriftart mit fester Breite verwenden, die diese ordnungsgemäß darstellt. Es unterstützt die Verwendung separater Kacheln für die abgewinkelten Teile der unterschiedlich gefärbten Wände, obwohl ich diese Funktion nicht verwende. Außerdem können Sie Decken-, Boden- und "entfernte" Kacheln bereitstellen und verschiedene verwenden, wenn der Spieler nach Osten oder Westen gegen Norden oder Süden zeigt. Leider sah das nie sehr gut aus, also sollten wahrscheinlich alle leer sein (oder so etwas wie fest█
).Leider hatte ich auf meinem Windows 7-System eine schreckliche Zeit damit, eine nichtproportionale Schriftart mit dem vollständigen Satz von Blockzeichen (z . B.
▜
und▟
) zu finden. Die meisten von denen, die ich gefunden habe, konnten auscmd
irgendeinem Grund nicht in der Konsole verfügbar gemacht werden (vielleicht, weil sie nicht perfekt monospaced sind?). Wenn Sie der Meinung sind, dass Ihre Konsole funktionsfähiger ist, verwenden Sie den alternativen Zeichensatz, den ich oben in der Datei auskommentiert habe, was auch mit nur zwei Farben nicht schlecht aussieht. Es hat Decken und Böden und größtenteils transparente Wände ausgefüllt.Der Code:
Der Zeichensatz wird oben in der Datei angegeben. Die Reihenfolge der Zeichen ist:
/
mit einer Wand darunter)Es gibt 15 Wände, die möglicherweise vom Spiel in einem Muster wie diesem gerendert werden müssen (mit
V
Angabe der Position und des Blickwinkels des Spielers):Die von den 15 Wänden verwendeten Kacheln werden in der
shapes
Liste definiert . Es ist eine Liste von 2 Tupeln. Der erste Wert des Tupels gibt die "Parität" der Wand an, wobei angegeben wird0
, dass diese mit den gleichen Zeichen wie eine Wand direkt vor dem Zeichen gezeichnet werden soll und1
dass es sich um das Alternativmuster (z . B.+
vsX
) handeln soll. Der zweite Wert ist eine Liste vonx,y,t
Tupeln, die die Bildschirmkoordinaten und den Kachelindex eines Pixels angeben (Wände, die mit ungerader Parität gerendert werden, werden1
zu jedem dieser Indizes hinzugefügt). Die Formen sind nach Abstand geordnet, sodass die ersten drei die senkrechten Wände, zwei Kacheln vor dem Zeichen, gefolgt von den beiden parallelen Wänden, zwei Kacheln vor dem Zeichen usw. darstellen.Die Funktionen sind:
rr
: "Rendern" des Bildschirms (durch Drucken der Kacheln im Bildschirmpuffer).dw
: "Wände zeichnen" in einen bereitgestellten Bildschirmpuffer. Hierbei wird der Maleralgorithmus verwendet, sodass die am weitesten entfernten Wände zuerst gezeichnet werden und möglicherweise von näheren verdeckt werden.ga
: "get area" gibt eine Liste mit Booleschen Werten zurück, die angibt, welche Wände für eine bestimmte Kartenposition und Ausrichtung undurchsichtig sind.rd
: "read", ein Generator, der die Karte liest und die Linien liefert. Dies ist nur erforderlich, weil die IDLE-Konsole seltsame Dinge tut, wenn Sie mehrzeilige Eingaben einfügen, anstatt jeweils eine Zeile einzugeben.rm
: "Karte lesen" parst die Karte in eine verschachtelte Liste von Booleschen Werten, die mitm[y][x][d]
(d=0
als Osten undd=1
als Süden) indiziert sind . Außerdem werden zwei Zeilen und zwei Spalten mit Auffüllquadraten hinzugefügt, um Indexfehler im anderen Code zu vermeiden.cl
: "lösche" die Ausgabe (indem du genug Zeilenumbrüche schreibst, um die alte Ansicht von der Oberseite der meisten Konsolen zu scrollen).gl
: "game loop", wo die Eingabe gesammelt wird und das oben genannte Zeug aufgerufen wird.Ein paar "Screenshots":
Die Ausgangsposition:
Blick entlang der Nordwand:
Einige Aufnahmen, die Ihren Beispielen entsprechen (beachten Sie, dass die leeren ersten Zeilen vom Stapelüberlauf abgeschnitten werden und in der Programmausgabe enthalten sind):
Und:
Hier ist eine der seltsamsten Ansichten auf der mitgelieferten Karte, da die Wand parallel zu unserer Ansicht dieselbe Farbe hat wie die senkrechte Wand, die dahinter herausragt:
So würde der Bereich der letzten Aufnahme von oben aussehen:
quelle