Trouvez le résultat d'un jeu de guerre
Quand j'étais à l'école primaire, il y avait un jeu "Rock-Paper-Scissors" que nous jouions pendant les assemblées, en attendant notre professeur, à la récréation, etc. Nous l'appelions "Guerre". Après quelques recherches cependant, il s'avère que c'est une variante beaucoup plus simple du "Shotgun Game" (selon WikiHow) . Je vais l'appeler "Guerre" car les règles sont légèrement différentes:
2 personnes sont assises l'une en face de l'autre. Le but du jeu est de "tuer" l'autre joueur. Chaque tour, vous pouvez jouer l'un des 3 coups:
Recharger : Vous avez un pistolet qui détient un seul coup. Il doit être rechargé avant de pouvoir être tiré à chaque fois. Le rechargement lorsque vous avez déjà des munitions est légal, mais ne fait rien. Un rechargement était symbolisé en tapant sur vos tempes avec les deux mains. Chaque joueur commence avec 0 munitions.
Garde : Le seul mouvement sûr. Si vous êtes abattu alors que vous gardez, vous ne mourrez pas. La garde était symbolisée en croisant vos bras sur votre poitrine.
Feu : tirez avec votre arme. Pour réussir le tir, vous devez avoir rechargé depuis le dernier tir. Si votre adversaire recharge, vous gagnez. S'ils tirent également et que vous avez tous les deux des munitions, c'est un match nul. S'ils gardent, vous avez gaspillé les munitions. Bien que tirer sans munitions soit légal, cela ne fait rien et vous rend vulnérable comme le rechargement. Le tir était symbolisé en pointant l'autre joueur.
Cela se jouait de la même manière que le RPS, en ce que chaque joueur rejette simultanément son choix (nous nous tapotions les jambes deux fois entre les tours pour garder le rythme les uns avec les autres, mais ce n'est pas important pour le défi).
Le défi:
Votre tâche est de trouver le résultat d'un jeu de guerre. Il peut s'agir d'une fonction ou d'un programme complet.
Contribution
L'option choisie par chaque joueur à chaque tour sera représentée par un caractère / chaîne:
r : recharger
g : garde
f : feu
L'entrée sera une liste de paires, une chaîne délimitée / non délimitée ou toute autre chose le long de ces lignes.
Un exemple d'entrée en Python pourrait être [("r", "g"), ("f", "r")]
, ce qui signifie qu'au premier tour, le premier joueur rechargé et le deuxième joueur gardé. Au deuxième tour, le premier joueur tire, tandis que le deuxième joueur recharge. Le joueur un gagne ce match. Pourrait éventuellement l'entrée même être représentée comme "r g f r"
, "rgfr"
, "rg fr"
"rg-fr"
...
Vous pouvez supposer ce qui suit:
La saisie correspondra au format choisi et ne contiendra que des caractères valides.
Quelqu'un mourra dans les 100 tours.
Vous ne pouvez cependant pas supposer que les virages se terminent lorsque quelqu'un décède.
Production
Une valeur indiquant qui a gagné (ou qui a gagné en premier *
). Vous pouvez choisir les éléments à afficher pour chaque scénario, mais vous devez tenir compte des éléments suivants:
Le joueur 1 gagne
Le joueur 2 gagne
Ils s'entretuent (dessine)
Chaque résultat doit avoir une valeur de district et doit toujours être le même pour chaque scénario.
À titre d'exemple: vous pouvez générer des résultats 1
lorsque le joueur 1 gagne, 2
lorsque le joueur 2 gagne et 0
en cas d'égalité. Vous devez ensuite toujours sortir 1
lorsque le joueur 1 gagne, 2
lorsque le joueur 2 gagne et 0
en cas d'égalité.
Il peut être retourné ou imprimé sur la sortie standard. La fin des espaces blancs est très bien.
Juste pour que ce soit clair, le seul scénario qui mène à un match nul est si les deux joueurs tirent, et les deux ont des munitions.
*
Étant donné que dans ce défi, les tours peuvent continuer après la mort de quelqu'un, il est possible que plus d'un joueur gagne finalement. Vous devez trouver qui a gagné en premier selon l'entrée.
Cas de test (en supposant 1
que P1 gagne, 2
lorsque P2 gagne et 0
pour un match nul):
"rg fr" => 1 (P1 shot P2 while they were reloading)
"rg ff" => 1 (They both shot, but only P1 had ammo)
"rr ff" => 0 (Both had ammo and shot each other)
"rr ff rr fg" => 0 (Both had ammo and shot each other. Everything after the first win is ignored)
"rr fg rf" => 2 (P2 shot P1 while they were reloading)
"rf gg rr fg rr fr" => 1
(P2 tried to shoot but didn't have any ammo, then they both guarded, then they both reloaded, then P2 blocked a shot, then they both reloaded again [but P2 still only has 1 ammo!], then P1 shoots P2 while they're reloading.
"rr gf fr rf gg rg ff" => 1
^ Player 1 wins here. The rest to the right has no effect on the output
C'est du golf de code, donc le plus petit nombre d'octets gagne!
Notez que, comme le montrent les cas de test, vous devez gérer les mouvements "stupides". Il est parfaitement valable pour un joueur d'essayer de tirer lorsqu'il n'a pas de munitions, ou de recharger 2 tours de suite (et d'accumuler une seule munition).
{"rff","rgf"}
?Réponses:
Rétine , 36 octets
Le format d'entrée doit être des paires séparées par des sauts de ligne, par exemple
La sortie est le
!_
joueur 1 gagne,_!
si le joueur 2 gagne et!!
s'il y a match nul.Essayez-le en ligne! (Une suite de tests qui utilise la séparation d'espace pour plus de commodité.)
J'ai dû complètement ignorer ce défi. Je suis sûr que j'aurais essayé cela à Retina plus tôt sinon. :)
Explication
Nous commençons par marquer les plans "valides" en transformant le premier
f
après chacunr
en!
. Nous le faisons en faisant correspondre chacun d'f
entre eux qui peut trouver unr
sur le même joueur sans en croiser un autref
. Limiter la recherche àr
s sur le même joueur est facile en faisant toujours trois caractères à la fois.Maintenant, nous rejetons tous les tours dans lesquels quelqu'un s'est gardé, car le tour de fin ne peut pas être l'un d'entre eux.
Maintenant, nous ne gardons que le premier tour qui contient un
!
. Si un tir valide se produit (et nous savons que personne ne garde), le jeu se termine.Enfin, nous devons consolider la chaîne pour donner des sorties cohérentes, et nous le faisons simplement en transformant les non-
!
caractères (soitr
ouf
) en_
.la source
Python, 139 octets
Prend l'entrée sur stdin sous la forme d'une liste de chaînes de 2 caractères (par exemple. ['Rf', 'rr', 'rg', 'ff']). Génère 1 si le joueur 1 gagne, -1 si le joueur 2 gagne et 0 pour un match nul.
Explication: Vérifiez d' abord si quelqu'un a tiré une balle, si c'est le cas, le jeu se termine. Ensuite, nous déterminons si les joueurs ont rechargé leurs armes ou gaspillé leurs munitions.
Ceci est mon premier article sur codegolf :)
la source
JavaScript (ES6),
10810793918985 octetsEnregistré 4 octets avec l'aide de Titus
Prend l'entrée comme un tableau de chaînes de 2 caractères décrivant les mouvements joués par chaque joueur.
Retour:
1
si le joueur 1 gagne2
si le joueur 2 gagne3
pour un match nulComment ça fonctionne
Nous maintenons un masque de bits
b
décrivant qui a une balle chargée:Nous utilisons la séquence De Bruijn
'ffrfgrrggf'
pour identifier les 9 combinaisons possibles de mouvements. Nous utilisons des bitmasks OR et AND pour mettre à jour enb
fonction de la combinaison de mouvements. Nous utilisons un troisième ensemble de bitmasks qui sont ETb
pour déterminer le gagnantw
. (Les trois seules combinaisons gagnantes étantff
,fr
etrf
.)Il convient de noter que les masques OR et AND peuvent être stockés avec le même motif, décalés de deux positions.
Cas de test
Afficher l'extrait de code
la source
0
(personne n'a été abattu) ou3
(les joueurs s'entretuent) en cas d'égalité. Je ne sais pas si cela est autorisé. Sinon, je peux revenir à law%3
place.&
masque peut être 0 pourfr,rf,ff
.'312'['0210231'[m='ffrfgrrggf'.search(c)]|'233331'[m-3]&b]
ou'123'['2100231'[m='frffgrrggf'.search(c)]|'233331'[m-3]&b]
enregistrez un octet; mais fonctionnent-ils?["rr","fg","fr","rf"]
&
a une priorité plus élevée que|
, donc changer l'ordre ne devrait rien y changer (à part sauvegarder l'octet). Mais la mission manquait dans mon code. Essayez...'123'[b='2100231'...
.Perl 6 ,
7162 octetsSolution basée sur Regex.
Prend l'entrée sous forme de chaîne dans le formulaire
"rg fr"
.Les trois sorties possibles sont les valeurs ENUM
More
(joueur 1 won),Less
(joueur 2 won),Same
(tirage au sort) - qui se transforment en ces mots lors de l' impression, ou dans1
,-1
,0
quand sous la contrainte aux chiffres.Essayez-le en ligne!
Comment ça fonctionne
Effectue deux correspondances d'expression régulière sur l'entrée. Après interpolation, les deux expressions régulières sont:
r[..[r|g]]*.[r|f]f
- Correspond au premier tir réussi du joueur 2.r[..[r|g]]*..f[r|f]
- Correspond au premier tir réussi du joueur 1.Dans chaque cas, il renvoie la position finale de la correspondance (
.to
), ou l'infini s'il n'y a pas de correspondance.Applique l'
<=>
opérateur aux deux positions finales de correspondance. Elle retourne une valeur dans laOrder
enum (More
,Less
, ouSame
), selon que le premier argument est supérieur, inférieur ou égal au second.la source
some number
? Et utilisez-vous réellement des caractères comme celui-ci dans le code Perl commun, ou est-ce juste pour le golf?[Menu] i n f
(cela s'appelle une séquence de composition ). Cependant, tous les symboles Perl 6 ont des versions ASCII - par exempleInf
et∞
sont des synonymes - il n'est donc pas nécessaire d'utiliser des symboles Unicode dans le code Perl 6. Je l'aime juste ... :)Haskell ,
101 9187 octetsEssayez-le en ligne! La fonction infixe
#
prend deux chaînes représentant les actions de chacun des deux joueurs et retourne(0,1)
si le joueur 1 gagne,(1,0)
pour le joueur 2 et(0,0)
pour un match nul.Exemple d'utilisation:
Explication:
La fonction infixe
!
traduit une séquence d'actions'r'
(rechargement),'f'
(feu) et'g'
(garde) en une séquence d'actions observables0
(feu réel),1
(aucune action) et2
(garde), où une action incendie n'est comptée que comme une action incendie réelle si une balle est chargée, et comme aucune action sinon. Pour y parvenir, le premier argumentn
est de savoir0
si une balle est chargée et1
si le pistolet n'est pas chargé. De cette façon, chacun'f'
peut simplement être remplacé par le courantn
. (n=0
-> chargé -> feu réel ->0
,n=1
-> déchargé -> aucune action ->1
)Les neuf possibilités qui en résultent sont alors
(0,0)
: Les deux joueurs tirent et meurent, la partie se termine.(0,1)
ou(1,0)
: Un joueur tire sur l'autre, la partie se termine.(0,2)
ou(2,0)
: Un joueur tire mais les autres gardes, le jeu continue.(1,1)
,(1,2)
,(2,1)
Ou(2,2)
: Aucun joueur tire, jeu continue.Par conception, la somme des options de fin de jeu est inférieure à 2 et la somme de chaque possibilité de poursuite de jeu est supérieure ou égale à 2. Le résultat du jeu est alors le premier tuple avec une somme inférieure à 2.
la source
Lot, 249 octets
L'entrée se présente sous la forme de paires de caractères pour chaque tour et les sorties par niveau d'erreur (0 = match nul, 1 = joueur 1, 2 = joueur 2).
x
ety
gardez une trace de si le joueur a des munitions, donc quand les deux tirent, le résultat est3-x-x-y
, à moins que ce ne soit 3, auquel cas nous continuons. À la ligne 5, j'abuse l'analyseur syntaxique de Batch -%1
(qui est le mouvement en cours) est substitué avant que l'shift
instruction ne s'exécute et ne la supprime, donc nous allons toujours à la bonne étiquette.la source
Clojure, 168 octets
Moins de golf (si les deux personnes sont en vie, nous utilisons
M
pour mettre à jour leurs munitions et l'état de vie de l'ennemi, sinon nous retournons le statut actuel):Exemple d'utilisation (le premier élément indique si le joueur 1 est vivant à la fin du jeu, le deuxième élément indique si le joueur 2 est vivant, les 3e et 4e indiquent le statut des munitions qui n'est pas pertinent pour déterminer le gagnant):
Mise à jour: Eh bien regardez ça, cela
loop
a une longueur identique! Je trouve lareduce
version plus facile à développer car vous pouvez facilement inspecter les états intermédiaires si vous utilisezreductions
.la source
[l1 l2 r1 r2]
(ses valeurs modifiées àlet
et ses valeurs d'origine) et cesfn
signatures.loop
. Je trouve que cela conduit à un code plus net. Dès que j'ai besoin de plier avec plus d'un accumulateur, je change.PHP,
10710190 octetsen utilisant un masque de bits $ d pour l'état de chargement et une séquence DeBruijn pour les mouvements de tir.
prend l'entrée comme arguments de ligne de commande à 2 caractères, exécutez avec
-nr
.panne
fr
:: position = 1 = P1 se déclenche;rf
= position 2 = feux P2,ff
= position 3 = les deux feuxg<$m
<=>f<$m[0]
(f<$m
est toujours vrai, car il y a un deuxième caractère).la source
Python, 200 octets
la source
turns
au lieu de simplementt
, ce qui signifie que le programme est beaucoup plus grand que nécessaire. Veuillez également commencer votre soumission avec quelque chose comme#Python 2, 200 bytes
(en supposant que ce soit 2 et que le programme est de 200 octets) afin que la langue que vous utilisez soit claire.Clojure,
180173 octets-7 octets en changeant la fonction en fonction complète au lieu d'utiliser une macro. Cela m'a permis de créer les macros des fonctions internes, ce qui économise un peu.
Il s'agit d'une solution très littérale. Je suis un peu bloqué depuis que je viens d'écrire une version complète du jeu, et c'est essentiellement une version considérablement allégée de l'algorithme que j'ai utilisé. Il y a probablement beaucoup d'optimisations que je pourrais faire, mais j'en suis assez satisfait. Voir le code pré-golfé pour l'explication.
la source