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.