Ein kleines Abenteuer

14

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

Dave
quelle
Sie werden mir vielleicht nicht glauben, aber ich dachte an eine Herausforderung, die ziemlich genau so ist wie diese vor ein paar Tagen ...
Acrolith
Ich mag diese Herausforderung. Allerdings würde ich definitiv Testfälle außerhalb Ihres Testskripts einschließen.
Nathan Merrill
@ NathanMerrill kann, welches Format würdest du bevorzugen? (Die Testfälle im Skript sind bereits recht einfach zu analysieren, daher war ich mir nicht sicher, was ich tun sollte, um eine Testtabelle zu erstellen, ohne einfach die gleichen Zeilen zu wiederholen!)
Dave,
@daHugLenny Ich hatte vor ein paar Tagen auch die Idee. Ich denke, es ist möglich, dass wir beide von einer Herausforderung inspiriert wurden, die letzte Woche veröffentlicht wurde, oder von einer anderen Frage im Netzwerk. Ich kann mich nicht erinnern, woher ich die Idee hatte.
Dave
Löschen eines Elements, das der Benutzer nicht hat. Ist es unmöglich (no op) oder Unsinn (wird nicht passieren). Und einen nicht existierenden Gegenstand fallen lassen?
Edc65

Antworten:

5

JavaScript (ES6), 244 249 267 280

Bearbeite gespeicherte 18 (!) Bytes dank @Neil

Eine Funktion mit Eingabe:

  • r = Rauminhalt (Array mit 10 Strings)
  • k = Kombinationen (String-Array mit 3 Zeichen - Quelle1, Quelle2, Ergebnis)
  • s = Inventar maximale Größe (Anzahl)
  • c = Befehle (Array von Strings)

Gibt true oder false zurück

(r,k,s,c,p=0,j={})=>c.some(([c,a,b])=>c<'D'?j[a]>0&j[b]>0&&!k.map(([t,u,v])=>u+t==a+b|u+t==b+a?j[j[a]=j[b]=v]=++s:0):c<'G'?j[a]>0&&!(j[++s,a]=~p):c>'G'?s&&j[a]==~p&&!(j[a]=s--):j['ABCDEFGHIJ'[a]]>0&&(p=a)>8,r.map((o,n)=>[...o].map(c=>j[c]=~n)))

Im Test-Snippet unten finden Sie eine durch Zeilenumbrüche getrennte Version

Prüfung

Exec=
(r,k,s,c,p=0,j={})=>
c.some(
  ([c,a,b])=>
   c<'D'?j[a]>0&j[b]>0&&!k.map(([t,u,v])=>u+t==a+b|u+t==b+a?j[j[a]=j[b]=v]=++s:0)
   :c<'G'?j[a]>0&&!(j[++s,a]=~p)
   :c>'G'?s&&j[a]==~p&&!(j[a]=s--)
   :j['ABCDEFGHIJ'[a]]>0&&(p=a)>8
  ,r.map((o,n)=>[...o].map(c=>j[c]=~n))
)

console.log = (...x) => O.textContent += x + '\n';

;`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`
.split(/;*\n/).map((srow,i)=>{
  var row=srow.split(/\s+/),
  rooms=row.slice(1,11).map(x=>x=="''"?"":x),
  ncomb=+row[11],
  comb=row.slice(12,12+ncomb),
  isize=+row[12+ncomb],
  commands=row.slice(13+ncomb),
  start='['+rooms+'] ['+comb+'] '+isize+' ['+commands+']';
  var result=Exec(rooms,comb,isize,commands),
     ok = row[0] == ['fail','pass'][~~result]
  console.log(i, ok ? 'ok':'ko', start, row[0], result)
})
<pre id=O></pre>

