Alice et Bob se battent


24
  • Alice (A) et Bob (B) ont décidé de se battre.
  • Chaque combattant a 10 points de vie.
  • À tour de rôle, ils lancent un dé à 6 faces pour les dégâts.
  • Ces dégâts sont retirés de la santé de leur adversaire.
  • À la fin, soit Alice soit Bob, vaincra leur ennemi.

Montrez-moi comment s'est déroulée la bataille. Sortie de ces codes pour les actions qui ont eu lieu.

Attaque

B a A    
^ Combatant
  ^ Action (attack)
    ^ Target

Rouleau

B r 4
^ Combatant
  ^ Action (roll)
    ^ Value

Changement de santé

A h 6
^ Combatant
  ^ Attribute (health)
    ^ Value   

Gagner

A w 
^ Combatant
  ^ Action (win)

Exemple de sortie:

A a B
A r 4
B h 6
B a A
B r 6
A h 4
A a B
A r 6
B h 0        
A w

Voici les règles:

  • Écrivez dans n'importe quelle langue.
  • Un seul jet de dé devrait avoir une chance égale de produire l'un des nombres 1, 2, 3, 4, 5 ou 6.
  • Alice commence toujours (Bob est chevaleresque, à l'ancienne).
  • Générez une action pour chaque tour.
  • Vous devez signaler les actions d'attaque, de roulis, de dégâts et de victoire.
  • Les combattants sont en majuscules, les actions sont en minuscules.
  • Il ne doit pas toujours produire le même résultat.
  • Il doit y avoir au moins un caractère d'espacement entre un combattant en sortie, une action et une valeur.
  • L'action de victoire a lieu lorsque l'adversaire a zéro ou moins de points de vie.
  • Toutes les parties d'une action doivent être sur la même ligne.
  • Il devrait y avoir une action par ligne.
  • Le moins d'octets gagne.

Allez-y!


9
Les noms Alice (A) et Bob (B) me donnent des flashbacks sur la classe de sécurité réseau. L'acteur Alice (A) envoie un paquet à Bob (B) avec la clé ... etc ...
Urne Magic Octopus

21
@MagicOctopusUrn c'est eux. Ils essaient généralement de communiquer. Malheureusement, un conflit survient souvent lorsque la communication tombe en panne.
AJFaraday

7
Les jours où nous essayions de découvrir comment cacher nos secrets à Mallory me manquaient ... c'était une époque plus simple ...
Bob

4
@Bob Mallory est vraiment une distraction. C'est Eve que vous devez surveiller.
AJFaraday

3
@ msh210 eh bien, le détail important du code golf est que tout le monde relève le même défi, mais voici la logique: - si vous jouiez à Donjons et Dragons, vous diriez "je vais frapper le gobelin", alors vous ' d rouler pour l'efficacité, puis mettre en œuvre le résultat du rouleau. Un rouleau n'a aucun sens si personne ne sait pour quoi vous roulez.
AJFaraday

Réponses:


5

05AB1E , 49 octets

"BaABr0Aha"S3ô»D„AB‡[6LΩ©Tǝ¤H®-©16ǝ=®0‹#s]н…ÿ w?

Essayez-le en ligne!

Explication

"BaABr0Aha"                                        # push the initial state of B
           S                                       # split to list of characters
            3ô                                     # divide into 3 parts
              »                                    # join each part on space and all on nl
               D„AB‡                              # make a copy with A and B inverted
                     [                             # start a loop
                      6LΩ©                         # pick a random number in [1 ... 6]
                          Tǝ                       # insert at position 10 of the string
                            ¤H                     # get the last char of the string and
                                                   # convert from hex
                              ®-©                  # subtract the random number
                                 16ǝ=              # insert at position 16 and print
                                     ®0‹#          # if the hp is less than 0, break
                                         s         # swap the other string to the stack top
                                          ]        # end loop
                                           н…ÿ w?  # print the winner

13

Python 3 , 131 octets

x,y="AB"
from random import*
X=Y=10
p=print
while X>0:p(x,"a",y);d=randint(1,6);p(x,"r",d);Y-=d;p(y,"h",Y);x,y,X,Y=y,x,Y,X
p(y,"w")

Essayez-le en ligne!

-8 octets grâce à officialaimm
-2 octets grâce à ChooJeremy


5
la prédéfinition vous p=printfera économiser environ 8 octets.
officialaimm

Étant donné que y gagne toujours à ce stade (et seulement X attaques dans la boucle, qui est ensuite remplacée par Y), vous n'avez pas besoin de vérifier si y a perdu. - ChooJeremy - De l'avis
NoOneIsHere

@NoOneIsHere merci de m'avoir transmis le message: D
HyperNeutrino

randint(1,6)pourrait être remplacé par id(X+Y)//3%6+1, bien que la distribution ne soit pas tout à fait uniforme.
Vincent

@Vincent Je ne vois pas l'intérêt de contourner les règles si cela n'aide même pas à le raccourcir ...
HyperNeutrino

7

C (gcc) , 146 141 octets

f(A,B,r,t,a,b){for(A=B=10;r=1+clock()%6,A*B>0;t=!t)printf("%c a %c\n%c r %u\n%c h %i\n",a=65+t,b=66-t,a,r,b,t?A-=r:(B-=r));printf("%c w",a);}

Essayez-le en ligne!

De-golf:

f(A,B,r,t,a,b){
    for(A=B=10; //Initialize HP
        r=1+clock()%6, // Get the number of processor cycles the program has consumed. This is relatively random, so I call it good enough.
        A*B>0;t=!t) // Flip t for change of turns
        printf("%c a %c\n%c r %u\n%c h %i\n", // Print the turn
            a=65+t,b=65+!t,a,r,b, // 65 is ASCII for 'A', 66 for 'B'
            t?A-=r:(B-=r)); // Deduct the damage.
    printf("%c w",a); // Print the winner
}

2
Pourriez-vous enregistrer un octet en utilisant a=65+t,b=66-t?
moopet

A*B>0vous fera économiser quelques octets.
Olivier Grégoire

A*Bpermettra d'économiser encore plus, mais je suis un peu pressé. Je mettrai à jour le soir

Trouvé un bug dans les dés seq {6,4,3,1,5}. b gagne avec santé -4. Voir TIO J'ai changé votre calculatrice de dés pour démo ce bug.
GPS

@GPS Merci, je corrige ça maintenant.

7

Python 3 , 127 octets

Il s'agit d'une amélioration de la réponse @HyperNeutrino qui ne rentrerait pas dans un commentaire. Voir l'explication ci-dessous.

x,y="AB"
s=id(0)
X=Y=10
p=print
while X>0:p(x,"a",y);s=s**7%~-2**67;d=s%6+1;p(x,"r",d);Y-=d;p(y,"h",Y);x,y,X,Y=y,x,Y,X
p(y,"w")

Essayez-le en ligne!


Une quête épique pour un jet de dés en python plus court

TL; DR: Il est possible de raser 4 octets du jet de dés Python standard en utilisant le cryptage RSA.

Je voulais voir si le jet de dés Python standard ( 32 octets ) pouvait être raccourci un peu:

from random import*;randint(1,6)

En particulier, il id(x)est très pratique d'apporter une valeur non déterministe au programme. Mon idée était alors de hacher en quelque sorte cette valeur pour créer un caractère aléatoire réel. J'ai essayé quelques approches, et l'une d'elles a porté ses fruits: le cryptage RSA .

Le cryptage RSA, en raison de sa simplicité, ne nécessite que quelques octets: m**e%n. La valeur aléatoire suivante peut ensuite être créée en chiffrant la précédente. En supposant que la (e,n)clé est disponible, le lancer de dés peut être écrit avec 22 octets :

s=id(0);s=s**e%n;s%6+1

Cela signifie que nous avons environ 10 octets pour définir une clé RSA valide. Ici, j'ai eu de la chance. Au cours de mes expériences, j'ai commencé à utiliser le Mersenne prime M67 pour me rendre compte plus tard que Mersenne avait fait une erreur en incluant M67 dans sa liste. Il se révèle être le produit de p=193707721et q=761838257287. J'avais trouvé mon module:

n=~-2**67

Maintenant, l'exposant et le totient de Charmichael (p-1)*(q-1) doivent être coprimes. Heureusement encore, le premier nombre premier qui ne divise pas le total de n ne comporte qu'un seul chiffre: 7. Le lancer de dés peut alors être écrit en utilisant 28 octets (4 octets de moins que l'approche standard):

s=id(0);s=s**7%~-2**67;s%6+1

Une bonne chose avec M67 est que la valeur aléatoire générée a 66 bits, ce qui est plus que le RNG 64 bits habituel. De plus, l'utilisation de RSA permet de remonter dans le temps en décryptant plusieurs fois la valeur courante. Voici les clés de chiffrement et de déchiffrement:

Encryption: (7,                    147573952589676412927)
Decryption: (42163986236469842263, 147573952589676412927)

Je ne suis certainement pas un expert en statistiques ou en cryptographie, donc je ne peux pas vraiment dire si ce RNG vérifie ou non les critères de "bon hasard". J'ai écrit un petit benchmark qui compare l'écart type des occurrences des 1 à 6 lancers de dés en utilisant différents RNG. Il semble que la solution proposée fonctionne comme les autres.


3
Un travail impressionnant! :)
HyperNeutrino

4

JavaScript (ES6), 122 octets

f=(h=[10,10,p=0])=>`${x='AB'[p]} a ${y='BA'[p]}
${x} r ${d=Math.random()*6+1|0}
${y} h ${H=h[p^=1]-=d}
${H<1?x+' w':f(h)}`

Essayez-le en ligne!


4

Java (JDK 10) , 180 octets

v->{var r="";int p=0,H[]={10,10},h=0;for(;H[0]*H[1]>0;)r+=r.format("%3$c a %4$c%n%3$c r %d%n%4$c h %d%n",h+=Math.random()*6-h+1,H[p]-=h,p+65,(p^=1)+65);return r+(char)(66-p)+" w";}

Essayez-le en ligne!

Crédits


1
Java 10 a var? o.Ô J'ai vraiment besoin d'enquêter sur certaines des nouvelles spécifications bientôt. Quoi qu'il en soit, vous pouvez jouer au golf 4 octets en changeant le tableau de caractères en int-tableau:v->{var r="";int P[]={65,66},p=0,H[]={10,10},h=0;for(;H[0]*H[1]>0;)r+=r.format("%3$c a %4$c%n%3$c r %d%n%4$c h %d%n",h+=Math.random()*6-h+1,H[p]-=h,P[p],P[p^=1]);return r+=P[p^1]+" w";}
Kevin Cruijssen

1
@KevinCruijssen Oui, Java 10 a var. Pas besoin de lire plus loin, c'est fondamentalement le seul changement qui soit utilisable pour nous golfeurs. Et non je ne peux pas faire ce que vous proposez: vérifiez la dernière ligne du résultat: il devient à la 65 wplace de A w. C'est pourquoi je l'ai extrait de la int ...déclaration: jouer au golf quelques octets ;-)
Olivier Grégoire

1
@KevinCruijssen J'ai respecté quelques exemples ici: codegolf.stackexchange.com/a/159922/16236
Olivier Grégoire



3

Rubis , 122 120 96 92 91 octets

f=->x=?A,y=?B,m=10,n=m{p [x,?a,y],[x,?r,r=1+rand(6)],[y,?h,t=n-r]
t<1?p([x,?w]):f[y,x,t,m]}

Enregistré 1 octet grâce à Asone Tuhid .

Essayez-le en ligne!


1
C'est comme si je ne savais même plus comment Ruby;)
AJFaraday

Je crains que votre alternative ne fonctionne pas, "Toutes les parties d'une action doivent être sur la même ligne." Cependant, pourrait-il être possible de faire la même optimisation avec un caractère de tabulation?
AJFaraday

@AJFaraday Serait-il acceptable de produire des lignes au format ["A", "a", "B"]? Si oui, j'ai cette solution de 96 octets.
Cristian Lupascu

S'ils en produisent un par ligne. Cela devrait faire l'affaire.
AJFaraday

-1 octet si vous remplacez ?(p [x,?w]):par?p([x,?w]):
Asone Tuhid

3

Java 8, 230 octets

v->{for(int h=104,a=h,x=0,y=1,A=10,B=A,r=0,t=0,T;a<119;)System.out.printf("%c %3$c %c%n",(x=a>h|A*B<1?x^1:x)+65,y=(a<98?t=r+=Math.random()*6-r+1:a>h?(T=x<1?A-=t:(B-=t))<0?0:T:A*B<1?-16:(x^1)+17)+48,a=a<98?114:a>h?104:A*B<1?119:97);}

Remarque: il y a déjà une réponse Java beaucoup plus courte, alors assurez-vous de voter pour la sienne ! Cependant, j'utilise une approche complètement différente, donc j'ai pensé qu'il valait également la peine d'être publié.

Explication:

Essayez-le en ligne.

v->{                     // Method with empty unused parameter and no return-type
  for(int h=104,         //  Temp integer with unicode for 'h' to save bytes
          a=h,           //  Second part (Action)
          x=0,           //  First part
          y=1,           //  Third part
          A=10,          //  Score player A, starting at 10
          B=A,           //  Score player B, starting at 10
          r=0,           //  Random dice-roll
          t=0,           //  Previous dice-roll
          T;             //  Temp integer
      a<119;)            //  Loop until there is a winner
     System.out.printf(  //   Print
      "%c %3$c %c,%n",   //    The three parts with spaces, and a new-line
      (x=                //    First part:
         a>h             //     If the previous action is 'r',
         |A*B<1?         //     or there is a winner:
           x^1           //      Change A→B or B→A
         :               //     Else:
          x)             //      A/B remains unchanged
       +65,              //     Add 65 to convert 0/1 to 65/66 (unicode values of A/B)
      (y=                //    Third part:
         (a<98?          //     If the previous action was 'a'
           t=r+=Math.random()*6-r+1
                         //      Roll the dice, and save it in `t`
          :a>h?          //     Else-if the previous action was 'r':
           (T=x<1?       //      If the first part changed to player A:
            A-=t         //       Subtract the previous dice-roll from A
           :             //      Else:
            (B-=t))      //       Subtract the previous dice-roll from B
           <0?           //      If this score is below 0:
            0            //       Use 0
           :             //      Else:
            T            //       Use this score
         :               //     Else (the previous action was 'h'):
          A*B<1?         //      Is there a winner:
           -16           //       Change the third part to a space
          :              //      Else:
           (x^1)+17)     //       Change the third part to the other player
       +48,              //     Add 48 to convert it to unicode
       a=                //    Second part:
         a<98?           //     If the previous action was 'a': 
          114            //      Change it to 'r'
         :a>h?           //     Else-if the previous action was 'r':
          h              //      Change it to 'h'
         :               //     Else (the previous action was 'h'):
          A*B<1?         //      If either score is 0:
           119           //       Use 'w'
          :              //      Else:
           97);}         //       Use 'a'


2

Lot, 174 octets

@set/aA=B=10
@set c=A
@set d=B
:g
@set/ar=%random%%%6+1,h=%d%-=r
@echo %c% a %d%
@echo %c% r %r%
@echo %d% h %h%
@if %h% gtr 0 set c=%d%&set d=%c%&goto g
@echo %c% w

Explication: %les références de variable sont remplacées au moment de l'analyse. Cela présente deux avantages utiles:

  • %d%-=rsoustrait rde la variable nommée par d(c.-à-d. référence indirecte)
  • set c=%d%&set d=%c% est tout simplement un échange direct.

2

PHP 7.1: 159 octets

<?php $A=$B=10;$t='AB';while($A>0&&$B>0){$a=$t[0];$b=$t[1];$d=rand(1,6);$$b-=$d;echo"$a a $b\n$a r $d\n$b h {$$b}\n";$t=strrev($t);}echo($A>0?'A':'B')." w\n";

Exécutez-le dans le navigateur ici!

PHP 5.6: 156 octets

<?php $A=$B=10;$t='AB';while($A>0&&$B>0){list($a,$b)=$t;$d=rand(1,6);$$b-=$d;echo"$a a $b\n$a r $d\n$b h {$$b}\n";$t=strrev($t);}echo($A>0?'A':'B')." w\n";

Exécutez-le dans le navigateur ici!

Voici à quoi ressemble la solution PHP 5.6 avec le formatage et les commentaires:

<?php
// Initialize both HP counters
$A = $B = 10;

// Set the turn order as a string (which 5.6 allows to be unpacked into a list)
$t = 'AB';

// Run this loop as long as both players have HP
while ($A > 0 && $B > 0) {
    // Unpack the turn string into $a and $b variables; on the first run, $a = 'A'
    // and $b = 'B'. This is no longer possible in PHP 7.0, so the PHP 7.0
    // solution needed to use an array instead.
    list($a, $b) = $t;

    // Set damage to a random number between 1 and 6
    $d = rand(1, 6);

    // Subtract the damage from the referenced value $b. On the first turn, this
    // is 'B', so this ends up subtracting $d from $B. Next turn, $b will be 'A',
    // so it'll subtract $d from $A
    $$b -= $d;

    // Echo the string (interpolated values)
    echo "$a a $b\n$a r $d\n$b h {$$b}\n";

    // Reverse the turn order string ('AB' becomes 'BA', which will affect the
    // call to list in the first line of the while-loop)
    $t = strrev($t);
}

// Someone's run out of HP; figure out whom by figuring out who still has HP
echo ($A > 0 ? 'A' : 'B') . " w\n";

1

Bash, 178 octets

A=10 B=10 e=echo
a(){ $e $1 a $2;d=$((RANDOM%6+1));$e $1 r $d;eval $2=$((${!2}-$d));$e $2 h ${!2};[ ${!2} -gt 0 ];}
while a A B && a B A;do cd;done;[ $A -gt 0 ]&&$e A w||$e B w

1

F #, 238 235 octets

Je pensais que j'allais bien, mais vous m'avez tous surclassé de loin!

let p=printfn
let mutable A=10
let mutable B=A
let x h a d=
 p"%s a %s"a d
 let i=(new System.Random()).Next(1,7)
 let j=h-i
 p"%s r %i"a i
 p"%s h %i"d j
 if j<=0 then p"%s w"a
 j
while A*B>0 do
 B<-x B"A""B"
 if B>0 then A<-x A"B""A"

Essayez-le en ligne!

Merci à Rogem pour le brillant conseil d'utiliser A * B> 0 au lieu de A> 0 && B> 0 (enlève 3 octets).

Merci également à officialaimm, dont la suggestion de prédéfinir printf dans la réponse Python m'a également aidé à réduire de quelques octets.


1
Un conseil que j'ai reçu de @OlivierGregoire: vous A*B>0permettra d'économiser encore quelques.

C'est absolument génial. Aimer. Merci beaucoup!
Ciaran_McCarthy

1

Haskell , 204 octets

Ma tentative avec Haskell, je n'ai pas pu l'obtenir plus compétitif malheureusement

import System.Random
main=getStdGen>>= \g->putStr$q(randomRs(1,6)g)10(10::Int)"A ""B "
(!)=(++)
l="\n"
q(x:z)a b p o=p!"a "!o!l!p!"r "!show x!l!o!"h "!show n!l!if n<1then p!"w"else q z n a o p where n=b-x

Essayez-le en ligne!

Explications:

import System.Random  --import random module
main=                        --main function, program entry point
 getStdGen                   -- get the global random number generator
   >>= \g->                  --using the random generator g
       putStr $ q            --print the result of function q, passing in ..
          (randomRs (1,6) g) --an infinite list of random numbers, 1 to 6 generated by g
           10 (10::Int)      --the starting health of both players, 
                             --type annotation sadly seems to be required
           "A " "B "         --The names of the players,
                             --with an extra space for formatting
(!)=(++) --define the operator ! for list (String) concatenation, 
         -- we do this a lot so we save a bit by having a one byte operator
l="\n"   -- define l as the newline character

q      --define function q                         
 (x:z) --our list of random numbers, split into the next number (x) and the rest (z)
 a     -- the health of the active player
 b     -- the health of the player getting attacked
 p     -- the name of the active player
 o     -- the name of the player getting attacked
=
  p!"a "!o!l --create the attack action string with a newline
 !p!"r "!show x!l -- append the roll action
 !o!"h "!show n!l -- append the health remaining
 !           -- append the result of the following if
  if n<1     -- if the player being attacked has been defeated
  then p!"w" -- append the win string for the active player
  else q z n a o p  --otherwise append the result of calling q again with 
                    --rest of the random numbers, and the active players swapped
  where n=b-x -- define the attacked player's new health n
              -- their current health b - the random roll x

Vous pouvez consulter nos conseils pour jouer au golf à Haskell . Par exemple , where m=b-xpeut être mis en garde: |m<-b-x=.
Laikoni

Vous pouvez perdre le lambda et un ensemble de parenthèses en réorganisant certains paramètres: main=putStr=<<q"A "10"B "10.randomRs(1,6::Int)<$>getStdGen. Vous pouvez également utiliser une liste et la concaténer pour vous débarrasser de la redéfinition (++). Le dernier où ne semble pas être bénéfique à simplement utiliser b-xpartout.
Angs

1

Julia 0,6 , 175 octets

p=println()
f(l="AB",h=[10,10],a=1)=(while min(h...)>0;d=3-a;p(l[a]," a ",l[d]);r=rand(1:6);h[d]-=r;p(l[a]," r ",r);p(l[d]," h ",max(h[d],0));a=d;end;p(l[findmax(h)[2]]," w"))

Essayez-le en ligne!

Version longue et non golfée:

function status(player, health)
    println("$player h $(max(0,health))")
end

function roll(player)
    x = rand(1:6)
    println("$player r $x")
    x
end

function play()
    players = ["A","B"]
    healths = [10, 10]
    attacker = 1

    while min(healths...) > 0
        println("$(players[attacker]) a $(players[3-attacker])")
        healths[3-attacker]-=roll(players[attacker])
        status(players[3-attacker], healths[3-attacker])

        attacker = 3 - attacker
    end

    winner = findmax(healths)[2]
    println("$(players[winner]) w")
end

Il ne semble pas y avoir de sortie dans votre lien TIO.
AJFaraday

Ouais, je ne sais pas pourquoi tio n'aime pas ça. Cela fonctionne bien sur ma machine. Je vais m'en occuper si j'ai le temps.
niczky12

1

VBA, 222 185 179 octets

Cette solution récursive implique 3 sous-marins

  1. g est le début du jeu qui démarre le premier tour
  2. t est appelé pour chaque tour . Il utilise la récursivité.
  3. p est plus court que Debug.Print lorsqu'il est utilisé plus de 3 fois (seulement 4 dans cette solution) Edit: Maintenant que j'ai appris que Debug.?c'est une alternative acceptable à Debug.Print, il Debug.?xest plus court que d'appeler un Sub pour imprimer.
Sub g()
t "A",10,"B",10
End Sub
Sub t(i,j,x,h)
d=Int(Rnd()*6)+1
Debug.?i &" a "&x
Debug.?i &" r "&d
h=h-d
If h<1Then
Debug.?i &" w"
Else
Debug.?x &" h "&h
t x,h,i,j
End If
End Sub

C'était un défi amusant. Si vous connaissez un interprète en ligne comme TIO pour VB6 / VBScript / VBA, veuillez laisser un commentaire. Ensuite, je peux poster un lien vers une solution de travail.

Si vous souhaitez tester ce code et installer Microsoft Excel, Word, Access ou Outlook (Windows uniquement), appuyez sur Alt + F11 pour ouvrir l'IDE VBA. Insérez un nouveau module de code (Alt + I, M) et désactivez Option Explicit. Collez ensuite le code et appuyez sur F5 pour l'exécuter. Les résultats devraient apparaître dans la fenêtre Exécution (appuyez sur Ctrl + G si vous ne le voyez pas).

Edit 1: Suppression des espaces que l'éditeur VBA ajoutera automatiquement. Réduit de 37 octets
Édition 2: Suppression de Sub p () * pour enregistrer 6 octets après l'apprentissage Debug.?est une alternative acceptable Debug.Print. L'appel d'un Sub pour gérer n'économise Debug.?que des octets après plus de six appels.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.