Alice e Bob litigano


24
  • Alice (A) e Bob (B) hanno deciso di combattere.
  • Ogni combattente ha 10 punti salute.
  • Si alternano per tirare un dado a 6 facce per danni.
  • Quel danno viene rimosso dalla salute del loro avversario.
  • Alla fine, Alice o Bob sconfiggeranno il loro nemico.

Mostrami come è andata la battaglia. Emissione di questi codici per le azioni che hanno avuto luogo.

attacco

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

rotolo

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

Cambiamento di salute

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

Vincere

A w 
^ Combatant
  ^ Action (win)

Esempio di output:

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

Ecco le regole:

  • Scrivi in ​​qualsiasi lingua.
  • Un singolo tiro del dado dovrebbe avere le stesse possibilità di provocare uno qualsiasi dei numeri 1, 2, 3, 4, 5 o 6.
  • Alice inizia sempre (Bob è cavalleresco, alla vecchia maniera).
  • Emetti un'azione per ogni turno.
  • Devi segnalare l'attacco, tirare, danneggiare e vincere le azioni.
  • I combattenti sono in maiuscolo, le azioni in minuscolo.
  • Non deve produrre costantemente lo stesso risultato.
  • Ci deve essere almeno un carattere di spazio tra un combattente in uscita, un'azione e un valore.
  • L'azione vincente si svolge quando l'avversario ha zero o meno salute.
  • Tutte le parti di un'azione devono essere sulla stessa linea.
  • Dovrebbe esserci un'azione per riga.
  • Vince il minor numero di byte.

Ce l'ho!


9
I nomi Alice (A) e Bob (B) mi stanno dando flashback alla classe di sicurezza della rete. L'attore Alice (A) invia un pacchetto a Bob (B) con chiave ... ecc ...
Magic Octopus Urn

21
@MagicOctopusUrn sono loro. Di solito stanno cercando di comunicare. Purtroppo, spesso si verificano conflitti quando si interrompe la comunicazione.
AJFaraday,

7
Mi mancano i giorni in cui stavamo cercando di capire come nascondere i nostri segreti a Mallory ... quelli erano tempi più semplici ...
Bob

4
@Bob Mallory è davvero una distrazione. È la vigilia che devi fare attenzione.
AJFaraday,

3
@ msh210 bene, il dettaglio importante nel code golf è che tutti accettano la stessa sfida, ma ecco la logica: - se stessi giocando a Dungeons and Dragons, diresti "Vado a dare dei calci al folletto", allora tu ' d roll per efficacia, quindi implementare il risultato del roll. Un tiro non ha senso se nessuno sa per cosa stai tirando.
AJFaraday,

Risposte:


5

05AB1E , 49 byte

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

Provalo online!

Spiegazione

"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 byte

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")

Provalo online!

-8 byte grazie a officialaimm
-2 byte grazie a ChooJeremy


5
il predefining p=printti farà risparmiare circa 8 byte.
officialaimm,

Poiché y vince sempre a questo punto (e solo X attacca nel loop, che viene successivamente scambiato con Y), non è necessario verificare se y ha perso. - ChooJeremy - Dalla recensione
NoOneIsHere

@NoOneIsHere grazie per avermi trasmesso il messaggio: D
HyperNeutrino,

randint(1,6)potrebbe essere sostituito con id(X+Y)//3%6+1, sebbene la distribuzione non sia abbastanza uniforme.
Vincent,

@Vincent Non vedo il punto di piegare le regole se non aiuta nemmeno a renderlo più breve ...
HyperNeutrino

7

C (gcc) , 146 141 byte

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);}

Provalo online!

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
Potresti salvare un byte usando a=65+t,b=66-t?
Moopet,

A*B>0ti farà risparmiare qualche byte.
Olivier Grégoire,

A*Bsalverò ancora di più, ma sono un po 'di fretta atm. Aggiornerò la sera

Trovato un bug nel dado seq {6,4,3,1,5}. b vince con la salute -4. Vedi TIO Ho cambiato il tuo calcolatore di dadi per dimostrare questo errore.
GPS

@GPS Grazie, lo farò ora.

7

Python 3 , 127 byte

Questo è un miglioramento sulla risposta di @HyperNeutrino che non rientrava in un commento. Vedi la spiegazione di seguito.

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")