edc65
quelle
Schöne (ab) Verwendung von .map!
Dave
Warum ist a>8in ()s? Kann j[--s,a]=1werden j[a]=s--? Ist auch String.fromCharCodeviel zu lang, warum nicht einfach in indexieren "ABCDEFGHIJ"?
Neil
@Neil danke für die Hinweise, ich werde sie alle überprüfen. Offensichtlich ist dies das Ergebnis einer Reihe von Änderungen (irgendwann muss j [] genau 1 sein, aber jetzt können sie wahrscheinlich einen beliebigen positiven Wert haben)
edc65
3

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!

#define P c[(i<j?i:j)*25+i+j]
#define F for(q=atoi(*++v);r
#define X c[r*91+i]
r,i,j,c[2405];main(q,v)char**v;{for(r=10;--r;)for(++v;i=**v;++*v)++X;++v;F<q;++r)i=**++v,j=1[*v],P=2[*v];r=9;F&&*++v;c[i=1[*v]]&&j==68?c[i]=!++X,++q:j>79&&q*X?c[i]=!--X,--q:j==71&&c[i+17]?r=57-i:j<68&&c[i]*c[j=2[*v]]&&P?c[i]=c[j]=0,c[P]=++q:0)j=**v;return r;}

Das spart mit ein paar Tricks Platz:

  • Die Zimmer werden in umgekehrter Reihenfolge geladen, sodass die Suche nach Zimmer 9 zur Suche nach Zimmer 0 wird, was billiger ist
  • Der Inhalt von Raum 9 spielt keine Rolle, daher wird er beim Lesen der Eingabe übersprungen und stattdessen zum Speichern des Inventars verwendet
  • Der Rauminhalt und die Artikelkombinationen werden in demselben Array gespeichert. Da Objekte mit ihren ASCII-Werten gespeichert werden, überlappen sie sich nie.

Nervenzusammenbruch:

#define P c[(i<j?i:j)*25+i+j]       // item combination lookup (input: i,j)
#define X c[r*91+i]                 // room item lookup (input: r,i)
r,i,j,c[2405];                      // globals default to 0
main(q,v)char**v;{                  // K&R syntax to save bytes
    for(r=10;--r;)                  // Load rooms 0-8, store as 9-1
        for(++v;i=**v;++*v)
            ++X;
    ++v;                            // Skip room 9
    for(q=atoi(*++v);r<q;++r)       // For each combination
        i=**++v,
        j=1[*v],                    // Use index[array] syntax to avoid (brackets)
        P=2[*v];                    // Record combination
    r=9;                            // Begin in room 0 (9 in memory)
    for(q=atoi(*++v);               // Load inventory size
                     r              // While not in room 9 (0 in memory)...
                      &&*++v;       // ...and still have user commands
                                    // (ISO C promises a NULL at the end of argv)
        c[i=1[*v]]&&j==68?          // If 'D'rop, and we have the item:
            c[i]=!++X,              //  Drop it
            ++q:                    //  Increase our inventory capacity
        j>79&&                      // If 'P'ick up, and...
              q                     // ...we have capacity in our inventory and...
               *X?                  // ...the item is in the room:
            c[i]=!--X,              //  Pick it up
            --q:                    //  Decrease our inventory capacity
        j==71&&c[i+17]?             // If 'G'o to room, and we have the key:
            r=57-i:                 //  Go to the room
        j<68&&                      // If 'C'ombine, and...
              c[i]*c[j=2[*v]]       // ...we have the items and...
                             &&P?   // ...they can be combined
            c[i]=c[j]=0,            //  Remove the items
            c[P]=++q:               //  Add the combined item and increase capacity
        0                           // Unrecognised or invalid command
    )
        j=**v;                      // 'j' is the command letter (happens first)
    return r;                       // Return the final room (0 = truthy in shell)
}

Teilweise inspiriert von der Antwort von @ edc65.


