Alice e Bob brigam


24
  • Alice (A) e Bob (B) decidiram ter uma batalha.
  • Cada combatente tem 10 pontos de vida.
  • Eles revezam-se para rolar um dado de 6 lados por danos.
  • Esse dano é removido da saúde do oponente.
  • No final, Alice ou Bob vencerão seu inimigo.

Mostre-me como foi a batalha. Saída desses códigos para as ações que ocorreram.

Ataque

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

Lista

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

Mudança de saúde

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

Ganhar

A w 
^ Combatant
  ^ Action (win)

Exemplo de saída:

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

Aqui estão as regras:

  • Escreva em qualquer idioma.
  • Um único lançamento do dado deve ter a mesma chance de resultar em qualquer um dos números 1, 2, 3, 4, 5 ou 6.
  • Alice sempre começa (Bob é cavalheiresco, à moda antiga).
  • Faça uma ação para cada turno.
  • Você deve relatar as ações de ataque, rolagem, dano e vitória.
  • Os combatentes são maiúsculos, as ações são minúsculas.
  • Ele não deve produzir consistentemente o mesmo resultado.
  • Deve haver pelo menos um caractere de espaço em branco entre um combatente de saída, ação e valor.
  • A ação ganha ocorre quando o oponente tem zero ou menos pontos de vida.
  • Todas as partes de uma ação devem estar na mesma linha.
  • Deve haver uma ação por linha.
  • Menos bytes ganha.

Têm-no!


9
Os nomes Alice (A) e Bob (B) estão me dando flashbacks para a classe de segurança de rede. O ator Alice (A) envia um pacote para Bob (B) com a chave ... etc ...
— Magic Octopus Urn

21
@MagicOctopusUrn são eles. Eles geralmente estão tentando se comunicar. Infelizmente, muitas vezes ocorre conflito quando a comunicação falha.
— AJFaraday

7
Sinto falta dos dias em que tentávamos descobrir como esconder nossos segredos de Mallory ... eram tempos mais simples ...
— Bob

4
@Bob Mallory é realmente uma distração. É Eva que você precisa tomar cuidado.
— AJFaraday

3
@ msh210 bem, o detalhe importante no código de golfe é que todos aceitam o mesmo desafio, mas aqui está a lógica: - se você estivesse jogando Dungeons and Dragons, você diria “eu vou chutar o goblin”, então você ' d role para obter eficácia, depois implemente o resultado do rolo. Um rolo não faz sentido se ninguém souber pelo que você está rolando.
— AJFaraday

Respostas:


5

05AB1E , 49 bytes

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

Experimente online!

Explicação

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

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

Experimente online!

-8 bytes graças a officialaimm
-2 bytes graças a ChooJeremy


5
a predefinição p=printeconomizará cerca de 8 bytes.
— officialaimm

Como y sempre vence neste momento (e apenas X ataca no loop, que é posteriormente trocado por Y), você não precisa verificar se y perdeu. - ChooJeremy - Da avaliação
— NoOneIsHere

@NoOneIsHere obrigado por passar a mensagem para mim: D
— HyperNeutrino

randint(1,6)pode ser substituído por id(X+Y)//3%6+1, embora a distribuição não seja bastante uniforme.
— Vincent

@Vincent eu não vejo o ponto de quebrar as regras, se ele mesmo não ajuda torná-lo mais curto ...
— HyperNeutrino

7

C (gcc) , 146 141 bytes

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

Experimente online!

De-golfe:

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
Você poderia salvar um byte usando a=65+t,b=66-t?
— moopet

A*B>0você economizará alguns bytes.
— Olivier Grégoire

A*Bvai economizar ainda mais, mas estou meio que com pressa. Eu atualizo à noite

Encontrou um bug nos dados seq {6,4,3,1,5}. b vence com saúde -4. Veja TIO Troquei sua calculadora de dados para demonstrar esse bug.
— GPS

@ GPS Obrigado, eu vou corrigir isso agora.

7

