Les jeux d'aventure texte ont une formule assez définie; il y a un monde composé d'une série de pièces / espaces, le joueur peut se déplacer dans ces pièces et il y a des objets dans les pièces. Les objets peuvent être récupérés par le joueur, déposés, utilisés pour accéder à d'autres pièces (par exemple les clés) et combinés avec d'autres objets pour en faire de nouveaux.
Défi
Votre défi est d'écrire un runtime texte aventure dans le moins d'octets (code golf). Pour garder les choses simples, tout ce que vous avez à faire est de produire une valeur true ou falsey selon qu'une série de commandes donnée gagnerait ou non un jeu donné (pas d'interactivité, pas de sortie conviviale, etc.)
Regles du jeu
- Le monde est toujours composé d'un couloir avec 10 pièces communicantes. Chaque pièce nécessite une clé pour entrer, mais peut être sortie à tout moment sans clé (c'est donc une sorte de verrou, je suppose);
- Le joueur commence dans la salle 0 et gagne s'il entre dans la salle 9 (une fois qu'il a atteint la salle 9, il peut faire ce qu'il veut, y compris aller dans une autre salle, et il aura toujours gagné);
- Chaque pièce peut contenir n'importe quel nombre d'articles;
- Il y a jusqu'à 26 éléments, appelés AZ, et aucun élément n'apparaîtra plus d'une fois dans le monde;
- Le joueur peut ramasser des objets de la salle actuelle et les placer dans son inventaire (il peut aussi déposer des objets de son inventaire dans la salle actuelle);
- La taille maximale de l'inventaire du joueur est finie et sera fournie avec les détails du niveau;
- Au début de la partie, l'inventaire du joueur est toujours vide;
- Il n'y a pas de limite au nombre maximum d'articles dans une pièce (bien que la limite implicite soit de 26, puisque c'est le nombre total d'articles);
- Les objets AJ sont des clés qui peuvent être utilisées pour entrer dans les pièces 0-9 (c'est-à-dire que le joueur peut se déplacer dans la pièce 0 s'il a l'élément A, dans la pièce 1 s'il a B, etc. notez que les clés ne sont pas requises pour quitter une pièce, et le joueur commence dans la salle 0, donc la clé "A" n'est requise que si le joueur veut revenir dans la salle 0);
- Les objets dans l'inventaire du joueur peuvent être combinés pour créer de nouveaux objets (qui seront créés dans l'inventaire du joueur) - les combinaisons autorisées seront fournies avec les détails du niveau;
- La combinaison d'articles consomme les articles d'origine (c'est-à-dire que si l'un des articles était une clé, il ne sera plus possible d'utiliser cette clé);
- Si le joueur essaie de faire quelque chose d'impossible (par exemple, ramasser un élément qui n'est pas dans la pièce actuelle / déposer un élément qu'il n'a pas / combiner des éléments qu'il n'a pas / aller dans une pièce, il n'a pas la clé pour), rien ne se passe et ils peuvent continuer;
- Le joueur ne donnera jamais un ordre absurde (par exemple, allez dans la salle 11).
Donc, un jeu simple pourrait ressembler à ceci:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | J | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 99
La pièce 0 contient l'élément "C" (qui est la clé de la pièce 2). La salle 2 contient l'article "J" (qui est la clé de la salle 9). Le joueur peut gagner la partie en ramassant C, en se déplaçant dans la salle 2, en ramassant J, puis en se déplaçant dans la salle 9.
Un jeu plus complexe pourrait être:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | X |YZ | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 10
C+X => D
Y+Z => J
Maintenant, le joueur peut gagner en ramassant C, en se déplaçant dans la salle 2, en ramassant X, en combinant C avec X pour créer D, puis en se déplaçant dans la salle 3. Ils peuvent maintenant ramasser et combiner Y et Z pour obtenir J, ce qui leur permet de allez dans la chambre 9.
Format d'entrée
Il y a pas mal d'entrées à gérer, et c'est une tâche assez ennuyeuse, donc le format d'entrée est très flexible. Vous obtiendrez les données suivantes, et la façon dont elles doivent être envoyées à votre programme dépend en grande partie de vous:
- Le contenu initial de chaque pièce (liste de 0 ou plusieurs éléments pour chaque pièce);
- Une collection de combinaisons d'éléments autorisées (chacune contient 2 éléments d'entrée et leur élément de sortie - notez que les éléments d'entrée ne sont pas ordonnés);
- La taille maximale de l'inventaire (entier, 0 <= taille <= 26);
- La liste des commandes que le joueur a tentées.
Les commandes du joueur peuvent être:
[P]ick up <item>
- ramasse un objet dans la salle et le met dans l'inventaire du joueur (s'il y a de l'espace)[D]rop <item>
- dépose un objet de l'inventaire du joueur dans la salle actuelle[C]ombine <item1> <item2>
- combine 2 objets dans l'inventaire du joueur pour produire un nouvel objet[G]o to <room>
- se rend dans la pièce choisie si le joueur a la clé requise
Par exemple, le format d'entrée que j'ai utilisé pour les tests était de simples arguments de programme:
./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)
Mais si un autre format facilite les choses, c'est bien (par exemple, des caractères de délimitation spéciaux / plusieurs lignes / un ordre différent / sérialisé en JSON / etc.)
Format de sortie
Votre programme devrait renvoyer une sortie véridique si les commandes du joueur lui font gagner le jeu, et une sortie falsey sinon. Cela peut être un message reconnaissable à stdout, un code retour de programme ou tout ce que la langue de votre choix fournit. Toutes les autres sorties seront ignorées.
Cas de test
Le script bash suivant fournit un faisceau de test qui vérifiera la plupart des situations. Il a été écrit pour utiliser le format décrit ci-dessus, mais le modifier pour utiliser un format différent n'est qu'un cas d'ajout d'une conversion dans la invoke
fonction.
#!/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;
Gagnant
Golf à code standard: le code le plus court (en octets) l'emporte. Les inscriptions doivent suivre les règles du jeu, ce qui signifie en pratique qu'elles doivent réussir tous les cas de test (d'autres tests peuvent être ajoutés si nécessaire).