Simule um jogo de Craps

18

Craps é um jogo de dados bastante simples, geralmente jogado em cassinos. Mesmo se você não é um jogador (o que eu não sou), ainda é um jogo bastante interessante. Aqui estão as regras:

No início de um jogo de Craps, há o que é chamado de rodada final. O jogador joga dois d6s (dado de seis lados) e os dois dados do dado são adicionados. Se o resultado for 7 ou 11, a pessoa vence automaticamente (isso é conhecido como natural ). Se o resultado for 2, 3 ou 12, a pessoa perde automaticamente (isso é conhecido como porcaria ). Caso contrário, o resultado será definido como o ponto para a ronda de pontos.

Depois disso, a rodada de pontos começa. Durante a rodada de pontos, o jogador deve rolar continuamente 2 d6s até que a pessoa gere 7 ou seu ponto da rodada anterior. Se a pessoa obtiver 7, eles perderão. Se eles argumentarem, eles vencem.

Desafio

Implemente um programa simples que simule um jogo de craps. Se a pessoa fizer uma rolagem natural ou porcaria durante a rodada de saída, o programa deve exibir "Natural:" ou "Crapping out:", seguido pela rolagem e depois sair. Caso contrário, ele deve gerar "Ponto:" seguido pelo ponto. Então, durante a rodada de pontos, ele deve gerar todos os dados até que um 7 ou o ponto seja alcançado. Se a pessoa vencer, deve produzir "Pass"; se eles perdem deve sair "Don't Pass".

Implementação de referência

Groovy, 277 bytes

def a={return Math.random()*6+1};int b=a()+a();(b<4||b==12)?{println"Crapping out: "+b}():{(b==7||b==11)?{println"Natural: "+b}():{println"Point: "+b;for(;;){int x=a()+a();println x;(x==7)?{println"Don't Pass";System.exit(0)}():{if(x==b){println"Pass";System.exit(0)}}()}}()}()

Experimente online.

Saídas de amostra

Natural: 7

Crapping out: 3

Point: 9
4
8
11
9
Pass

e

Point: 5
3
7
Don't Pass

Isso é , então o código mais curto vence.

(AVISO LEGAL: Este desafio não se destina a promover o jogo de forma alguma. Lembre-se de que a casa sempre vence.)

um spaghetto
fonte
You can't make your program shorter by picking a random number between 1 and 12 for the die roll; it must be two numbers picked between 1 and 6.- Que tal escolher um valor aleatório em [1, 12] de uma distribuição idêntica à adição de dois valores aleatórios uniformes em [1, 6]?
Mego
@Mego Whoa, velho desafio. Sim, isso seria bom. Eu acho que esse aviso foi principalmente para garantir que as pessoas percebessem que uma distribuição uniforme entre [1, 12] não é a mesma que uma 2d6. Vou reescrevê-lo um pouco.
um spaghetto

Respostas:

6

Ruby 164

Bem direto. Recursos interessantes:

Os casos de descarte são resumidos como r%12<4e os demais casos naturais são resumidos como r%4==3.

A sequência inicial é armazenada ce outros rolos são obtidos apenas se for posterior em ordem alfabética à letra única ?P(o que ocorre apenas para Point.)

f=->{rand(6)+rand(6)+2}
s=0
r=f[]
print c=r%12<4?'Crapping out':r%4==3?'Natural':'Point',": #{r}
"
c>?P&&(until s==r||s==7
p s=f[]end
print s==7?"Don't ":"","Pass")
Level River St
fonte
Adore a maneira como você verifica o restante em vez de 2,3,7,11 ou 12 separadamente!
Jeroen
6

Python 3, 190 bytes

from random import*
r=randrange
p=print
a=r(5)+r(5)+2
c=890145//3**a%3
p(['Point:','Crapping out:','Natural:'][c],a)
if c<1:
 while 7!=c!=a:c=r(5)+r(5)+2;p(c)
 p(['Pass',"Don't pass"][c==7])

Isso é baseado na resposta de Celeo ; Substituí alguns condicionais longos por um número mágico que codifica uma LUT para cada número, reutilizei uma variável e fiz alguns outros golfe diversos. Ainda espaço para jogar golfe; provavelmente é possível ter menos de 170 anos.

Eu não tentei usar o Python 2, então não sei se seria mais curto.

lirtosiast
fonte
1
Importa-se de explicar como você conseguiu esse número mágico e como ele funciona?
Karl Napf
5

C99, 366 312 293 277 bytes

Este é o meu primeiro post aqui, então acho que isso pode ser melhorado muito.