Provalo online!


Una ricerca epica per un tiro di dadi in pitone più corto

TL; DR: è possibile radere 4 byte dal tiro standard di dadi in pitone usando la crittografia RSA.

Volevo vedere se il tiro standard di dadi in pitone ( 32 byte ) potesse essere abbreviato un po ':

from random import*;randint(1,6)

In particolare, id(x)è abbastanza conveniente introdurre un valore non deterministico nel programma. La mia idea quindi era di in qualche modo hash questo valore per creare una casualità effettiva. Ho provato alcuni approcci e uno di loro ha dato i suoi frutti : la crittografia RSA .

Cifratura RSA, grazie alla sua semplicità, richiede solo pochi byte: m**e%n. Il successivo valore casuale può quindi essere creato crittografando quello precedente. Supponendo che la (e,n)chiave sia disponibile, il tiro di dado può essere scritto con 22 byte :

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

Ciò significa che abbiamo circa 10 byte per definire una chiave RSA valida. Qui sono stato fortunato. Durante i miei esperimenti, ho iniziato a utilizzare Mersenne prime M67 solo per rendermi conto in seguito che Mersenne ha commesso un errore includendo M67 nella sua lista. Risulta essere il prodotto di p=193707721e q=761838257287. Avevo trovato il mio modulo:

n=~-2**67

Ora, l'esponente e il Totient Charmichael (p-1)*(q-1) devono essere coprimi. Fortunatamente, il primo numero primo che non divide il totale di n è lungo solo una cifra: 7. Il tiro di dado può quindi essere scritto usando 28 byte (4 byte in meno rispetto all'approccio standard):

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

Una cosa buona con M67 è che il valore casuale generato ha 66 bit, che è più del solito RNG a 64 bit. Inoltre, l'uso di RSA consente di tornare indietro nel tempo decodificando il valore corrente più volte. Ecco le chiavi di crittografia e decrittografia:

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

Non sono sicuramente un esperto di statistica o crittografia, quindi non posso davvero dire se questo RNG controlla o meno i criteri per "buona casualità". Ho scritto un piccolo benchmark che confronta la deviazione standard delle occorrenze dei tiri da 1 a 6 usando diversi RNG. Sembra che la soluzione proposta funzioni esattamente come le altre.


3
Lavoro impressionante! :)
HyperNeutrino

4