Python 3 , 127 bytes

Esta é uma melhoria na resposta @HyperNeutrino que não caberia em um comentário. Veja a explicação abaixo.

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

Experimente online!


Uma busca épica por um rolo de dados python mais curto

TL; DR: É possível raspar 4 bytes do rolo de dados python padrão usando a criptografia RSA.

Eu queria ver se o rolo de dados python padrão ( 32 bytes ) poderia ser reduzido um pouco:

from random import*;randint(1,6)

Em particular, id(x)é bastante conveniente trazer algum valor não determinístico para o programa. Minha idéia, então, era de alguma forma misturar esse valor para criar alguma aleatoriedade real. Tentei algumas abordagens e uma delas valeu a pena: criptografia RSA .

A criptografia RSA, devido à sua simplicidade, requer apenas alguns bytes: m**e%n . O próximo valor aleatório pode ser criado criptografando o valor anterior. Supondo que a (e,n)chave esteja disponível, o rolo de dados pode ser escrito com 22 bytes :

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

Isso significa que temos cerca de 10 bytes para definir uma chave RSA válida. Aqui eu tive sorte. Durante minhas experiências, comecei a usar o Mersenne prime M67 apenas para perceber mais tarde que Mersenne cometeu um erro, incluindo M67 em sua lista. Acontece que é o produto de p=193707721e q=761838257287. Eu encontrei meu módulo:

n=~-2**67

Agora, o expoente e o Charmichael totient (p-1)*(q-1) precisam ser coprimes. Felizmente, novamente, o primeiro número primo que não divide o totiente de n tem apenas um dígito: 7. A rolagem de dados pode ser escrita usando 28 bytes (4 bytes a menos que a abordagem padrão):

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

Uma coisa boa com M67 é que o valor aleatório gerado possui 66 bits, que é mais do que o usual RNG de 64 bits. Além disso, o uso do RSA torna possível voltar no tempo descriptografando o valor atual várias vezes. Aqui estão as chaves de criptografia e descriptografia:

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

Definitivamente, não sou especialista em estatística ou criptografia, por isso não sei dizer se esse RNG verifica os critérios de "boa aleatoriedade" ou não. Escrevi uma pequena referência que compara o desvio padrão das ocorrências de 1 a 6 jogadas de dados usando RNGs diferentes. Parece que a solução proposta funciona exatamente como as outras.


3
Trabalho impressionante! :)
— HyperNeutrino 24/03

4

JavaScript (ES6), 122 bytes

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

Experimente online!


4

Java (JDK 10) , 180 bytes

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

Experimente online!

Créditos


11
Java 10 tem var? o.Ô Eu realmente preciso investigar algumas das novas especificações em breve. De qualquer forma, você pode obter 4 bytes de golfe alterando o char-array para 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

11
@KevinCruijssen Sim, o Java 10 tem var. Não precisa ler mais, é basicamente a única alteração que é utilizável para nós, golfistas. E não, não posso fazer o que você sugere: verifique a última linha do resultado: torna-se em 65 wvez de A w. É por isso que eu extraí-lo da int ...declaração: a golf alguns bytes ;-)
— Olivier Grégoire

11
@KevinCruijssen I cumpriu alguns exemplos aqui: codegolf.stackexchange.com/a/159922/16236
— Olivier Grégoire



3

Ruby , 122 120 96 92 91 bytes

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

Guardado 1 byte graças a Asone Tuhid .

Experimente online!


11
É como se eu nem sei como rubi mais;)
— AJFaraday

Receio que sua alternativa não funcione: "Todas as partes de uma ação devem estar na mesma linha". Embora, seja possível fazer a mesma otimização com um caractere de tabulação?
— AJFaraday

@AJFaraday Seria aceitável enviar linhas no formato ["A", "a", "B"]? Nesse caso, eu tenho essa solução de 96 bytes.
— Cristian Lupascu 22/03

Se eles são produzidos um por linha. Isso deve servir.
— AJFaraday

