Text-Abenteuerspiele haben eine ziemlich feste Formel; Es gibt eine Welt, die aus einer Reihe von Räumen besteht, der Spieler kann sich in diesen Räumen bewegen und es gibt einige Gegenstände in den Räumen. Gegenstände können vom Spieler aufgenommen, abgelegt, für den Zugang zu anderen Räumen (z. B. Schlüsseln) verwendet und mit anderen Gegenständen zu neuen Gegenständen kombiniert werden.
Herausforderung
Ihre Herausforderung besteht darin, eine Text-Adventure-Laufzeit in den wenigsten Bytes zu schreiben (Code Golf). Um die Dinge einfach zu halten, müssen Sie nur einen Wahrheits- oder Falsch-Wert ausgeben, je nachdem, ob eine bestimmte Befehlsfolge ein bestimmtes Spiel gewinnen würde oder nicht (keine Interaktivität, keine menschenfreundliche Ausgabe usw.).
Spielregeln
- Die Welt besteht immer aus einem Korridor mit 10 miteinander verbundenen Räumen. Jeder Raum erfordert einen Schlüssel, kann aber jederzeit ohne Schlüssel verlassen werden (es ist also eine Art Riegelschloss, denke ich).
- Der Spieler beginnt in Raum 0 und gewinnt, wenn er Raum 9 betritt (sobald er Raum 9 erreicht hat, kann er tun, was er will, einschließlich in einen anderen Raum gehen, und er hat trotzdem gewonnen).
- Jeder Raum kann beliebig viele Gegenstände enthalten;
- Es gibt bis zu 26 Artikel mit dem Namen AZ, und kein Artikel wird mehr als einmal auf der Welt erscheinen.
- Der Spieler kann Gegenstände aus dem aktuellen Raum aufnehmen und in sein Inventar legen (er kann auch Gegenstände aus seinem Inventar in das aktuelle Zimmer legen).
- Die maximale Inventargröße des Spielers ist begrenzt und wird mit den Leveldetails versehen.
- Zu Beginn des Spiels ist das Inventar des Spielers immer leer.
- Es gibt keine Begrenzung für die maximale Anzahl von Elementen in einem Raum (obwohl die implizite Begrenzung 26 wäre, da dies die Gesamtanzahl von Elementen ist).
- Artikel AJ sind Schlüssel , die verwendet werden können , um eingeben Zimmer 0-9 (dh der Spieler kann auf Raum 0 bewegen , wenn sie Artikel A, auf Raum 1 , wenn sie B usw. beachten Sie, dass Schlüssel nicht einen Raum verlassen erforderlich, und der Spieler beginnt im Raum 0, so dass die Taste „A“ ist nur dann erforderlich , wenn der Spieler will Rückkehr in Raum 0 ;
- Gegenstände im Inventar des Spielers können kombiniert werden, um neue Gegenstände zu erstellen (die im Inventar des Spielers erstellt werden). Die zulässigen Kombinationen werden mit den Leveldetails versehen.
- Durch das Kombinieren von Objekten werden die ursprünglichen Objekte verbraucht (dh wenn eines der Objekte ein Schlüssel war, kann dieser Schlüssel nicht mehr verwendet werden).
- Wenn der Spieler versucht, etwas Unmögliches zu tun (z. B. einen Gegenstand aufheben, der sich nicht im aktuellen Raum befindet, einen Gegenstand ablegen, den er nicht hat, Gegenstände kombinieren, die er nicht hat, in einen Raum gehen, für den er keinen Schlüssel hat for) passiert nichts und sie können weitermachen;
- Der Spieler gibt niemals einen Unsinnbefehl (zB gehe zu Raum 11).
Ein einfaches Spiel könnte also so aussehen:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | J | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 99
Raum 0 enthält den Punkt "C" (der der Schlüssel zu Raum 2 ist). Raum 2 enthält Gegenstand "J" (der Schlüssel zu Raum 9). Der Spieler kann das Spiel gewinnen, indem er C aufhebt, zu Raum 2 geht, J aufhebt und dann zu Raum 9 geht.
Ein komplexeres Spiel könnte sein:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | X |YZ | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 10
C+X => D
Y+Z => J
Jetzt kann der Spieler gewinnen, indem er C aufhebt, sich zu Raum 2 bewegt, X aufhebt, C mit X kombiniert, um D zu erzeugen, und sich dann zu Raum 3 bewegt. Er kann nun Y und Z aufheben und kombinieren, um J zu erhalten Gehe zu Raum 9.
Eingabeformat
Es ist einiges an Eingaben zu erledigen, und das ist eine ziemlich langweilige Aufgabe, sodass das Eingabeformat sehr flexibel ist. Sie erhalten die folgenden Daten, und wie diese an Ihr Programm gesendet werden sollen, liegt weitgehend bei Ihnen:
- Der anfängliche Inhalt jedes Raums (Liste von 0 oder mehr Elementen für jeden Raum);
- Eine Sammlung zulässiger Elementkombinationen (jede enthält 2 Eingabeelemente und ihr Ausgabeelement - beachten Sie, dass die Eingabeelemente ungeordnet sind);
- Die maximale Inventargröße (Ganzzahl, 0 <= Größe <= 26);
- Die Liste der Befehle, die der Spieler versucht hat.
Die Befehle des Spielers können sein:
[P]ick up <item>
- Nimmt einen Gegenstand aus dem Raum und legt ihn im Inventar des Spielers ab (falls Platz vorhanden ist)[D]rop <item>
- wirft einen Gegenstand aus dem Inventar des Spielers in den aktuellen Raum[C]ombine <item1> <item2>
- Kombiniert 2 Gegenstände im Inventar des Spielers, um einen neuen Gegenstand herzustellen[G]o to <room>
- fährt in den gewählten Raum, wenn der Spieler den gewünschten Schlüssel hat
Das Eingabeformat, das ich zum Testen verwendet habe, waren beispielsweise einfache Programmargumente:
./adventure YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ G9
# r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 combinations inv. size commands...
# means:
# room 0 starts with items Y & Z, all other rooms start empty
# 1 combination is possible: Y+Z => J
# max inventory size is 2
# player commands are [P]ick up Y, [P]ick up Z, [C]ombine Y and Z, [G]o to room 9
# (in this example, the player wins)
Wenn es jedoch ein anderes Format erleichtert, ist das in Ordnung (z. B. spezielle Trennzeichen / mehrere Zeilen / unterschiedliche Reihenfolge / nach JSON serialisiert / usw.).
Ausgabeformat
Ihr Programm sollte eine echte Ausgabe zurückgeben, wenn die Befehle des Spielers dazu führen, dass das Spiel gewonnen wird, und eine falsche Ausgabe, wenn dies nicht der Fall ist. Dies kann eine erkennbare Nachricht an stdout, ein Programmrückgabecode oder eine andere von Ihnen gewählte Sprache sein. Alle anderen Ausgaben werden ignoriert.
Testfälle
Das folgende Bash-Skript bietet ein Test-Harness, das die meisten Situationen überprüft. Es wurde geschrieben, um das oben beschriebene Format zu verwenden. Wenn Sie es jedoch ändern, um ein anderes Format zu verwenden, müssen Sie der invoke
Funktion lediglich eine Konvertierung hinzufügen .
#!/bin/sh
PROG="$1";
if [[ -z "$PROG" ]]; then
echo "Usage: $0 <program-to-test>";
exit 1;
fi;
function invoke {
"$PROG" "$@"
}
RED="\033[1;31m";
GREEN="\033[1;32m";
RESET="\033[m";
FAILURES="0";
function pass {
if ! invoke "$@" >/dev/null 2>&1; then
echo "${RED}Expected pass, got fail:${RESET} $*" >&2;
(( FAILURES = "$FAILURES" + 1 ));
invoke "$@" 2>&1;
fi;
}
function fail {
if invoke "$@" >/dev/null 2>&1; then
echo "${RED}Expected fail, got pass:${RESET} $*" >&2;
(( FAILURES = "$FAILURES" + 1 ));
invoke "$@" 2>&1;
fi;
}
echo "Running tests...";
# R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 C I Cmd...
pass J '' '' '' '' '' '' '' '' '' 0 9 PJ G9;
fail '' J '' '' '' '' '' '' '' '' 0 9 PJ G9;
pass J '' '' '' '' '' '' '' '' '' 0 9 PJ PJ G9;
fail J '' '' '' '' '' '' '' '' '' 0 9 PJ;
fail J '' '' '' '' '' '' '' '' '' 0 9 G9;
pass J '' '' '' '' '' '' '' '' '' 0 9 G9 PJ G9;
pass J '' '' '' '' '' '' '' '' '' 0 1 PJ G9;
fail J '' '' '' '' '' '' '' '' '' 0 0 PJ G9;
fail J '' '' '' '' '' '' '' '' '' 0 9 PJ DJ G9;
fail J '' '' '' '' '' '' '' '' '' 0 9 PJ PJ DJ G9;
pass J '' '' '' '' '' '' '' '' '' 0 9 PJ DJ PJ G9;
pass J '' '' '' '' '' '' '' '' '' 0 9 PJ DJ PJ G9;
pass B CJ '' '' '' '' '' '' '' '' 0 2 PB G1 DB PC PJ G9;
fail B CJ '' '' '' '' '' '' '' '' 0 2 PB G1 DB PB PC PJ G9;
pass AJ '' '' '' '' '' '' '' '' '' 0 2 PA PJ G9;
pass B D '' J '' '' '' '' '' '' 0 2 PB G1 PD G3 DB PJ G9;
fail B D '' J '' '' '' '' '' '' 0 2 PB G1 PD G2 DB PJ G9;
fail B D '' J '' '' '' '' '' '' 0 2 PB G1 PD G3 PJ G9;
fail B D J C '' '' '' '' '' '' 0 2 PB G1 PD G3 PJ G9;
pass AJ '' '' '' '' '' '' '' '' '' 0 2 PA PJ G9 G0;
fail ADJ '' '' '' '' '' '' '' '' '' 0 3 PA PD PJ G3 DJ G0 PJ G9;
pass ADJ '' '' '' '' '' '' '' '' '' 0 3 PA PD PJ G3 DJ G0 G3 PJ G9;
fail ADJ '' '' '' '' '' '' '' '' '' 0 3 PA PD PJ G3 DJ G0 DD G3 PJ G9;
pass ADJ '' '' '' '' '' '' '' '' '' 0 3 PA PD PJ DD G3 DJ G0 DD G3 PJ G9;
fail ADJ '' '' '' '' '' '' '' '' '' 0 1 PA DA DA PD PJ G9;
pass ADJ '' '' '' '' '' '' '' '' '' 0 1 PA DA DA PJ G9;
fail ABCDEFGHIKLMNOPQRSTUVWXYZ J '' '' '' '' '' '' '' '' 0 26 PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PT PU PV PW PX PY PZ G9;
pass ABCDEFGHIJKLMNOPQRSTUVWXYZ '' '' '' '' '' '' '' '' '' 0 26 PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PT PU PV PW PX PY PZ G9;
fail YZJ '' '' '' '' '' '' '' '' '' 0 2 PY PZ CYZ PJ G9;
pass YZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PJ G9;
pass YZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PJ CWJ G9;
fail XYZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PX PJ G9;
fail XYZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PX DY DZ PJ G9;
pass XYZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PX DW PJ G9;
pass YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 CYZ G9;
pass YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ DJ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ DJ PY PZ CYZ G9;
fail WZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PW PZ CYZ G9;
fail WZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ G9;
pass YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CZY G9;
pass YZ '' '' '' '' '' '' '' '' '' 1 ZYJ 2 PY PZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 1 PY PZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 1 PY PZ CYZ PY PZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 1 PY PZ CYZ PJ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 1 PJ G9;
pass BW UV '' '' '' '' '' '' '' '' 3 BUR WVS RSJ 2 PB PW G1 DW PU CBU DR PW PV CVW PR CRS G9;
fail BW AUV '' '' '' '' '' '' '' '' 3 BUR WVS RSJ 2 PB G1 PU CBU DR PA PB G0 DA PW G1 PV CVW PR CRS G9;
pass BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PC PA PB G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW UV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PC PA PB G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU PA PB G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PA G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PB G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PA PB G0 DA G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PA PB G0 DA PW G1 DB CVW PR CRS G9;
pass BFK LG M N O CDE PQR U W '' 10 BPT CQS TSH HUI IWV VFA GRX MXZ ANY YZJ 5 \
PB PF PK G1 PL PG G6 DB DK DL G5 PC PD PE G6 DF G2 PM G6 DM DC G3 PN G4 PO G6 DN DO DD DE \
PB PP CBP PC PQ CCQ CTS G7 PU CUH G8 PW CWI G6 PF CVF PR PM PN CGR CMX CAN CYZ G9
fail BFK LG M N O CDE PQR U W '' 10 BPT CQS TSH HUI IWV VFA GRX MXZ ANY YZJ 5 \
PB PF PK G1 PL PG G6 DB DK DL G5 PC PD PE G6 DF G6 DM DC G3 PN G4 PO PM G6 DN DO DD DE \
PB PP CBP PC PQ CCQ CTS G7 PU CUH G8 PW CWI G6 PF CVF PR PM PN CGR CMX CAN CYZ G9
if (( "$FAILURES" == "0" )); then
echo "${GREEN}All tests passed${RESET}";
else
echo "${RED}Total failures: $FAILURES${RESET}";
fi;
Gewinnen
Standard Code Golf: Der kürzeste Code (in Bytes) gewinnt. Die Beiträge müssen den Spielregeln entsprechen, was in der Praxis bedeutet, dass sie alle Testfälle bestehen müssen (bei Bedarf können weitere Tests hinzugefügt werden).
quelle
Antworten:
JavaScript (ES6), 244
249 267 280Bearbeite gespeicherte 18 (!) Bytes dank @Neil
Eine Funktion mit Eingabe:
Gibt true oder false zurück
Im Test-Snippet unten finden Sie eine durch Zeilenumbrüche getrennte Version
Prüfung
quelle
.map
!a>8
in()
s? Kannj[--s,a]=1
werdenj[a]=s--
? Ist auchString.fromCharCode
viel zu lang, warum nicht einfach in indexieren"ABCDEFGHIJ"
?C 338 Bytes
Ich habe versucht, mein eigenes Testprogramm zu optimieren. Ich denke, es ist ganz gut gelaufen, auch wenn es die bisher längste Antwort ist!
Das spart mit ein paar Tricks Platz:
Nervenzusammenbruch:
Teilweise inspiriert von der Antwort von @ edc65.
Ich war so nah an bekommen
;*++*v;
undc[P][c]
in den Code für die ultimative Verwirrung, aber leider andere Optionen stellte sich heraus , kürzer sein :(quelle
Haskell,
354325323 BytesDefiniert eine Funktion,
!
die die Reihenfolge annimmtRückgabe
True
oderFalse
. Beispielaufruf:Alle Testfälle .
Viele Bytes werden für den Spielstatus ausgegeben. Haskell kann Datenstrukturen wie Räume und Inventar nicht zerstörerisch aktualisieren.
Die Arbeit wird durch eine Funktion erledigt,
g
die 4 Parameter übernimmt: das Inventar (String), den aktuellen Raum (Integer), die Räume (Assoc-List, mit Schlüssel: Raumnummer und Wert: Items) und die verbleibenden Befehle (List of String). .Vielleicht können die folgenden Dinge einige Bytes sparen
Eine einzelne Assoc-Liste für die Schlüssel (Schlüssel: Schlüsselbuchstabe, Wert: Raumnummer mitNein, die Erstellung einer solchen anfänglichen Assoc-Liste und die Überprüfung auf maximale Inventargröße kostet mehr als es den Handel erspart mit einem Parameter weniger.-1
für Inventar) anstelle von Räumen / Inventarquelle
s
als Inventar Nutzungsänderungen, um zu überprüfen, um zu vermeidenlength i
(Sie überprüfen könnten ,s
gegen 0 statt)s
es zum fünften Parameter von machen würde und es herumgereicht werdeng
müsste. Ich habe 5 rekursive Aufrufeg
, ein zusätzlicher Parameter kostet mindestens 6 Bytes.Python 3,
321311 Bytes-10, danke Dave
Räume (r), Kombinationen (c) und Züge (m) sind Listen von Zeichenfolgen. Maximales Inventar (i) ist ein int.
Ziemlich unkomplizierte Implementierung. Verwendete Sets () für den Rauminhalt und das Inventar, um die Aktualisierung zu vereinfachen. Verwendete Frozensets, um ein Wörterbuch der Kombinationen zu tasten, sodass die Reihenfolge der 2 Eingabeelemente irrelevant ist.
quelle
import sys;r=sys.argv[1:11];nc=int(sys.argv[11]);c=sys.argv[12:12+nc];i=int(sys.argv[12+nc]);m=sys.argv[13+nc:];exit(not f(r,c,i,m))
Testset mit diesem: (Semikolon -> Zeilenumbruch). Sieht übrigens so aus, als wärst du drin geblieben,dbg=False
. Sie können 10 Bytes sparen, indem Sie es entfernen!