#include<stdlib.h>
#include<time.h>
#define r rand()%6+1
#define p printf(
main(c,s){srand(time(0));s=r+r;int*a=s==7||s==11?"Natural:%d":2-s||3-s||12-s?0:"Crapping out:%d";if(a){p a,s);return 0;}p"Point:%d\n",c=s);do p"%d\n",s=r+r);while(7-s&&s-c);p(7-s)?"Pass":"Don't pass");}

Versão expandida

#include<stdlib.h>
#include<time.h>
#define r rand()%6+1
#define p printf(
main(c,s){
    srand(time(0));
    s=r+r;
    int*a=s==7||s==11?"Natural:%d":2-s||3-s||12-s?0:"Crapping out:%d";
    if(a) {p a,s);return 0;}
    p"Point:%d\n",c=s);
    do p"%d\n",s=r+r);
    while(7-s&&s-c);
    p(7-s)?"Pass":"Don't pass");
}

Como você pode ver, há uma boa quantidade de redundância aqui que provavelmente pode ser eliminada.

Créditos ao @Mego por ajudar a torná-lo menor.

Chris Loonam
fonte
1
Contanto que compile em algum lugar, você é bom.
lirtosiast
@Mego obrigado por apontar isso, que conseguiu se livrar de 19 bytes.
Chris Loonam
Tenho um pouco mais fora se livrar de ae be também usando o método de subtracção junto com ternários operadores.
Chris Loonam 26/10/2015
5

Python 2, 226 224 bytes

Primeira passagem e há muito código lá:

from random import*
r=randrange
a=r(5)+r(5)+2
if a in[7,11]:print'Natural:',a
elif a in[2,3,12]:print'Crapping out:',a
else:
 print'Point:',a
 b=0
 while b not in[7,a]:b=r(5)+r(5)+2;print b
 print'Pass'if b-7else"Don't pass"

Obrigado ao Mego por 2 bytes!

Celeo
fonte
Poucos problemas com isso. Não imprime "Ponto:" seguido do número se o rolo não for natural ou uma porcaria. Além disso, deve haver um espaço entre o: e o número.
a spaghetto
Ops! Corrigido não imprimindo 'Point: #'. Na saída, há um espaço.
Celeo
Ah ok. Eu não uso muito mais o Python, por isso não tinha certeza de como isso funciona.
a spaghetto
Programei seu código até 198 no Python 3, que é 192 no Python 2. Você quer as sugestões ou devo postar minha própria resposta?
lirtosiast
@ThomasKwa Se você colocar um monte de trabalho nele, poste como uma resposta separada para que você possa obter algum representante.
Celeo
3

PHP 230 228 218 199 192 188 bytes

186 bytes sem o <?

<?$a=rand(1,6)+rand(1,6);$a%4==3?die("Natural: $a"):$a%12<4?die("Crapping out: $a"):print"Point: $a
";while(1){($b=rand(1,6)+rand(1,6))==7?die("Don't Pass"):$b==$a?die("Pass"):print"$b
";}

Primeira tentativa de código de golfe! Não tem certeza se o uso </br>seria permitido? Como isso não funcionaria em um console (como uma nova linha). Deixe-me saber se isso não é permitido e irá alterar meu código.

EDIT (16-8-16): Depois de melhorar no codegolf, notei algumas melhorias possíveis. Isso ainda funciona usando a interface da linha de comandos. Substituído </br>por um disco rígido.

Jeroen
fonte
Natural está escrito "Natural" e não "Naturel".
Kritixi Lithos 27/10/2015
Mudou isso. Obrigado
Jeroen
2

Javascript 262

var r=(x=>Math.floor(Math.random()*6+1)),a=r()+r();if(a<4||a==12){alert("Crapping out: "+a)}else if(a==7||a==11){alert("Natural: "+a)}else{alert("Point: "+a);while(1){var b = r()+r();if(b==a){alert("pass");break}if(b==7){alert("dont't pass");break}alert(""+b)}}
user902383
fonte
1

Perl 5 , 140 bytes

sub d{1+int rand 6}say$"=($p=&d+&d)%12<4?"Crapping out":$p%4-3?Point:Natural,": $p";if($"gt O){say$_=&d+&d until/7|$p/;say"Don't "x/7/,Pass}

Experimente online!

Xcali
fonte
1

PowerShell , 181 183 179 178 167 167 165 bytes

-10 bytes graças ao mazzy
-2 bytes graças ao Xcali

switch -r($z=&($x={(random 6)+(random 6)+2})){'7|11'{"Natural: $z"}'2|3'{"Crapping out: $z"}default{"Point: $z"
do{($m=&$x)}until($m-in7,$z)"Don't "*!($m-7)+'Pass'}}

