Текстові пригодницькі ігри мають досить задану формулу; є світ, що складається з серії кімнат / просторів, гравець може пересуватися по цих кімнатах, а в кімнатах є деякі предмети. Гравець може підбирати предмети, класти їх, використовувати для доступу до інших приміщень (наприклад, ключів) та комбінувати з іншими предметами для створення нових предметів.
Виклик
Ваше завдання полягає в тому, щоб написати текстовий час виконання пригод у найменших байтах (код гольфу). Щоб все було просто, все, що вам потрібно зробити, - це вивести значення "truthy" або "falsey" залежно від того, виграла б дана серія команд у певній грі чи ні (відсутність інтерактивності, відсутність дружнього результату для людини тощо)
Правила гри
- Світ завжди складається з коридору з 10 підключеними кімнатами. У кожній кімнаті потрібен ключ для входу, але його можна вийти в будь-який час без ключа (тому я думаю, це якась фіксація засувки);
- Гравець починається в кімнаті 0 і виграє, якщо коли-небудь увійде до кімнати 9 (як тільки вони дойдуть до кімнати 9, вони можуть робити все, що завгодно, в тому числі перейти до іншої кімнати, і вони все одно виграють);
- Кожна кімната може містити будь-яку кількість предметів;
- Є до 26 предметів з назвою AZ, і жоден предмет не з’явиться більше одного разу у світі;
- Гравець може забрати предмети з поточної кімнати і помістити їх у свій інвентар (вони також можуть скинути предмети зі свого інвентарю в поточну кімнату);
- Максимальний розмір інвентаря гравця обмежений, і йому надаватимуться деталі рівня;
- На початку гри запас гравця завжди порожній;
- Максимальна кількість предметів у кімнаті не обмежується (хоча неявна межа буде 26, оскільки це загальна кількість предметів);
- Елементи AJ ключі , які можуть бути використані для введення номерів 0-9 (тобто гравець може перейти в кімнату 0 , якщо у них є пункт А, в кімнату 1 , якщо у них є B, і т.д. Зверніть увагу , що ключі НЕ повинні виходити з кімнати, і гравець починається в кімнаті 0, тому клавіша "A" потрібна лише в тому випадку, якщо гравець хоче повернутися в номер 0);
- Елементи в інвентарі гравця можна комбінувати для створення нових предметів (які будуть створені в інвентарі гравця) - дозволені комбінації надаватимуться деталями рівня;
- При об'єднанні елементів споживаються оригінальні елементи (тобто, якщо один із елементів був ключовим, його більше не можна буде використовувати);
- Якщо гравець намагається зробити щось неможливе (наприклад, забрати предмет, який не знаходиться в поточній кімнаті / відкинути предмет, якого у них немає / об'єднати предмети, яких у них немає / зайти до кімнати, у них немає ключа бо) нічого не відбувається, і вони можуть продовжуватися;
- Гравець ніколи не дасть дурницьких команд (наприклад, перейти до кімнати 11).
Тож проста гра може виглядати так:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | J | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 99
Кімната 0 містить пункт "С" (це ключ до кімнати 2). Кімната 2 містить пункт "J" (який є ключем до кімнати 9). Гравець може виграти гру, забравши C, перебравшись до кімнати 2, забравши J, потім перейшовши до кімнати 9.
Більш складною грою може бути:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | X |YZ | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 10
C+X => D
Y+Z => J
Тепер гравець може виграти, взявши C, перебравшись до кімнати 2, підібравши X, поєднуючи C з X, щоб створити D, а потім переїхати до кімнати 3. Тепер вони можуть забрати і комбінувати Y і Z, щоб отримати J, дозволяючи їм перейти до кімнати 9.
Формат введення
Для цього достатньо трохи вводу, і це досить нудне завдання, тому формат введення дуже гнучкий. Ви отримаєте такі дані, і те, як воно має бути надіслано вашій програмі, багато в чому залежить від вас:
- Початковий вміст кожної кімнати (список 0 або більше предметів для кожної кімнати);
- Колекція дозволених комбінацій елементів (кожен містить 2 елементи введення та їх вихідний елемент - зауважте, що елементи введення не упорядковані);
- Максимальний розмір запасів (ціле число, 0 <= розмір <= 26);
- Список команд, які намагався виконати гравець.
Командами гравця можуть бути:
[P]ick up <item>
- вибирає предмет із кімнати та вкладає його в інвентар гравця (якщо є місце)[D]rop <item>
- перекидає предмет з інвентаря гравця в поточну кімнату[C]ombine <item1> <item2>
- поєднує 2 предмети в інвентарі гравця, щоб створити новий предмет[G]o to <room>
- їде до обраної кімнати, якщо у гравця є необхідний ключ
Наприклад, формат введення, який я використовував для тестування, був простими програмними аргументами:
./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)
Але якщо якийсь інший формат це полегшує, це нормально (наприклад, спеціальні символи-роздільники / кілька рядків / різні впорядкування / серіалізовані до JSON / тощо)
Формат виводу
Ваша програма повинна повернути деякий простий вихід, якщо команди гравця змусять їх виграти гру, а деякі фальси вивести в іншому випадку. Це може бути впізнаване повідомлення для stdout, код повернення програми чи будь-яку іншу мову. Усі інші результати будуть ігноровані.
Випробування
Наступний скрипт bash містить тестовий джгут, який перевірить більшість ситуацій. Це було написано для використання описаного вище формату, але змінити його для використання іншого формату - це лише випадок додавання перетворення у invoke
функцію.
#!/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;
Перемога
Стандартний код гольфу: найкоротший код (у байтах) виграє. Записи повинні дотримуватися правил гри, що на практиці означає, що вони повинні пройти всі тестові справи (за потреби можна додати ще тести).