Quand j'étais jeune garçon, les enfants se promenaient dans les magasins d'informatique et jouaient à Hunt the Wumpus jusqu'à ce que le personnel nous expulse. C’était un jeu simple, programmable sur les ordinateurs personnels du milieu des années 70, des machines tellement rudimentaires qu’au lieu de microprocesseurs de la taille d’un poussin, certains d’entre eux avaient probablement de vrais poussins.
Évoquons cette époque révolue en reproduisant le jeu sur du matériel moderne.
Le joueur commence dans une salle au hasard sur une carte icosaédrique (il y a donc 20 salles au total, connectées les unes aux autres comme des faces d'icosaèdre, et chaque salle possède exactement trois sorties).
Le wumpus commence dans une pièce différente choisie au hasard. Le wumpus pue et son odeur peut être détectée dans l’une des trois salles adjacentes à son emplacement, bien que la direction de l’odeur soit impossible à déterminer. Le jeu rapporte seulement "tu sens un wumpus."
Le joueur porte un arc et un nombre infini de flèches, qu’il peut tirer à tout moment dans la pièce devant lui. Si le wumpus est dans cette pièce, il meurt et le joueur gagne. Si le wumpus n'était pas dans cette pièce, il est surpris et se déplace de manière aléatoire dans l'une des trois pièces connectées à son emplacement actuel.
Une salle choisie au hasard (garantie de ne pas être la salle dans laquelle le joueur commence) contient un puits sans fond. Si le joueur se trouve dans une pièce adjacente à la fosse, il ressent une brise, mais ne sait pas de quelle porte provient la brise. S'il entre dans la pièce avec la fosse, il meurt et Wumpus gagne. Le wumpus n'est pas affecté par la fosse.
Si le joueur entre dans la chambre du wumpus ou si le wumpus entre dans la chambre du joueur, le wumpus gagne.
Le joueur spécifie la direction à laquelle il fait face avec un chiffre (1 = droite, 2 = gauche, 3 = arrière), puis une action (4 = tire une flèche, 5 = marche dans la direction spécifiée).
Par souci de marquer, chaque séquence de jeu ("Vous sentez une brise," "Vous sentez un wumpus", "Votre flèche n'a rien touché", etc.) peut être considérée comme un octet. Pas besoin d'en abuser pour cacher le code du jeu dans le texte; c'est juste pour interagir avec le joueur.
Déduisez 10% de votre nombre d'octets pour la mise en œuvre de mégabats, qui commencent dans une pièce différente du joueur (bien qu'ils puissent partager une pièce avec le wumpus et / ou le pit). Si le joueur entre dans la salle avec les chauves-souris, les chauves-souris le mèneront dans une autre pièce choisie au hasard (il lui sera garanti de ne pas être la pièce contenant la fosse ou le wumpus) avant de s'envoler vers son nouvel emplacement aléatoire. Dans les trois salles adjacentes aux chauves-souris, on peut les entendre grincer, mais le joueur ne reçoit aucune information sur la pièce d'où provient le son.
Déduisez 35% de votre nombre d'octets pour implémenter une interface graphique qui montre la carte icosaédrique et une sorte d'indication des informations dont dispose le joueur jusqu'à présent sur l'emplacement de la fosse, du wumpus et des chauves-souris (le cas échéant), par rapport à le joueur. Évidemment, si le wumpus se déplace ou si le joueur est déplacé par les chauves-souris, la carte doit être réinitialisée en conséquence.
Le plus petit nombre d'octets, ajusté, gagne.
Le code source BASIC pour une version du jeu (non nécessairement conforme aux règles ci-dessus et, en tout état de cause, totalement non-golfée) peut être trouvé sur ce site et probablement sur d'autres.
la source
Réponses:
GolfScript, 163
Le score est obtenu en prenant le nombre d'octets (290), en ajoutant le nombre de chaînes utilisées pour l'interaction avec l'utilisateur (6) et en soustrayant la longueur combinée de ces chaînes (133). Les sauts de ligne font partie des chaînes et contribuent au nombre d'octets.
Les jalons
Ported profanish réponse de Bash à GolfScript. Score: 269
A suivi les suggestions de Peter Taylor dans les commentaires. Score: 250
Peter Taylor a restructuré tout mon code et m'a aidé à compresser la table de consultation. Score: 202
Remplacement de la table de consultation des salles adjacentes par une approche mathématique. Score: 182
L'entrée, la sortie et la fonction refactorisées supportant l'approche mathématique. Score: 163
Un grand merci à Peter Taylor pour toute son aide.
Comment ça marche
Les 20 salles sont représentées comme les sommets d'un dodécaèdre, et portent les numéros 0 à 19 de la manière suivante:
Pour trouver les pièces adjacentes à la pièce N et les commander dans le sens des aiguilles d'une montre, nous devons considérer quatre cas:
Si N ≡ 0 mod 4 (sommets bleus), la salle adjacente est 19 - N , N + 2 mod 20 et N - 2 mod 20 .
Si N ≡ 1 mod 4 (sommets verts), la salle adjacente est 19 - N , N - 4 mod 20 et N + 4 mod 20 .
Si N ≡ 2 mod 4 (sommets jaunes), la salle adjacente est 19 - N , N - 2 mod 20 et N + 2 mod 20 .
Si N ≡ 3 mod 4 (sommets rouges), la pièce adjacente est 19 - N , N + 4 mod 20 et N - 4 mod 20 .
la source
Q
avec19rand 97+
; 2@
avec97%3*&>
..., un autre 1 par inlineQ
que{19rand 97+}2*:,\:H
, quelques en remplaçant|
avec*
, ce qui est souvent la meilleure façon de faire uneif
.B
ne sert à rien, et je pense que quelques autres variables pourraient être éliminées en utilisant la pile.256base 20base
(et probablement aussi éliminer quelques +/- 97). Le seul inconvénient est que cela nécessitera des caractères non imprimables.You were killed by the wumpus
sans mention de la flèche manquante. C'est pourquoi j'ai ajouté dans la version non-jolie.2*2+
=>)2*
REV0 C ++ (Visual Studio sous Windows) 405Vous trouverez ci-dessous un scénario de jeu montrant que si vous jouez correctement, vous pouvez toujours gagner (à condition que vous ne commenciez pas juste à côté d'un obstacle). Le joueur ressent une brise, fait demi-tour et fait une boucle complète dans le sens antihoraire. Comme il lui faut exactement 5 coups pour sentir à nouveau une brise, il connaît le trou à sa droite et s’éloigne le plus possible. De même, quand il sent le wumpus, ne sachant pas si c'est à droite ou à gauche, il se retourne et fait une boucle dans le sens des aiguilles d'une montre. Cela lui prend 5 coups pour sentir à nouveau le wumpus, alors il sait que c'est à gauche et tire avec certitude.
S'il avait bouclé dans l'autre sens, il aurait retrouvé le wumpus plus tôt et aurait su que c'était dans la même direction qu'il se retournait.
REV1 C (GCC sur Cygwin), bonus de 431 à 35% = 280,15Nouvelles lignes ajoutées pour plus de clarté. Les modifications par rapport à la révision 0 sont les suivantes:
Un grand merci à @Dennis pour avoir recommandé le compilateur GCC sur l'émulateur Cygwin Linux pour Windows. Ce compilateur ne requiert pas le
include
s dans le programme rev 0, et il autorise leint
type par défaut pour les variables etmain.
c’est un conseil de golf qui change la vie!De plus, tourner sous Linux signifie que
\f
le curseur descendra sans faire de retour chariot (contrairement à Windows où il ne produit qu'un symbole imprimable.) Cela a permis de raccourcir considérablement l'instruction printf imprimant le tableau.Plusieurs conseils supplémentaires de Dennis dans les commentaires, et un des miens: changement de condition lors de la vérification si la flèche touche le wumpus:
if(q==w)
>if(q-w)
(..else .. est inversé)Ajout d'un affichage graphique montrant les informations que le joueur sait sur l'endroit où un wumpus est senti / une brise semble réclamer le bonus de 35%. (J'ai supprimé l'ancienne version de débogage de celle-ci, qui indiquait la position exacte du wumpus et du trou. Elle peut être vue dans l'historique d'édition.)
REV2 C (GCC sur Cygwin), bonus de 389 à 35% = 252,85
Merci encore à Dennis pour refactoriser mon code:
Constante de caractère
m[]
remplacée par des littéraux (je ne savais pas que vous pouviez indexer un littéral.)Amorçage de nombres aléatoires avec une variable de pile (dépendant du système, certains systèmes randomisent l'allocation de mémoire comme mesure de sécurité)
Macro à
puts
remplacé par une macro avecprintf
un code supplémentaire à exécuter lorsque le message affiché est placé à l'intérieur d'printf
arguments (avantage de la face que printf n'imprime pas les derniers arguments s'il n'y a pas suffisamment de spécificateurs de format dans la chaîne de format.)if
remplacé par||
Calcul de la nouvelle position du joueur / wumpus placé dans la nouvelle macro.
Messages gagnants / perdus placés en dehors de la
while
boucle.if
remplacé par l'opérateur conditionnel.Utilisation de l'opérateur conditionnel en ligne pour la flèche de tir. Si le joueur manque, cela nécessite à la fois d’imprimer un message et d’ajuster la position de Wumpus. Dennis a proposé plusieurs façons de combiner
printf
et de calculer la position de wumpus en une seule expression, mais je suis parti avec l'une des miennes.printf
renvoie le nombre de caractères imprimés, qui , pourYour arrow didn't hit anything\n
se 31 (11111 binaire). Donc,31&Q(w)==Q(w)
.Mon autre contribution à cette vérification a été l’élimination de certains crochets inutiles.
Sortie
Ici, le joueur a déjà trouvé où se trouve le Wumpus, mais choisit de faire une exploration approfondie pour savoir exactement où se trouve la fosse. Contrairement à mon ancienne version de débogage qui indiquait où se trouvaient le wumpus et la fosse tout au long du jeu, elle ne montre que les pièces où le joueur s’est rendu et a senti une brise (1) sentait le wumpus (2) ou les deux (3). (Si le joueur tire une flèche et manque, la variable
a
contenant les informations de position de wumpus est réinitialisée.)REPRÉSENTATION ICOSAHEDRON
Remarque: cette section est basée sur la rév. 1
Mon film vedette! Il n'y a pas de graphique dans mon code. Pour expliquer son fonctionnement, voir la carte du monde ci-dessous. Tout point de l'icosaèdre peut être représenté par une latitude comprise entre 0 et 3 et une longitude comprise entre 0 et 4 (ou par un seul chiffre
long*4+lat
,.) le centre des faces avec une latitude zéro.Le joueur peut être orienté sur 3 axes possibles, représentés par les symboles suivants: nord-sud
-
nord-sud-sud-ouest\
nord-ouest-sud-est/
. Dans n'importe quelle pièce, il dispose exactement d'une sortie sur chacun de ces axes. Sur l’affichage indiqué, le lecteur effectue une boucle complète dans le sens des aiguilles d’une montre. Il est généralement facile d'identifier le joueur qui marque d'où il vient et donc où il est autorisé à aller.Le quatrième cas est un peu difficile pour l'œil non initié. Lorsque vous voyez une inclinaison dans l'une de ces rangées polaires, le joueur vient de la cellule polaire la plus proche de l'extrémité extérieure de l'inclinaison et fait généralement face à l'équateur. Ainsi, le joueur fait face au sud-est et ses options sont: 15 (SUD, la cellule à droite) 25 (nord-est, la cellule ci-dessus) ou 35 (nord-ouest, la cellule ci-dessous.)
Donc, fondamentalement, je mappe l'icosaèdre sur une grille 5x4, avec les cellules numérotées de 19 à 0 dans l'ordre dans lequel elles sont imprimées. Le déplacement est effectué en ajoutant ou en soustrayant de la position actuelle, en fonction de la latitude et de la direction du joueur, conformément au tableau ci-dessous.
Si le joueur quitte le bord inférieur (ouest) du plateau, il revient sur le côté supérieur (est) et inversement, sa position est donc prise modulo 20. Généralement, les mouvements sont codés dans m [] en ajoutant ascii 80 (
P
) à la valeur brute donnant les caractères montrés ci-dessous, mais en principe, tout multiple de 20 peut être ajouté sans affecter le fonctionnement.L'entrée du joueur (divisée par 10 pour supprimer le deuxième chiffre) est ajoutée à sa direction actuelle et prise en modulo 3 pour obtenir sa nouvelle direction. Cela fonctionne bien dans la majorité des cas. Cependant, il y a un problème lorsqu'il se trouve dans une pièce polaire et se dirige vers le pôle. En pliant la carte ci-dessous, il est clair que s’il quitte la pièce face au "nord-est", il entrera dans la nouvelle place faisant face au "sud-est"; une correction doit donc être effectuée. Cela se fait dans la ligne
e=(d+i/10)*m[p%4]%3;
par la multiplication parm[p%4]
. Les quatre premières valeurs de m [] sont sélectionnées de telle sorte que, en plus de leur fonction ci-dessus, elles possèdent également la caractéristiquem[1]%3==m[2]%3==1
etm[0]%3==m[3]%3==2
. Cela laisse la direction seule pour les salles équatoriales et applique la correction nécessaire pour les salles polaires.Le moment logique pour faire la correction serait après le déménagement. Cependant, pour sauvegarder les personnages, cela est fait avant le déplacement. Par conséquent, certaines valeurs dans m [] doivent être transposées. Ainsi, les 2 derniers caractères sont
LT
au lieu deTL
par la table ci-dessus par exemple.CODE UNGOLFED
c'est le code rev 1, qui est moins obscurci que le rev 2.
Cela fonctionnera sous GCC / Linux. J'ai inclus dans les commentaires le code supplémentaire nécessaire pour le faire fonctionner sous Visual studio / Windows. C'est une grande différence!
QUESTIONS ET CURIOISITES
J'ai profité du point mentionné par @professorfish, si le wumpus et la fosse commencent à des endroits aléatoires, il n’est pas nécessaire que le joueur démarre dans un endroit aléatoire. Le joueur commence toujours dans la salle 19 face au nord.
Je comprends que, le wumpus n'étant "pas affecté par la fosse", il peut commencer ou entrer dans la pièce où se trouve la fosse. En général, cela simplifie les choses sauf pour un point. Je n'ai pas de variable spécifique pour indiquer que le jeu est terminé; c'est fini quand le joueur coïncide avec le wumpus ou la fosse. Ainsi, lorsque le joueur gagne, j'affiche le message gagnant mais déplace le stand au joueur pour qu'il sorte de la boucle! Je ne peux pas mettre le joueur dans la fosse car le wumpus est peut-être là et je voudrais recevoir un message sur le wumpus que je ne veux pas.
Le rev0program fonctionnait parfaitement dans Visual Studio, mais l’EDI disait "pile corrompue autour de la variable i" à la sortie. En effet , scanf tente de mettre
int
enchar.
Dennis ont signalé un comportement incorrect sur sa machine Linux à cause de cela. Quoi qu’il en soit, il est corrigé par l’utilisation du type correct dans rev 1.La ligne d'affichage du tableau dans rev 0 est maladroite et semble légèrement différente sur d'autres plates-formes. Au
printf(" %c%c%c")
milieu,% c est le caractère imprimable affiché. Le dernier% c est ASCII 0 ou ASCII 10 (\ n, nouvelle ligne avec retour chariot dans Windows.) Il semble qu’aucun caractère de Windows fonctionnant dans la console ne passe sur une ligne sans donner de retour chariot. Si c'était le cas, je n'aurais pas besoin du premier c% (onglet ASCII 0 ou ASCII 9 avant le caractère de latitude 1. Les onglets sont notoirement non définis dans leur comportement.) .) La rév. 1 a une révision de cette ligne qui utilise un caractère de saut de page et ne nécessite par conséquent aucun caractère de format au début de printf. Cela le rend plus court, mais le \ f ne fonctionne pas sous Windows.la source
scanf_s
parscanf
et l'inclurestdio.h
si je compile en tant qu'évaluateur C ++ plutôt que C), mais cela ne fonctionne pas très bien pour moi. Par exemple, si je vais à gauche, puis à droite au début (15 35
), je suis dans une pièce différente de celle où j'ai commencé.i
est en effet le problème. La page de manuel indique: " d Correspond à un entier décimal éventuellement signé; le pointeur suivant doit être un pointeur sur int ." Changer le type le fait fonctionner correctement.NULL
par0
etscanf_s
avecscanf
, vous n'avez pas besoinint
avantmain
et vous pouvez vous déplaceri
etd
sortir de main (ellesint
sont initialisées par défaut0
). En outre, vous pouvez définirp=19,h=rand()%p,w=rand()%p
, remplacerm[]
par*m
et il devrait être possible de définir une macro pour toutes les instances deif(...==...)puts(...);
.GolfScript, 269 caractères
Notez que 163 a été soustrait du nombre de caractères pour les chaînes codées en dur. Si vous voulez que la sortie de débogage indique les numéros de salle, ajoutez la ligne suivante juste après la première occurrence de
^
:Un exemple de session (avec une sortie de débogage supplémentaire):
la source
{puts}:|;
, 5 caractères en remplaçantR
etW
avec-
et>
(permet d'éliminer les espaces environnants) et 9 caractères en sautant'> 'print
(ne semble pas être requis par la question).JavaScript (ECMAScript 6) -
21971759 -45% = 967.45 CaractèresPresque fini de jouer au golf cette ...
Inclut une interface graphique avec une carte icosaededral et des méga-chauves-souris pour tous les bonus.
X
(le Pit);B
(le méga-bat);W
(le Wumpus); etP
(vous).W
etP
ne peuvent être cliqués que dans les salles adjacentes à votre position actuelle.Code:
la source
Bash, 365 (première version de travail 726!)
ACCÉDER AU GOLFSCRIPT?
@ Dennis a essentiellement fait tout le golf pour moi. Merci!
Le programme suppose une entrée valide. Une entrée valide correspond à la direction que vous choisissez (1 à droite, 2 à gauche, 3 à l'arrière) suivie de votre action (4 à tirer, 5 à marcher).
Quelques explications
Je fais normalement de grosses explications verbeuses, mais c'est probablement un peu trop compliqué pour que je sois dérangé.
Chaque sommet du graphe du dodécaèdre est codé sous forme de lettre (a = 1, b = 2, ... t = 20).
La position de départ du joueur est toujours 20 (et ils se tiennent dos à 18), puisque cela n'a pas d'importance en soi, seules les positions relatives du joueur, des stands et des wumpus importent.
La variable
$p
stocke l'emplacement du joueur.$r
stocke l'emplacement précédent du joueur.$w
est le wumpus et$h
(H pour trou) est la fosse.Code
Historique de la version
grep -oE
une variable. Sauvegardé 5 caractères.[a-z]{3}
une variable. Sauvegardé 3 caractères.echo
une variable. Sauvegardé 5 caractères.$m
.grep
et en étant un peu plus sensible.C
comme une fonction de recherche d'expression rationnelle à utiliser dans les instructions if, etE
comme une fonction affichant "Vous avez tué le wumpus" et sortant.d
et en supprimant les crochets inutiles.Échantillon échantillon
"In:" est entré, "Out: est sorti".
Le joueur erre un peu, sent le wumpus et tire. Ils manquent, et le wumpus entre dans leur chambre et les mange.
la source
exit
est seulement un octet plus long queg=1
et il élimine la nécessité de tester non-zérog
et certaineselif
déclarations. 2. Vous pouvez utiliser((i==35))
au lieu de[ $i = 35 ]
et...&&...
au lieu deif ... then ... fi
. 3.q(){ L=({a..s});$j ${L[RANDOM%19]};}
et lesn=`$k $w$m<<<$d`;w=${n:RANDOM%2+1:1}
deux économiser quelques octets.while :;do
...done
parfor((;;);{
...}
pour une économie de 3 caractèresd(){ x=npoemfgnshtoksblbtckpdpljqniorelgfhkbqraicadjaghimsmjtqecrdf;s=${x:3*30#$1-30:3};}
vous permettra de remplacer les définitions des
etn
avecd $p
etd $w
. Si vous définissez en outreu=${s#*$r}$s
(et d' ajuster les définitions del
et enf
conséquence), vous aurez pas besoin$k
et$m
plus. Enregistre 83 octets, je pense. En outre, l'espaceq ()
n'est pas requis.c(){ [[ $1 =~ $2 ]];}
et en remplaçant, par exemple, l'avant-dernière ligne parc $r $b||{ $j You missed;d $w;w=${s:RANDOM%2+1:1};}
.b=$p
avecd $p;u=u${s#*$r}$s
, les lignes aprèsread i
pary=${u:i/10:1};C $i 5&&{ p=$y;r=$b;}||{ d $w;C $y $w&&$j You killed the wumpus&&exit;$j You missed;w=${s:RANDOM%2:1};}
et en vous en débarrassantE()
.GolfScript (
206198)Enfin rattrapé la version de la table de recherche de Dennis, à laquelle il emprunte un peu. La chose intéressante à propos de cette version est qu’elle n’a pas de table de recherche pour la disposition de la salle.
Les 60 symétries de rotation d'un icosaèdre sont isomorphes du groupe alternant sur 5 lettres, A_5. Après avoir essayé toutes sortes d'approches pour représenter le groupe de manière compacte, je suis revenu à la plus simple: chaque élément est une permutation de parité paire. Le groupe peut être généré à partir de deux générateurs de plus d'une façon: l'approche que je prends utilise les générateurs
3
et3 1
. Ceux - ci nous permettent de générer1 = 3 3 1
,2 = 3 3 1 3 1
et3 = 3
.Observez que la direction
3
correspond à un élément d'ordre 2, car après avoir franchi la porte derrière vous, cette porte est à nouveau derrière vous. La direction1
correspond à un élément d'ordre 5, en contournant un sommet de l'icosaèdre. (Élément similaire2
). Et la combinaison3 1
est d'ordre 3, car elle fait le tour des pièces adjacentes à celle qui commence derrière vous.Nous cherchons donc une permutation de l’ordre 2 pour représenter la direction
3
et une permutation de l’ordre 5 pour représenter la direction1
telle qu’elle3 1
soit de l’ordre 3.Il y a 15 permutations d'ordre 2 dans A_5, et pour chacune il y a 8 permutations candidates pour
1
(et donc pour3 1
). Il y a un intérêt évident[4 3 2 1 0]
pour3
: inverser un tableau, c'est juste-1%
.3 1
J'ai choisi parmi les permutations possibles de mon compagnon[0 1 3 4 2]
, qui admet une implémentation assez courte comme[~@]
.Ungolfed
la source
10/@3%=
tente d'accéder au quatrième élément d'un tableau de longueur 3 si l'entrée est35
.9/3%@3%=
.9/
au lieu de10/
fonctionne toujours, alors merci.Wumpus , 384 - 129 (chaînes) = 255 octets
Essayez-le en ligne!(Bien sûr, TIO n’a pas beaucoup de sens, parce que vous ne pouvez pas utiliser le programme de manière interactive là-bas, et une fois que le programme est à court d’instructions sur STDIN, il lira
0 0
, ce qui équivaut à3 4
, de sorte que vous finirez par tirant des flèches jusqu'à ce que le Wumpus se déplace là-bas ou vous tue.)Lorsque vous exécutez cette opération localement, assurez-vous que le saut de ligne après le deuxième numéro de chaque entrée est purgé (car Wumpus en a besoin pour déterminer si le nombre est dépassé). Dans Powershell, je dois en quelque sorte entrer un caractère supplémentaire après le saut de ligne pour que cela fonctionne (peu importe le personnage, mais je viens d'utiliser un double saut de ligne pour les tests).
Il y a beaucoup de place pour jouer au golf plus loin, mais essayer de nouvelles configurations prend du temps. Le score final dépend aussi beaucoup des chaînes que j’utilise, car dans un langage 2D, une chaîne de N octets a tendance à vous coûter plus cher que N octets de code source, car elle impose des contraintes importantes à la structure du code et besoin de le scinder en plusieurs sections (ce qui entraîne des guillemets doubles). À la fin, si je réduisais chaque chaîne à une seule lettre (et les -129 à -12), je économiserais probablement une tonne d'octets.
Explication
Tout d’abord une clause de non-responsabilité: malgré le nom de la langue, elle n’a pas été conçue pour rendre particulièrement simple l’ application de Hunt the Wumpus . Au lieu de cela, j'ai d'abord conçu le langage autour du thème des triangles, puis une structure de données icosaédrique et décidé de l'appeler Wumpus pour cette raison.
Donc oui, bien que Wumpus soit principalement basé sur des piles, il possède également 20 registres disposés autour des faces d’un icosaèdre. Cela signifie que nous obtenons une structure de données pour représenter la carte gratuitement. La seule chose que nous ne pouvons pas facilement faire est de trouver des visages spécifiques sur l'icosahédron. Par conséquent, pour les rechercher, nous devons "lancer le d20" jusqu'à obtenir le visage que nous recherchons. (Il est possible de le faire de manière déterministe, mais cela prendrait beaucoup plus d'octets.) La recherche de visages comme celle-ci se termine presque sûrement (c'est-à-dire avec la probabilité 1), de sorte que la recherche exécutée pour toujours n'est pas une préoccupation dans la pratique).
Le code ci-dessus est une version golfée de cette première implémentation avec une mise en page plus saine:
Étant donné que le jeu consiste principalement à compresser la présentation, je vais simplement expliquer cette version pour l'instant (jusqu'à ce que j'ajoute des astuces qui vont au-delà de la restructuration du code).
Commençons par le code d'installation:
Initialement, toutes les faces sont définies sur 0 . Nous allons coder le wumpus en définissant le bit 1 de la face correspondante, et la fosse en définissant le 2 bits. De cette façon, ils peuvent tous deux être dans la même pièce. La position du joueur ne sera pas du tout enregistrée sur l'icosaèdre, mais restera toujours active (un seul des 20 registres est actif à la fois).
Nous devons maintenant trouver un visage vide au hasard dans lequel placer le joueur.
Cette section suivante vérifie l'environnement du joueur et affiche les avertissements appropriés:
C'est une boucle que nous parcourons 3 fois. À chaque fois, nous regardons le voisin de droite, imprimons la ou les chaînes appropriées s'il y a un danger, puis faisons pivoter l'icosaèdre de 120 °.
La section suivante lit deux chiffres du joueur puis déplace le joueur ou tire une flèche. Le premier est trivial, le dernier moins. Le problème principal pour tirer la flèche est le cas où il manque. Dans ce cas, nous devons a) rechercher le wumpus pour le déplacer, puis b) retourner dans la chambre du joueur et indiquer la bonne orientation de l'icosaèdre (pour que "retour" reste "en arrière"). C'est la partie la plus chère de l'ensemble du programme.
Le point d’entrée de cette section est le
I
à gauche.Ouf, c'était la partie difficile. Il ne reste plus qu’à vérifier si le joueur meurt et à recommencer par la boucle principale:
La structure de cette section est essentiellement identique à celle utilisée lors de la vérification de l'environnement du joueur: nous vérifions le bit du visage actuel (la chambre du joueur) et, le cas échéant, imprimons
The wumpus ate you.
et mettons fin au programme. Sinon, on vérifie le 2-bit et c'est réglé nous imprimonsYou fell into the pit.
et terminons le programme. Sinon, nous atteignons le2.
qui revient au début de la boucle principale (aux coordonnées(0, 2)
).la source
awk - grand
Cela n’a pas été aussi bref que je l’espérais, mais j’ai adopté une approche légèrement différente de la gestion du graphique; j’ai donc publié la version non-golfée.
J'ai profité du fait qu'un icosaèdre (polyèdre à 20 côtés) avec une orientation préservant les rotations est isomorphe au groupe alternant du degré 5 (permutations à 5 éléments ayant un nombre pair de cycles de longueurs égales). Je choisis ensuite deux permutations avec la longueur de cycle 5 en "gauche" et "à droite", et je choisis une permutation avec la longueur de cycle 2 en "arrière". En utilisant ceux-ci, je construis le graphique d'une pièce en marchant sur le chemin hamiltonien (2xRRRLLLRLRL, en utilisant 3xRB dans chaque pièce pour capturer les 3 directions possibles).
la source