6
\$\begingroup\$

When you roll a die, you have a 6:1 chance of any given option.

There's a bookmaker taking bets on die rolls. He owns £20 at the start of the game.

The bookmaker offers odds of 4:1, but gamblers take it, because there's money on offer.

There are 10 gamblers. A, B, C, D, E, F, G, H, I, and J. Each gambler owns 10 pounds sterling.

Each round, the 10 gamblers each bet £1 on a die roll, if they have any money left.

  • If they win their bet, £4 is transferred from the bookmaker to the gambler.
  • If they lose, £1 is transferred from the gambler to the bookmaker.

The game ends in either of these conditions:

  • The bookmaker runs out of money, or is in debt.
  • All of the gamblers have run out of money.

We should see the result presented as a series of tables, like so:

Turn 1
Roll: 2

|                | Bookie | A  | B  | C  | D  | E  | F  | G  | H  | I  | J  |
| Start money    | 20     | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 10 |  
| Bet            | n/a    | 1  | 3  | 2  | 1  | 2  | 4  | 6  | 5  | 2  | 4  |
| Balance change | -2     | -1 | -1 | +3 | -1 | +3 | -1 | -1 | -1 | +3 | -1 |
| End money      | 18     | 9  | 9  | 13 | 9  | 13 | 9  | 9  | 9  | 13 | 9  |

Turn 2
Roll: 4

|                | Bookie | A  | B  | C  | D  | E  | F  | G  | H  | I  | J  |
| Start money    | 18     | 9  | 9  | 13 | 9  | 13 | 9  | 9  | 9  | 13 | 3  |  
| Bet            | n/a    | 1  | 2  | 3  | 4  | 5  | 6  | 1  | 2  | 3  | 4  |
| Balance change | +2     | -1 | -1 | -1 | +3 | -1 | -1 | -1 | -1 | -1 | +3 |
| End money      | 20     | 8  | 8  | 12 | 8  | 12 | 8  | 8  | 8  | 12 | 12 |

When a gambler runs out of money, they can't bet any more. Their bet is 0.

turn 20 roll: 5

|                | Bookie | A  | B  | C  | D  | E  | F  | G  | H  | I  | J  |
| Start money    | 180    | 3  | 1  | 12 | 4  | 0  | 1  | 3  | 6  | 23 | 1  |  
| Bet            | n/a    | 1  | 2  | 3  | 4  | 0  | 6  | 1  | 2  | 3  | 4  |
| Balance change | +2     | -1 | -1 | -1 | +3 | 0  | -1 | -1 | -1 | -1 | +3 |
| End money      | 20     | 8  | 8  | 12 | 8  | 0  | 8  | 8  | 8  | 12 | 12 |

Write some code to model this game, and display the results in a table:

  • Use any language
  • The gamblers can change their bet each turn, always bet on the same number, all bet on the same number. As long as each turn they bet on one number from 1 to 6.
  • The die roll must be a random integer from 1 to 6. Use a typical, vernacular definition of random.
  • The end money from one turn is the start money of the next turn.
  • The balance change for the bookie is the sum of the other balance changes.
  • Each turn your program should output:
    • Which turn we are on
    • The resulting die roll
    • The starting balance, die roll, balance change, and ending balance for the bookie and all ten gamblers, as an ascii table.
  • Attempt to do so in the fewest bytes.
\$\endgroup\$
  • 1
    \$\begingroup\$ I'm assuming we take no input, and I'm assuming we have to use random for the dice-rolls and bets each round? Also, how does a round look when some of the gamblers have run out of money? \$\endgroup\$ – Kevin Cruijssen Aug 8 '18 at 9:24
  • \$\begingroup\$ @KevinCruijssen useful questions, as ever :) I said it’s fine for the gamblers to always bet the same way, the die roll has to be random™️. I’ll add a broke gambler table. \$\endgroup\$ – AJFaraday Aug 8 '18 at 9:43
  • \$\begingroup\$ Does the table need to be formatted exactly as shown in the post, or does it just need to be a legible table of results? \$\endgroup\$ – Skidsdev Aug 8 '18 at 10:07
  • \$\begingroup\$ Not to be a pain, but 3:1 odds would mean either £3 bookie->punter or £1 punter->bookie. As written, when I win I bet £1 but don't pay, then get £4 back... \$\endgroup\$ – Phil H Aug 8 '18 at 10:17
  • 1
    \$\begingroup\$ @AJFaraday the only issue is it says 3:1 but the rules actually are 4:1, just change the post to say 4:1 \$\endgroup\$ – Skidsdev Aug 8 '18 at 10:38
8
\$\begingroup\$

JavaScript (Node.js), 548 516 511 485 453 397 396 392 372 325 323 260 bytes

