Tekstowe gry przygodowe mają dość ustaloną formułę; istnieje świat złożony z szeregu pomieszczeń / przestrzeni, gracz może poruszać się po tych pokojach, a w pokojach jest kilka przedmiotów. Przedmioty mogą być podnoszone przez gracza, odkładane, używane do uzyskiwania dostępu do innych pomieszczeń (np. Klucze) i łączone z innymi przedmiotami w celu tworzenia nowych przedmiotów.
Wyzwanie
Twoim wyzwaniem jest napisanie tekstowego środowiska wykonawczego przygodowego w jak najmniejszej liczbie bajtów (kod golfowy). Aby uprościć wszystko, wszystko, co musisz zrobić, to wygenerować wartość true lub falsey w zależności od tego, czy dana seria poleceń wygrałaby daną grę, czy nie (brak interaktywności, brak przyjaznych dla człowieka wyników itp.)
Zasady gry
- Świat zawsze składa się z korytarza z 10 połączonymi pokojami. Każdy pokój wymaga klucza, aby wejść, ale można w dowolnym momencie wyjść z niego bez klucza (więc to chyba jakaś blokada zatrzasku);
- Gracz zaczyna w pokoju 0 i wygrywa, jeśli kiedykolwiek wejdzie do pokoju 9 (po osiągnięciu pokoju 9 może zrobić, co chce, w tym przejść do innego pokoju i nadal wygra);
- Każdy pokój może zawierać dowolną liczbę przedmiotów;
- Istnieje do 26 przedmiotów o nazwie AZ i żaden element nie pojawi się na świecie więcej niż jeden raz;
- Gracz może podnosić przedmioty z bieżącego pokoju i umieszczać je w ekwipunku (może również upuszczać przedmioty z ekwipunku do bieżącego pokoju);
- Maksymalny rozmiar ekwipunku gracza jest skończony i zostanie dostarczony ze szczegółami poziomu;
- Na początku gry ekwipunek gracza jest zawsze pusty;
- Nie ma ograniczenia maksymalnej liczby przedmiotów w pokoju (choć domyślny limit wynosiłby 26, ponieważ jest to całkowita liczba przedmiotów);
- Przedmioty AJ to klucze, których można użyć do wejścia do pomieszczeń 0-9 (tj. Gracz może przejść do pokoju 0, jeśli ma przedmiot A, do pokoju 1, jeśli ma B, itp. Należy pamiętać, że klucze nie są wymagane do opuszczenia pokoju, a gracz zaczyna w pokoju 0, więc klawisz „A” jest wymagany tylko wtedy, gdy gracz chce wrócić do pokoju 0);
- Przedmioty w ekwipunku gracza można łączyć, aby tworzyć nowe przedmioty (które zostaną utworzone w ekwipunku gracza) - dozwolone kombinacje zostaną podane ze szczegółami poziomu;
- Łączenie przedmiotów zużywa oryginalne przedmioty (tj. Jeśli jeden z przedmiotów był kluczem, nie będzie już można użyć tego klucza);
- Jeśli gracz próbuje zrobić coś niemożliwego (np. Podnieść przedmiot, który nie znajduje się w bieżącym pokoju / upuścić przedmiot, którego nie ma / połączyć przedmioty, których nie ma / udać się do pokoju, nie ma klucza dla) nic się nie dzieje i mogą kontynuować;
- Gracz nigdy nie wyda bezsensownego polecenia (np. Przejdź do pokoju 11).
Prosta gra może wyglądać następująco:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | J | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 99
Pokój 0 zawiera element „C” (który jest kluczem do pokoju 2). Pokój 2 zawiera element „J” (który jest kluczem do pokoju 9). Gracz może wygrać grę, podnosząc C, przechodząc do pokoju 2, podnosząc J, a następnie przechodząc do pokoju 9.
Bardziej złożona gra może być:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | X |YZ | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 10
C+X => D
Y+Z => J
Teraz gracz może wygrać, podnosząc C, przechodząc do pokoju 2, podnosząc X, łącząc C z X, aby utworzyć D, a następnie przechodząc do pokoju 3. Mogą teraz podnieść i połączyć Y i Z, aby uzyskać J, pozwalając im na idź do pokoju 9.
Format wejściowy
Jest sporo do zrobienia, a to dość nudne zadanie, więc format wejściowy jest bardzo elastyczny. Otrzymasz następujące dane, a sposób ich przesłania do twojego programu zależy w dużej mierze od Ciebie:
- Początkowa zawartość każdego pokoju (lista 0 lub więcej pozycji dla każdego pokoju);
- Zbiór dozwolonych kombinacji elementów (każda zawiera 2 elementy wejściowe i ich element wyjściowy - zwróć uwagę, że elementy wejściowe są nieuporządkowane);
- Maksymalny rozmiar zapasów (liczba całkowita, 0 <= rozmiar <= 26);
- Lista poleceń, które próbował wykonać gracz.
Poleceniami gracza mogą być:
[P]ick up <item>
- podnosi przedmiot z pokoju i umieszcza go w ekwipunku gracza (jeśli jest miejsce)[D]rop <item>
- upuszcza przedmiot z ekwipunku gracza do bieżącego pokoju[C]ombine <item1> <item2>
- łączy 2 przedmioty w ekwipunku gracza, aby stworzyć nowy przedmiot[G]o to <room>
- podróżuje do wybranego pokoju, jeśli gracz ma wymagany klucz
Na przykład format wejściowy, którego użyłem do testowania, to proste argumenty programu:
./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)
Ale jeśli jakiś inny format to ułatwia, to w porządku (np. Specjalne znaki ograniczające / wiele wierszy / różne kolejność / szeregowane do JSON / itp.)
Format wyjściowy
Twój program powinien zwrócić trochę prawdziwych danych wyjściowych, jeśli polecenia gracza spowodują, że wygra grę, a niektóre wyniki falsey w przeciwnym razie. Może to być rozpoznawalny komunikat dla standardowego wyjścia, kod powrotu programu lub cokolwiek, co zapewnia wybrany język. Wszystkie inne dane wyjściowe zostaną zignorowane.
Przypadki testowe
Poniższy skrypt bash zapewnia uprząż testową, która sprawdzi większość sytuacji. Został napisany, aby używać formatu opisanego powyżej, ale zmodyfikowanie go w celu użycia innego formatu jest tylko przypadkiem dodania konwersji w invoke
funkcji.
#!/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;
Zwycięski
Standardowy kod golfowy: wygrywa najkrótszy kod (w bajtach). Zgłoszenia muszą być zgodne z zasadami gry, co w praktyce oznacza, że muszą przejść wszystkie przypadki testowe (w razie potrzeby można dodać więcej testów).
źródło
Odpowiedzi:
JavaScript (ES6), 244
249 267 280Edytuj Zapisane 18 (!) Bajtów dzięki @Neil
Funkcja z wejściem:
Zwraca true lub false
Zobacz fragment testowy poniżej, aby zobaczyć wersję oddzieloną od nowego wiersza
Test
źródło
.map
!a>8
środku()
? Możej[--s,a]=1
zostaćj[a]=s--
? Ponadto,String.fromCharCode
jest zbyt długa, dlaczego po prostu nie do indeksu"ABCDEFGHIJ"
?C, 338 bajtów
Próbowałem zminimalizować własny program testowy. Myślę, że poszło całkiem dobrze, nawet jeśli jest to najdłuższa jak dotąd odpowiedź!
Wykorzystuje kilka sztuczek, aby zaoszczędzić miejsce:
Awaria:
Częściowo zainspirowany odpowiedzią @ edc65.
Byłem tak blisko do uzyskania
;*++*v;
ic[P][c]
do kodu dla ostatecznego zamieszania, ale niestety inne opcje okazały się krótsze :(źródło
Haskell,
354325323 bajtówDefiniuje funkcję,
!
która przyjmuje kolejnośćZwraca
True
lubFalse
. Przykładowe wywołanie:Wszystkie przypadki testowe .
Wiele bajtów wydaje się na przenoszenie stanu gry. Haskell nie może destrukcyjnie aktualizować struktur danych, takich jak pokoje i zapasy.
Praca jest wykonywana przez funkcję,
g
która przyjmuje 4 parametry: ekwipunek (Ciąg), bieżący pokój (Liczba całkowita), pokoje (Lista Assoc, z kluczem: numer pokoju i wartość: przedmioty) oraz pozostawione polecenia (Lista Ciąg) .Może następujące rzeczy mogą zaoszczędzić niektóre bajty
Pojedyncza lista Assoc dla kluczy (klucz: litera klucza, wartość: numer pokoju zNie, budowanie takiej wstępnej listy Assoc i sprawdzenie maksymalnego rozmiaru zapasów kosztuje więcej niż oszczędza transakcji z jednym parametrem mniej.-1
ekwipunkiem) zamiast pokoi / inwentarzaźródło
s
gdy zmieniają się zasoby, aby uniknąć konieczności sprawdzanialength i
(s
zamiast tego możesz sprawdzić 0)s
sprawiłaby , że byłby to piąty parametrg
i musiałby zostać przekazany. Mam 5 wywołań rekurencyjnychg
, dodatkowy parametr kosztuje co najmniej 6 bajtów.Python 3
321311 bajtów-10, dzięki Dave
Pomieszczenia (r), kombinacje (c) i ruchy (m) są listami ciągów. Maksymalna wartość zapasów (i) to liczba całkowita.
Dość prosta implementacja. Wykorzystano zestawy dla zawartości pokoju i ekwipunku, aby ułatwić aktualizację. Użyto frozensetów do wprowadzenia słownika kombinacji, tak że kolejność 2 elementów wejściowych nie ma znaczenia.
źródło
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))
(średniki -> nowe linie). Nawiasem mówiąc, wygląda na to, że,dbg=False
tam zostałeś ; możesz zaoszczędzić 10 bajtów, usuwając go!