Experimente online!

Versão desenrolada:

#Switch using regex on $z which is...
#&($x={...}) first assigns $x to a scriptblock then calls it, saving the return to $z
switch -r($z=&($x={(random 6)+(random 6)+2})){
    '7|11' {"Natural: $z"}
    '2|3' {"Crapping out: $z"}
    default{
        "Point: $z"

        #Call the diceroll scriptblock until you Pass,
        #while pushing each roll to output
        do{($m=&$x)}
        until($m-in7,$z)
        "Don't "*!($m-7)+'Pass'
    }
}

Existem alguns pontos menos difíceis agora que a lógica de construção da lista foi reconstruída em um switch. Eu acho que ainda é uma abordagem muito boa. +2 bytes corrigindo um erro.

Veskah
fonte
1
impressionante! encurtá-lo até 178 bytes
Mazzy
Eu acho que a condição -notin (7,$z)não é relevante para a regra During the point round, the player must continuously roll ... the previous round. Agora o loop termina quando $mé igual a 7ou na primeira rodada.
mazzy
1
@mazzy Essa é uma questão de redação na pergunta. Há apenas duas rodadas. Você define o ponto apenas uma vez na Come-outrodada e esse é o seu número alvo para toda a Pointrodada. O previous roundrefere-se à Come-outrodada
Veskah
1
obrigado. 168 bytes
mazzy
2
Você poderá tirar mais dois, removendo o 1?regex do seu craps.
Xcali 6/06
0

R, 197 bytes

 r=sum(sample(6,2,T));if(r%%12<4)cat("Crap Out",r)else if(r%%4==3)cat("Natural",r)else{cat("Point",r);while(T){cat("",q<-sum(sample(6,2,T)));if(q==7){cat(" Don't");break};if(q>r)break};cat(" Pass")}

Ungolfed

r=sum(sample(6,2,T))
if (r%%12<4)  {
    cat("Crap Out",r) 
} else if (r%%4==3) {
    cat("Natural",r)
} else { 
    cat("Point",r)
    while (T) {
        q = sum(sample(6,2,T))
        cat("",q)
        if (q==7) {
            cat(" Don't")
            break
        }
        if (q>r) break
    }
    cat(" Pass")
}
user5957401
fonte
0

Pitão , 108 bytes

p|K?}J+OS6OS6,7 11"Natural"?}J[2 3 12)"Crapping out"k"Point"+": "JI!KW!}Z,7JIq7=Z
+OS6OS6=K"Don't "))+K"Pass

Experimente online!

Primeira passagem, provavelmente pode encontrar algumas economias.

Sok
fonte
0

Encantos Rúnicos , 151 bytes

R}}6'RA6'RA2++{{B͍
00B:7=S:b={+?\"Natural: "@>
pping out: "@\:2=}:3=}:c={{++?/"Cra
{:}≠   ?\ 6?;$$k\/ak$00B:$:7≠?\
"Don't "R"Pass"a/\$:$" :tnioP"\

Experimente online!

Depois de corrigir um erro referente a números aleatórios (era repetido sempre 'RA repetida era chamado e a semente era hora do sistema, resultando em execuções massivas de valores repetidos), isso funciona corretamente.

Explicação

A entrada está na segunda linha, como a primeira linha até é uma função para rolar dois dados e somar.

Fluxo do programa, com alguns redirecionamentos de quebra de borda e enrolados desenrolados para facilitar a leitura

   R}}6'RA6'RA2++{{B͍                      Roll 2, sum, return
   >00B:7=S:b={+?\                        Entry, make first roll, compare to 7 and 11.
                  "Natural: "@            If true, print "Natural: " and the value, else go down
                 \:2=}:3=}:c={{++?/       Compare to 2, 3, and 12.
"Crapping out: "@                         If true, print "Crapping out: " and the value, else go up
                     \$:$" :tnioP"\       Print "Point: " and value (IP is travelling RTL)
                     /ak$00B:$            Print newline, roll, print
:7≠?\                                     Compare to 7
    \"Don't "R"Pass"ak$$;                 If equal, print a newline and "Don't Pass"
     {:}≠   ?\                            Else compare to initial roll.
             R"Pass"ak$$;                 If equal, print a newline and "Pass"
              6?......ak$00B              Else return to roll loop by printing a newline
                                              and rolling again (. are skipped instructions)

Existem apenas 4 instruções NOP ( {:}≠...?\.6?) que seriam muito difíceis de remover devido ao espaço necessário em outras linhas (ou seja, o comprimento da "Don't "string).

Draco18s
fonte