JavaScript (ES6), 122 byte

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)}`

Provalo online!


4

Java (JDK 10) , 180 byte

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";}

Provalo online!

Crediti


1
Java 10 ha var? o.Ô Ho davvero bisogno di studiare presto alcune delle nuove specifiche .. Comunque, puoi giocare a golf a 4 byte modificando il char-array in int-array: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 Sì, Java 10 ha var. Non ho bisogno di leggere oltre, è sostanzialmente l'unico cambiamento utilizzabile per noi golfisti. E no, non posso fare ciò che suggerisci: controlla l'ultima riga del risultato: diventa 65 winvece di A w. Ecco perché l'ho estratto int ...dall'affermazione: giocare a golf a pochi byte ;-)
Olivier Grégoire,

1
@KevinCruijssen Ho seguito alcuni esempi qui: codegolf.stackexchange.com/a/159922/16236
Olivier Grégoire



3

Rubino , 122 120 96 92 91 byte

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]}

Salvato 1 byte grazie a Asone Tuhid .

Provalo online!


1
È come se non sapessi più nemmeno come Ruby;)
AJFaraday,

Temo che la tua alternativa non funzioni: "Tutte le parti di un'azione devono essere sulla stessa linea". Tuttavia, potrebbe essere possibile effettuare la stessa ottimizzazione con un carattere di tabulazione?
AJFaraday,

@AJFaraday Sarebbe accettabile produrre linee nel formato ["A", "a", "B"]? In tal caso, ho questa soluzione a 96 byte.
Cristian Lupascu,

Se vengono emessi uno per riga. Quello dovrebbe fare.
AJFaraday,

-1 byte se si sostituisce ?(p [x,?w]):con?p([x,?w]):
Asone Tuhid

3

Java 8, 230 byte

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);}

Nota: esiste già una risposta Java molto più breve, quindi assicurati di votare la sua ! Uso comunque un approccio completamente diverso, quindi ho pensato che valesse la pena pubblicare anche questo.

Spiegazione:

Provalo online.

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'

3

C (gcc) , 142 byte

#define R(c,t)r=rand()%6+1,c&&printf(#c" a "#t"\n"#c" r %d\n"#t" h %d\n",r,t-=t<r?t:r),t||puts(#c" w")
f(A,B,r){for(A=B=10;A*B;R(B,A))R(A,B);}

Provalo online!


Solo un problema, questo non si è concluso con una vittoria.
AJFaraday,

@AJFaraday Oh sì, risolto.
nwellnhof,

2

Lotto, 174 byte

@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

Spiegazione: %i riferimenti alle variabili vengono sostituiti al momento dell'analisi. Ciò ha due vantaggi utili:

  • %d%-=r sottrae r dalla variabile indicata da d(cioè riferimento indiretto)
  • set c=%d%&set d=%c% è semplicemente uno scambio diretto.

2

PHP 7.1: 159 byte

<?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";

Eseguilo nel browser qui!

PHP 5.6: 156 byte

<?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";

Eseguilo nel browser qui!

Ecco come appare la soluzione PHP 5.6 con formattazione e commenti:

<?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 byte

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 byte

Pensavo che stavo andando bene, ma mi hai superato di gran lunga!

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"

Provalo online!

Grazie a Rogem per il brillante consiglio di usare A * B> 0 invece di A> 0 && B> 0 (toglie 3 byte).

Grazie anche a officialaimm, il cui suggerimento sulla predefinizione della stampa nella risposta di Python mi ha aiutato a radere qualche byte.


1
Un consiglio che ho ricevuto da @OlivierGregoire: A*B>0ti farà risparmiare ancora un paio.

È assolutamente geniale. Lo adoro. Grazie mille!
Ciaran_McCarthy

1

Haskell , 204 byte

Il mio tentativo con Haskell, sfortunatamente, non sono riuscito a renderlo più competitivo

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

Provalo online!

spiegazioni:

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

Puoi dare un'occhiata ai nostri consigli per giocare a golf a Haskell . Ad esempio, where m=b-xpuò essere messo in guardia: |m<-b-x=.
Laikoni,

Si può perdere la lambda e una serie di parentesi riorganizzando alcuni parametri: main=putStr=<<q"A "10"B "10.randomRs(1,6::Int)<$>getStdGen. Puoi anche utilizzare un elenco e concatenerlo per eliminare la ridefinizione (++). L'ultimo dove non sembra essere utile usare solo b-xovunque.
Angs

1

Julia 0.6 , 175 byte

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"))

Provalo online!

Versione lunga e non golfata:

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

Non sembra esserci alcun output nel tuo link TIO.
AJFaraday,

Sì, non so perché a Tio non piaccia. Funziona bene sulla mia macchina. Ci penserò se avrò tempo.
niczky12

1

VBA, 222 185 179 byte

Questa soluzione ricorsiva coinvolge 3 sottotitoli

  1. g è l' inizio del gioco che inizia il primo turno
  2. t viene chiamato per ogni turno . Usa la ricorsione.
  3. p è più breve di Debug.Print se usato più di 3 volte (solo 4 in questa soluzione) Modifica: ora che ho imparato che Debug.?è un'alternativa accettabile Debug.Print, Debug.?xè più breve di chiamare un Sub per stampare.
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

Questa è stata una sfida divertente. Se conosci un interprete online come TIO per VB6 / VBScript / VBA, lascia un commento. Quindi posso pubblicare un collegamento a una soluzione funzionante.

Se vuoi testare questo codice e hai installato Microsoft Excel, Word, Access o Outlook (solo Windows), premi Alt + F11 per aprire l'IDE VBA. Inserire un nuovo modulo di codice (Alt + I, M) e deselezionare Opzione esplicita. Quindi incolla il codice e premi F5 per eseguirlo. I risultati dovrebbero apparire nella finestra immediata (premi Ctrl + G se non li vedi).

Modifica 1: spazio vuoto rimosso che verrà automaticamente aggiunto dall'editor VBA. Ridotto di 37 byte
Modifica 2: rimosso Sub p () * per salvare 6 byte dopo l'apprendimento Debug.?è un'alternativa accettabile Debug.Print. Chiamare un sub per gestire Debug.?salva solo i byte dopo più di sei chiamate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.