16
\$\begingroup\$

Craps is a fairly simple dice game often played in casinos. Even if you aren't a gambler (which I'm not), it's still a fairly interesting game. Here's the rules:

At the start of a game of Craps there's what is called the come-out round. The player rolls two d6s (six-sided die) and the two die rolls are added. If the result is 7 or 11, the person automatically wins (this is known as a natural). If the result is 2, 3 or 12 the person automatically loses (this is known as crapping out). Otherwise, the result is set as the point for the point round.

After this, the point round begins. During the point round, the player must continuously roll 2 d6s until the person rolls a 7 or his/her point from the previous round. If the person rolls a 7, they lose. If they roll their point, they win.

Challenge

Implement a simple program that simulates a game of craps. If the person rolls a natural or a crap-out during the come-out round, the program should output "Natural: " or "Crapping out: " followed by the die-roll and then exit. Otherwise, it should output "Point: " followed by the point. Then, during the point round, it should output every die-roll until a 7 or the point is reached. If the person wins, it should output "Pass"; if they lose it should output "Don't Pass".

Reference Implementation

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

Try it online.

Sample outputs

Natural: 7

Crapping out: 3

Point: 9
4
8
11
9
Pass

and

Point: 5
3
7
Don't Pass

This is , so shortest code wins.

(DISCLAIMER: This challenge is not intended to promote gambling in any way. Remember, the house always wins.)

\$\endgroup\$
  • \$\begingroup\$ 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. - What about picking a random value in [1, 12] from a distribution that is identical to adding two uniform random values in [1, 6]? \$\endgroup\$ – Mego Aug 16 '16 at 8:28
  • \$\begingroup\$ @Mego Whoa, old challenge. Yes that would be fine. I think that warning was mostly just to make sure people realized that a uniform distribution between [1, 12] isn't the same as a 2d6. I'll rewrite it a little bit. \$\endgroup\$ – a spaghetto Aug 16 '16 at 15:30
5
\$\begingroup\$

Ruby 164

Pretty straightforward. Interesting features:

The crapping out cases are summarised as r%12<4 and the remaining natural cases are summarised as r%4==3.

The initial string is stored in c and further rolls are taken only if this is later alphabetically than the single letter ?P (which only occurs for 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")
\$\endgroup\$
  • \$\begingroup\$ Love the way how you check for the remainder instead for 2,3,7,11 or 12 seperatly! \$\endgroup\$ – Jeroen Oct 27 '15 at 12:08
6
\$\begingroup\$

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

This is based on Celeo's answer; I replaced some lengthy conditionals with a magic number that encodes a LUT for each number, reused a variable, and did a few other miscellaneous golfs. Still room to golf; it's probably possible to get under 170.

I didn't try to use Python 2, so I don't know if it would be shorter.

\$\endgroup\$
  • \$\begingroup\$ Care to explain how you got that magic number and how it works? \$\endgroup\$ – Karl Napf Aug 16 '16 at 8:44
5
\$\begingroup\$

C99, 366 312 293 277 bytes

This is my first post here, so I'm going to guess that this can be improved by a lot.

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

Expanded Version

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

As you can see, there's a good amount of redundancy here that can most likely be done away with.

Credits to @Mego for helping to make this smaller.

\$\endgroup\$
  • 1
    \$\begingroup\$ As long as it compiles somewhere, you're good. \$\endgroup\$ – lirtosiast Oct 24 '15 at 4:13
  • \$\begingroup\$ @Mego thanks for pointing that out, that managed to get rid of 19 bytes. \$\endgroup\$ – Chris Loonam Oct 25 '15 at 23:11
  • \$\begingroup\$ Got some more off getting rid of a and b and also using the subtraction method along with ternary operators. \$\endgroup\$ – Chris Loonam Oct 26 '15 at 2:42
5
\$\begingroup\$

Python 2, 226 224 bytes

First pass and there's a lot of code there:

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"

Thanks to Mego for 2 bytes!

\$\endgroup\$
  • \$\begingroup\$ Few issues with this. It doesn't print out "Point: " followed by the number if the roll wasn't a natural or a crap. Also, there should be a space between the : and the number. \$\endgroup\$ – a spaghetto Oct 22 '15 at 21:37
  • \$\begingroup\$ Whoops! Fixed not printing 'Point: #'. In the output, there is a space. \$\endgroup\$ – Celeo Oct 22 '15 at 21:43
  • \$\begingroup\$ Ah OK. I don't use Python very much anymore so I was uncertain about how the ,a works. \$\endgroup\$ – a spaghetto Oct 22 '15 at 21:43
  • \$\begingroup\$ I golfed your code down to 198 in Python 3, which is 192 in Python 2. Do you want the suggestions, or should I post my own answer? \$\endgroup\$ – lirtosiast Oct 23 '15 at 2:28
  • \$\begingroup\$ @ThomasKwa If you put a bunch of work into it, post as a separate answer so you can get some rep for it. \$\endgroup\$ – Celeo Oct 23 '15 at 15:37
3
\$\begingroup\$

PHP 230 228 218 199 192 188 Bytes

186 bytes without the <?

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

First attempt at code golf! Not sure if using </br> would be allowed though? As this would not work in a console (as a new line). Let me know if this is not allowed and will alter my code.

EDIT (16-8-16): After getting better at codegolf I noticed some possible improvements. This still works using the command line interface. Replaced </br> with an hard enter.

\$\endgroup\$
  • \$\begingroup\$ Natural is spelt "Natural" and not "Naturel". \$\endgroup\$ – Cows quack Oct 27 '15 at 12:08
  • \$\begingroup\$ Changed it. Thanks \$\endgroup\$ – Jeroen Oct 27 '15 at 12:26
2
\$\begingroup\$

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)}}
\$\endgroup\$
0
\$\begingroup\$

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")
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.