-1 byte se você substituir ?(p [x,?w]):por?p([x,?w]):
— Asone Tuhid 22/03

3

Java 8, 230 bytes

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: já existe uma resposta Java muito mais curta, portanto, vote novamente na sua ! No entanto, eu uso uma abordagem completamente diferente, então achei que também valia a pena postar.

Explicação:

Experimente 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'


2

Lote, 174 bytes

@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

Explicação: % as referências de variáveis ​​são substituídas no momento da análise. Isso tem dois benefícios úteis:

  • %d%-=rsubtrai rda variável nomeada pord (ou seja, referência indireta)
  • set c=%d%&set d=%c% é simplesmente uma troca direta.

2

PHP 7.1: 159 bytes

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

Execute-o no navegador aqui!

PHP 5.6: 156 bytes

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

Execute-o no navegador aqui!

Aqui está a aparência da solução PHP 5.6 com formatação e comentários:

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

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 bytes

Eu pensei que estava indo bem, mas todos vocês me superaram muito!

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"

Experimente online!

Agradecemos a Rogem pelo brilhante conselho de usar A * B> 0 em vez de A> 0 && B> 0 (decola 3 bytes).

Obrigado também a officialaimm, cuja dica sobre a predefinição de printf na resposta do Python me ajudou a raspar alguns bytes também.


11
Um conselho que recebi de @OlivierGregoire: A*B>0você economizará mais um pouco.

Isso é absolutamente brilhante. Adoro. Muito obrigado!
— Ciaran_McCarthy 24/03

1

Haskell , 204 bytes

Minha tentativa com Haskell, infelizmente não fui capaz de torná-lo mais 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

Experimente online!

Explicações:

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

Você pode dar uma olhada em nossas dicas para jogar golfe em Haskell . Por exemplo, where m=b-xpode ser colocado em um guarda: |m<-b-x=.
— Laikoni

Você pode perder o lambda e um conjunto de parênteses, reorganizando alguns parâmetros: main=putStr=<<q"A "10"B "10.randomRs(1,6::Int)<$>getStdGen. Você também pode usar uma lista e concatê-la para se livrar da redefinição (++). O último onde não parece ser benéfico usar apenas em b-xqualquer lugar.
— Angs 29/03

1

Julia 0,6 , 175 bytes

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

Experimente online!

Versão longa e não destruída:

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

Parece não haver nenhuma saída no seu link TIO.
— AJFaraday

Sim, eu não sei por que tio não gosta. Funciona bem na minha máquina. Vou investigar se tiver tempo.
— niczky12

1

VBA, 222 185 179 bytes

Esta solução recursiva envolve 3 subs

  1. g é o começo do jogo que começa na primeira vez
  2. É chamado para cada turno . Ele usa recursão.
  3. p é menor que o Debug.Print quando usado mais de 3 vezes (apenas 4 nesta solução) Edit: Agora que aprendi que Debug.?é uma alternativa aceitável paraDebug.Print , Debug.?xé mais curto do que chamar um Sub para imprimir.
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

Este foi um desafio divertido. Se você conhece um intérprete on-line como o TIO for VB6 / VBScript / VBA, deixe um comentário. Então eu posso postar um link para uma solução funcional.

Se você deseja testar esse código e ter o Microsoft Excel, Word, Access ou Outlook instalado (apenas Windows), pressione Alt + F11 para abrir o IDE do VBA. Insira um novo módulo de código (Alt + I, M) e limpe a opção explícita. Em seguida, cole o código e pressione F5 para executá-lo. Os resultados devem aparecer na janela Imediata (pressione Ctrl + G se você não a vir).

Edit 1: Removido o espaço em branco que o editor VBA adicionará automaticamente. Reduzido em 37 bytes
Edit 2: Remove Sub p () * para salvar 6 bytes depois que o aprendizado Debug.?for uma alternativa aceitável Debug.Print. Chamar um Sub para manipular Debug.?apenas salva bytes após mais de seis chamadas.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.