Ich war so nah an bekommen ;*++*v;und c[P][c]in den Code für die ultimative Verwirrung, aber leider andere Optionen stellte sich heraus , kürzer sein :(

Dave
quelle
2

Haskell, 354 325 323 Bytes

(#)=elem
(#)=elem
(%)=filter.(/=)
m!s=g""0.zip[0..]where g _ p _[]=p>8;g i p r(c:d)|p>8=1<2|'P':[k]<-c,k#x,length i<s=g(k:i)p((p,k%x):r)d|'D':[k]<-c,k#i=g(k%i)p((p,k:x):r)d|'C':q@[k,l]<-c,k#i,l#i,[y]<-[f|[d,e,f]<-m,q==[d,e]||q==[e,d]]=g(y:k%(l%i))p r d|'G':n<-c,y<-read n,['A'..]!!y#i=g i y r d|1<2=g i p r d where Just x=lookup p r

Definiert eine Funktion, !die die Reihenfolge annimmt

  • die möglichen Kombinationen als Liste von 3 Buchstabenfolgen
  • die maximale Größe des Inventars
  • die zimmer als liste von 9 saiten
  • Der Spieler befiehlt als Liste von Zeichenfolgen

Rückgabe Trueoder False. Beispielaufruf:

*Main> (!) ["YZW"] 2 ["YZJ","","","","","","","","",""] ["PY","PZ","CYZ","PJ","CWJ","G9"]
True

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

g _ p _[] = p>8                     -- base case. if no commands left, return
                                    -- True if we are in room 9
g i p r(c:d)
  | p>8 =   1<2                     -- reached room 9
  | 'P':[k]<-c,                     -- 'Pickup', if
        k#x,                        --   key is in room and
        length i<s                  --   inventory not full
        = g(k:i)p((p,k%x):r)d       --   adjust inventory and room
  | 'D':[k]<-c,                     -- 'Drop', if
        k#i                         --   key is in inventory
        = g(k%i)p((p,k:x):r)d       --   adjust inventory and room
  | 'C':q@[k,l]<-c,                 -- 'Combine', if
        k#i,l#i,                    --   both keys are in inventory and
        [y]<-[f|[d,e,f]<-m,q==[d,e]||q==[e,d]]
                                    --   combination is possible
        = g(y:k%(l%i))p r d         --   adjust inventory
  | 'G':n<-c, y<-read[n],           -- 'Goto', convert digit to integer  
        ['A'..]!!y#i                --   key for room is in inventory
        = g i y r t                 --   go to room
  | 1<2                             -- impossible command
        = g i p r d                 --   ignore it

Vielleicht können die folgenden Dinge einige Bytes sparen

  • Staatsmonade für den Spielzustand
  • Eine einzelne Assoc-Liste für die Schlüssel (Schlüssel: Schlüsselbuchstabe, Wert: Raumnummer mit -1für Inventar) anstelle von Räumen / Inventar Nein, 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.
nimi
quelle
Nett. Ich weiß nicht genug Haskell zu überprüfen, aber Sie könnten in der Lage , einige Bytes durch Erhöhen / Erniedrigen speichern sals Inventar Nutzungsänderungen, um zu überprüfen, um zu vermeiden length i(Sie überprüfen könnten , sgegen 0 statt)
Dave
@ Dave: Ich denke nicht, dass es sich auszahlt, weil das Ändern ses zum fünften Parameter von machen würde und es herumgereicht werden gmüsste. Ich habe 5 rekursive Aufrufe g, ein zusätzlicher Parameter kostet mindestens 6 Bytes.
Nimi
1

Python 3, 321 311 Bytes

-10, danke Dave

S,F=set,frozenset
def f(r,c,i,m):
 w,v,r,c=0,S(),list(map(S,r)),{F(k):S(x)for*k,x in c}
 for a,*q in m:
  p=F(q)
  if a<'D'and p in c and p<=v:v-=p;v|=c[p]
  elif a=='D'and p<=v:r[w]|=p;v-=p
  elif a=='G'and F(chr(65+int(q[0])))<=v:w=int(q[0])
  elif a>'G'and p<=r[w]and len(v)<i:r[w]-=p;v|=p
  if w==9:return 1

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.

RootTwo
quelle
Cool. Verifiziert es am 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!
Dave