f=(i=!(b=20,p=10))=>b*p>0?`T:${++i} R:${(r=0|Math.random()*6)+1}
|   |Book|A |B |C |D |E |F |G |H |I |J |
|Stt${(d=(n,s)=>`|${n}`.padEnd(5)+`|${s}`.padEnd(3).repeat(10)+`|
`)(b,p)}|Bet${d('n/a',1)}|Chg${d(u=r?'+10':-40,v=r?-1:'+4')}|End`+d(b+=+u,p+=+v)+f(i):''

Try it online!

-32 something bytes by shortening row labels. Also fixed the dice roll being 0-5, not 1-6
-5 bytes by compacting output format
-26 bytes because padding
-32 bytes because whitespace is the devil
-56 bytes thanks to ASCII-only and Luis Felipe in chat
-1 byte because return x doesn't need to be on a new line
-4 bytes thanks to some small refactors from ASCII-only
-20 bytes thanks to more collaboration in chat and some changes by Kevin Cruijssen
-47 bytes because y was the devil and ASCII-only performed an exorcism
-2 bytes because ASCII-only is a golfing machine
-63 bytes thanks to the work of several people in the comments

The golf I took was calculated, but man am I bad at golf.

Almost looks like python rather than JS because where possible I used newlines in place of semicolons for readability.

All gamblers always bet on 1, so we only need to store 1 gambler balance (p), the bookie's balance is b.

Explanation time

I need to rewrite the explanation to match the 260 byte version, but check the revision history for the lengthy explanation of the 323 byte version.

\$\endgroup\$
  • \$\begingroup\$ Hmmm, I might have made a model where the house always loses... \$\endgroup\$ – AJFaraday Aug 8 '18 at 10:39
  • \$\begingroup\$ @AJFaraday it does seem like the bookie loses most of the time. Longest game I've seen was a 25 round game where the bookie won though, so that's nice \$\endgroup\$ – Skidsdev Aug 8 '18 at 10:53
  • \$\begingroup\$ also @AJFaraday let me know if at any point my format compression becomes too much and the table isn't table-y enough \$\endgroup\$ – Skidsdev Aug 8 '18 at 10:56
  • \$\begingroup\$ That's fine with me. It's recognisably a table \$\endgroup\$ – AJFaraday Aug 8 '18 at 10:59
  • \$\begingroup\$ Admittedly the format will break if the players hit triple digit balance, or the bookie hits 5 digit balance, but both are impossible due to the nature of the game \$\endgroup\$ – Skidsdev Aug 8 '18 at 11:00
3
\$\begingroup\$

Charcoal, 248 bytes

≔²⁰θ≔EχχηW∧›θ⁰⌈η«Turn: IL⊞Oυω⸿Roll: ≔⊕‽⁶ζIζ”{⧴&DCZJW›B↨⊘KBgU→≦”⪫…αχ |  ﹪ |⸿| Start  |%7d |θ⪫Eη◧Iκ³ |≔Eη∧κ⊕‽⁶ε”{➙∧➙⌈℅⎇/s?↨Vp2S>”⪫ε |  ≔⁻LΦεκ×⁴LΦε⁼κζδ |⸿| Change |◧⁺…+›δ⁰δ⁷ | ⪫Eε⎇⁼κζ+3⎇κ-1⁺ ⁰ | ≦⁺δθ﹪ |⸿| End    |%7d |θUMη⁻κ∧§ελ∨¬⁼§ελζ±³⪫Eη◧Iκ³ |¦ |⸿⸿

Try it online! Link is to verbose version of code. Explanation:

≔²⁰θ

The bookie starts with £20.

≔Eχχη

Create an array of 10 £10s for the gamblers.

W∧›θ⁰⌈η«

Repeat the rest of the program while the bookie and at least one gambler have any money left.

Turn: IL⊞Oυω

Print the current turn by pushing a value to the predefined empty list and taking the resulting length.

⸿Roll: ≔⊕‽⁶ζIζ

Generate and print the next roll.

”{⧴&DCZJW›B↨⊘KBgU→≦”⪫…αχ

Print the header row.

 |  ﹪ |⸿| Start  |%7d |θ⪫Eη◧Iκ³ |

Print the starting balances.

≔Eη∧κ⊕‽⁶ε

Generate the 10 bets (or 0 if the gambler has no money left).

”{➙∧➙⌈℅⎇/s?↨Vp2S>”⪫ε |  

Print the bets.

≔⁻LΦεκ×⁴LΦε⁼κζδ

Calculate the bookie's change in balance.

 |⸿| Change |◧⁺…+›δ⁰δ⁷ | ⪫Eε⎇⁼κζ+3⎇κ-1⁺ ⁰ | 

Print the bookie's and gamblers' changes in balance.

≦⁺δθ﹪ |⸿| End    |%7d |θ

Update and print the bookie's balance.

UMη⁻κ∧§ελ∨¬⁼§ελζ±³⪫Eη◧Iκ³ |¦ |⸿⸿

Update and print the gamblers' balances.

\$\endgroup\$
2
\$\begingroup\$

Kotlin, 468 432 bytes

I'm definitely going to try this another way as I'd like it to be around 300. However, it works. Player 1 wins by magically always picking the winning number.
-36 bytes for various golfs I missed last night including @Mayube's fixed bet on 1,

{var o=""
val n=Random()
val m=Array(11){10}
m[0]=20
var t=0
val f={d:Int->o+="%3d|".format(d)}
while(m[0]>0){val b=Array(11){1}
b[1]=n.nextInt(6)+1
val c=Array(11){when{it<1||m[it]<1->0
b[1]==b[it]->3
else->-1}}
o+="\nT:${++t} R:${b[1]}\n|   |Bok|"
('A'..'J').map{o+=" $it |"}
o+="\n|Stt|"
m.map{f(it)}
o+="\n|Bet|n/a|"
(1..10).map{f(b[it])
c[0]-=c[it]}
o+="\n|Chg|"
(0..10).map{f(c[it])
m[it]+=c[it]}
o+="\n|End|"
m.map{f(it)}}
o}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

R 417 bytes

g=function(){s=sample
d=10
m=t(matrix(c(20,rep(d,d),NA,s(6,d,T)),11,4,di=list(c("Book",LETTERS[1:d]),c("Stt","Bet","Chg","End"))))
i=1
u=which
while(m[1,1]!=0){
if(m[1,1]==120)break
w=s(6,1)
l=m[1,]!=0
o=m[2,]==0
m[3,u(o&l)]=3
m[3,u(!o&l)]=-1
m[3,u(m[1,]==0)]=0
m[3,1]=-sum(m[3,2:11],na.rm=T)
m[4,]=colSums(m[c(1,3),])
print(kable(m,ca=paste0("T:",i," R:",w),format="pandoc"))
m[1,]=m[4,]
m[2,]=c(NA,s(6,d,T))
i=i+1}}

Explanation:

I was going to post a while ago, but my first attempt was at about 600, after some effort, I whittled it down to 500. After more research, I slowly got down to this result. I'm open to advice regarding better methods.

NOTE: R has a package known as knitr which utilizes the kable function to create tables with various formats (Latex, HTML, pandoc, etc). Each player makes a random guess every turn. Most games end between 26 and 200 or so turns, with the bookie winning every game. Also, variable name choice has little reasoning, I just tried to avoid using builtins as variable names.

g=function(){s=sample          # Abbreviate sample function
d=10                           # Store 10
m=t(matrix(c(20,rep(d,d),NA,s(6,d,T)),11,4,di=list(c("Book",LETTERS[1:d]),c("Stt","Bet","Chg","End"))))      
                               # Creates a 11x4 matrix, populates it, names it's columns and rows, and transposes it.
i=1                            # Turn Counter
u=which                        # Abbreviate the which function that tests values to be equivalent to a chosen values
while(m[1,1]!=0){              # While loop with condition on the bookie not having 0 pounds
if(m[1,1]==120)break           # Loop stops if bookie reaches 120 pounds, total
w=s(6,1)                       # Bookie Dice Roll/Winning Die Value
l=m[1,]!=0                     # Check if total pounds of each player equals 0
o=m[2,]==w                     # Check if players choices matches the winning roll
m[3,u(o&l)]=3                  # If guess is correct, and current wages is not 0, store 3
m[3,u(!o&l)]=-1                # If guess is incorrect, and current wages is not 0, store -1
m[3,u(m[1,]==0)]=0             # If current wages is 0, store 0
m[3,1]=-sum(m[3,2:11],na.rm=T) # Add up players totals to get the change to the bookies total
m[4,]=colSums(m[c(1,3),])      # Add the old total to the change
print(kable(m,ca=paste0("T:",i," R:",w),format="pandoc"))   #Print the table with title
m[1,]=m[4,]                    # Store last row in first row
m[2,]=c(NA,s(6,d,T))           # Store new guesses in second row
i=i+1}}                        # Add to the turn counter
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 407 406 397 bytes

Each of the gamblers chooses a random number and then always bets on that value.

Thanks to ceilingcat for the suggestions.

#define l(a,b)for(i=11,a;i--;b)
#define p printf
#define q p("%d"s,a[i])
#define z(a)p("\n| "#a s)
#define s"\t| "
a[11],b[11];r,t,i,j,k;f(){l(0,b[i]=i?rand()%6:0)a[i]=10*-~!i;for(t=0;++t;){l(p("\n\nTurn %d\tRoll: %d\n|"s,t,r=rand()%6),p(i?"%c"s:"Book"s,75-i));l(z(Start),q);l(z(Bet),p(i?"%d"s:"-"s,1+b[i]));l(k=!z(Chg),p("%+d"s,i?j:k))k-=j=i?4-5*b[i]!=r:0,*a-=j,a[i]+=j;l(z(End),a[i]||(t=-1))q;}}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Suggest ~9*~!i instead of 10*-~!i and t=a[i]?t:-1 instead of a[i]||(t=-1) \$\endgroup\$ – ceilingcat Sep 6 '18 at 20:11

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.