CrapR - A Craps Simulator in R Markdown

CrapR is an R Markdown based simulator for the Casino dice game of Craps. Many gambling “strategy” sites claim to provide Craps strategies and ways to win more money using complex named strategies with fancy sounding names like the “Iron Cross”. However, since the game of craps is a game of pure chance, and since the casino ALWAYS has the edge (just like every casino game) then that means that the expected value is negative. And if you are familiar with statistics - you know that means only one thing - that the law of large numbers always wins in the end, and a game with a negative expected value will always emean that you LOSE in the end. So, the best strategy is to not play… But that’s not much fun!

Instead, using this simulator, you can try out different strategies, and unlike the “Magical thinking” that seems to dominate in this game about “hot tables”, you can see which strategies might actually work for short term vs long term play. These are offered not as a way to “win big” as many youtube videos would falsely lead you to believe is possible- but rather, to lose the least over the long term, and have a chance to win over a short term, with a limited number of rolls, in a single session of play.

So, that being said, let’s look at how the game of craps can be modeled in R and built into a looping function, in which you can run X trials of N rolls and view a summary and timeseries outcome of each trial at the end. Since the rules of this game are fairly complicated, there are abundant comments in the code that should help you understand why certain bets are placed at certain times, the state of the table changes depending on the last roll, and what the bet limits, payouts and odds are for various bets that are available.

Hopefully after seeing the rather complex nature of this game, you will have some ideas about how to use R to model other games and create simulations for other games of chance that might be less (or more) complex than Craps!

Environment Setup

Load packages used by this analysis project and set the default to standard notation.

#this process may take a while...
if(!require(dplyr)) install.packages("dplyr", repos = "http://cran.us.r-project.org")
if(!require(ggrepel)) install.packages("ggrepel", repos = "http://cran.us.r-project.org")
if(!require(tidyverse)) install.packages("tidyverse", repos = "http://cran.us.r-project.org")
if(!require(caret)) install.packages("caret", repos = "http://cran.us.r-project.org")
if(!require(dslabs)) install.packages("dslabs", repos = "http://cran.us.r-project.org")
if(!require(lubridate)) install.packages("lubridate", repos = "http://cran.us.r-project.org")
if(!require(gtools)) install.packages("gtools", repos = "http://cran.us.r-project.org")
if(!require(magick)) install.packages("magick", repos = "http://cran.us.r-project.org")


library(dplyr)
library(ggrepel)
library(tidyverse)
library(dslabs)
library(caret)
library(dslabs)
library(lubridate)
library(gtools)
library(magick)

options(scipen = 999)

Initialize the Simulator

Set up the initial starting conditions of the simulation:

House Odds Rules

Most Las Vegas casinos limit odds bets to 3-4-5x the pass line.

However, you may alter these rules to change the max odds allowed.

The array below is the max odds allowed for each of the points 4,5,6,8,9,10

The highest odds allowed in any casino is 100x the pass line, which would be c(100,100,100,100,100,100)

#rule
#max_odds <- c(10,10,10,10,10,10)
max_odds <- c(3,4,5,5,4,3)

Craps Rules

The general flow of a craps game is a bit complex to learn, but once you understand some key concepts, you can start to make choices about which bets to place, at what time. Each round of play consists of players placing their bets, the shooter rolling two dice, and the dealer paying on winning bets and collecting money on losing bets.

Craps Number Theory

Understanding Craps requires understanding combinations & permutations. The most important mathematical concept in craps is the multiplication principle of counting.

The Multiplication Principle of Counting

When completing a sequence of choices, there are \(p\) choices for the first, \(q\) for the second, \(r\) for the third, and so on, then the multiplication principle of counting may be used to determine how many different ways \(D\) that this sequence can be completed.

This formula holds that: \(D = p \cdot q \cdot r ...\)

How this applies to craps is that you have two dice, with six sides each. Lets calculate how many possible outcomes that will produce.

#set a series of choices that can be combined
choices <- c(6,6)

#the total will multiple each choices following the first, by the sum of all prior products
total <- choices[1]
for (x in choices[-1]){
  total <- total * x
}

# result
result <- paste("When one dice with ", choices[1]," sides, and a second dice with ", choices[2]," sides, a total of ",total," possible combinations could be rolled.",sep="")
result
## [1] "When one dice with 6 sides, and a second dice with 6 sides, a total of 36 possible combinations could be rolled."

Listing the Permutations

SInce many of teh rolls in craps are based on a specific combination of the two dice we really need to consider permutations - - so we have to think oif each of th two dice as distinct entities. So for this exercise we will consider the dice as “right” and “left”. SO for example, we could roll a 1 on the right, and a 2 on the left, which is different than rolling a 2 on the right and a 1 on the left. The reason this matters, is that your odds of winning are directly tied to how many ways you could roll one of the possible totals.

Tip: The gtools package contains some useful features related to permutations including the permutations function. This function will return a frame of all possible permutations of r objects from n possibilities, with options for repetition. In the case of a dice roll, repetition must be allowed - because rolling a 6 on the left, does not preclude the possibility that you will also roll a 6 on the right.

# all permutations of 2 objects selected from 6 possibilities
n <- 6
r <- 2
perms <- permutations(n = n, 
                      r = r, 
                      repeats.allowed=TRUE)

perms
##       [,1] [,2]
##  [1,]    1    1
##  [2,]    1    2
##  [3,]    1    3
##  [4,]    1    4
##  [5,]    1    5
##  [6,]    1    6
##  [7,]    2    1
##  [8,]    2    2
##  [9,]    2    3
## [10,]    2    4
## [11,]    2    5
## [12,]    2    6
## [13,]    3    1
## [14,]    3    2
## [15,]    3    3
## [16,]    3    4
## [17,]    3    5
## [18,]    3    6
## [19,]    4    1
## [20,]    4    2
## [21,]    4    3
## [22,]    4    4
## [23,]    4    5
## [24,]    4    6
## [25,]    5    1
## [26,]    5    2
## [27,]    5    3
## [28,]    5    4
## [29,]    5    5
## [30,]    5    6
## [31,]    6    1
## [32,]    6    2
## [33,]    6    3
## [34,]    6    4
## [35,]    6    5
## [36,]    6    6

So based on the table above we can now see what are the 36 ways that two 6-sided dice can be rolled. We will sort the possile row sums to see how may ways each sum could be rolled.

total_perms <- nrow(perms)
total_perms
## [1] 36

As expected - The lowest possible roll is:

min_rowsum <- min(rowSums(perms))
min_rowsum
## [1] 2

And the highest is:

max_rowsum <- max(rowSums(perms))
max_rowsum
## [1] 12

But here is where the essence of the game is - the probability that any of these combinations will be rolled, is different. COnsider another way to look at this list of numbers - by sorting the row sums we can see how many combinations could result in each of the possible ending rolls.

total_rolls <- sort(rowSums(perms))
total_rolls
##  [1]  2  3  3  4  4  4  5  5  5  5  6  6  6  6  6  7  7  7  7  7  7  8  8  8  8
## [26]  8  9  9  9  9 10 10 10 11 11 12

The table function can return the frequency of each possible roll.

all_perms <- as.data.frame(table(total_rolls))
all_perms
##    total_rolls Freq
## 1            2    1
## 2            3    2
## 3            4    3
## 4            5    4
## 5            6    5
## 6            7    6
## 7            8    5
## 8            9    4
## 9           10    3
## 10          11    2
## 11          12    1

And this can be visualized using ggplot.

all_perms %>% ggplot(aes(x=total_rolls,y=Freq, fill=Freq)) + geom_col()

We can now clearly see why 7 is such an important number in craps - Because the greatest number of possible dice rolls will result in a total of 7.

For each number between 2 (the lowest) and 12 (The highest) there are different numbers of chances to hit that specific total.

Available Bets

Before we get too far into strategy, lets examine the craps table itself - since this helps understand what the possible bets are. When you play the game, you are either placing chips on the table directly, or in some cases, asking the dealer to place them for you.

Craps Table

The Button

The dealer uses a button to keep track of the current state of the game. When the state of the game is ON, the WHITE side of the button is up; when the state is OFF the BLACK side is facing up.

Once you determine which state the game is in, you will understand which bets are available to you in that state - and after some practice, you can begin to better understand which bets have the best odds of winning.

At any given time the button must be either ON or OFF. In this simulator, you will always start with the “coming out” roll. This means the the button starts in the OFF state.

Persistent vs One-Time Bets

The best bets in craps are the persistent bets, where you have ore than one roll (usually) to win on one bet. This in contrast to a one time”* bet, where you must roll the number on the very next roll, or you lose your bet.

Good Bets

“There is nothing either good or bad, but thinking makes it so”. - Hamlet

This section will discuss the good bets - these are bets that are considered the most viable bets for strategic play. However, as with every casino game, the expected value, even on good bets, is less than 1, meaning that statistically speaking, you will still lose money on these good bets - just not as quickly as you would when placing bad bets. So “good and bad” are relative terms. But since you are here to learn about Craps - we will assume you want to play a risky game - for that is the nature of gambling - and it will be up to you to crate a strategy that matches your style, risk tolerance, and available funds.

Ultimately, Gambling should always be approached a money losing proposition, and you should only bet money you can afford to lose - but that said, we will consider these the “good bets” first, since they tend to lead to longer play times, and if you enjoy the thrill of the dice roll, the excitement of the table, and the entertainment value of the game - then these are almost certainly the best bets you have available.

Pass Line bet - Persistent

This bet may only be placed when the button is OFF. This is called the “come out” roll. A pass line bet pays even money [1 to 1] if you roll a 7 or 11 when you are coming out. If a 4,5,6,8,9 or 10 is rolled on the come out roll, that number becomes the point. In this simulator, your bet will remain on the pass line, and subsequent rolls of the point will pay out even money.

One the point is set, the button is set to on, and the objective of the game changes. Once the button is on, you are now trying to roll the point again, BEFORE a 7 is rolled. If a 7 is rolled, that is “craps” and you lose your pass line bet and most other “persistent” bets.

Odds Bet - Persistent

Taking the odds bet means that once the point has been set, you are increasing your pass line bet. How much you can bet on the odds is dependent on how much you bet on the pass line, as discussed in the “house odds bet” section above. The odds is a way to improve the expected value of a pass line bet, because it pays better than even money if the point is rolled.

Because the 6 and 8 are more likely to be rolled than a 4,5,9, or 10, these points pay a little less than a 5 or 9, which pay a little less than the 4 or 10. In the initialize section above, the odds bets are set at double your money [2 to 1] when the point is 4 or 10, one and a half time your bet [3 to 2] if the point is 5 or 9, and even money plus 20% [6 to 5] if the point is a 6 or 8.

Come Bet - Persistent

This bet may be placed at any time, even when the button is OFF. The come bet is similar to the Pass line bet. The come bet, like the pass line, pays even money [1 to 1], but and it wins or loses on different rolls, depending on whether the button is ON or OFF.

If the button is OFF, you win if a 7 is rolled, and lose if a 2, 3 or 12 is rolled. If the button is ON - you win if the point (4,5,6,8,9,or 10) is rolled, but lose if a 7 is rolled.

Place Bets - Persistent - May be Removed

Place bets are available when the button is ON (after the come out roll). When playing in a casino, you ask the dealer to place your money on a specified number. You are then betting that that number will be rolled before a 7 is rolled. Similar to the odds bet, the payout is based on which number you are betting on. If you bet on 6 or 8, the payout is seven dollars on a six dollar bet [7 to 6]; if you bet on the 5 or 9, the payout is seven to five [7 to 5] and if you nbet on the 4 or 10, the payout is nine dollars on a five dollar bet [9 to 5]. Because of the way these odds differ - you must bet in increments of $6 on a roll of 6 or 8, and increments of $5 on the others. Place bets may be removed, but most players will place the bet and leave it on the table until a craps roll.

Bad Bets

The following bets are considered bad bets, and are riskier to play. However, in casino play, they can add some fun and excitement to a craps session, because of the simple fact that some of these bets pay at higher ratios, up to 31 to 1 on the most rare and unlikely rolls like twelve (two 6’s) and deuce (two 1’s). However these are not great bets to incorporate into a craps “strategy” because, according to the law of large numbers, over time, you will lose money. Some of these bets are also “one time” bets, so as you might expect your odds of winning on these is much worse than a persistent bet where you have several chances to win without putting more money on the table.

Field Bets - One Time

Field bets are place by the player on to the field bar. This means that you are betting on the next roll being a 2,3,4,9,10,11, or 12. These pay even money [1 to 1] if you roll any number except 2 or 12, which pays double money [2 to 1]. This is not a great bet - because even though it gives you exposure to win on a lot of different numbers - you will lose your bet if any of the most common combinations (6, 7 or 8) is rolled.

Proposition Bets - Persistent or One Time

The proposition bets include several somewhat more complicated bets - sand these are always worse odds than the above discussed bets. We will only discuss these briefly. In short there are two categories- Hardways, which are persistent, and everything else, which are one time bets.

Hardways, once placed, remain on the table until that number is rolled. So a Hard 8, is a just a bet that you will roll a total of 8 “the hard way” before you roll it the “easy way”. (Not that its particularly hard to throw dice!) BUt what this really means, is that you are trying to roll 2 dice and they each come up as a 4. This is the called the hard way, because there is only one combination (4&4) that results in a hard 8. But there are 4 other ways to roll an eight - a 2&6 a 5&3 a 3&5 or a 6&2

All other proposition bets such as horn bets 2,3,11,12, any craps, or seven are one-time bets and you are betting that the very next roll with hit the specific total you chose. So if you place a horn proposition on 12, you chance of hitting is 1 in 36, and your potential payout is 31 to 1.

Exercise: Understanding expected value on proposition bets

To understand the expected value of a one roll bet - you must look at 2 factors-

  1. how many ways you could roll that total
  2. what the payout ratio is for that roll

In the code block below we will create a function that considers the % chance of hitting a 12 vs an 11.

Determining expected value is a fairly simple equation for a one roll bet - you must multiply the decimal which contains the % chance of hitting that number, by the payout offered for hitting it.

Since we have already set the payout on horn bets above, we can use the payouts_on_horn vector. To find the correct EV for each of these proposition bets.

ways_to_roll <- function(target_number){
  all_perms %>% filter(total_rolls == target_number) %>% pull(Freq)
}

chance_value <- function(target_number,total_perms){
chances <- ways_to_roll(target_number)
chance_to_hit <- chances / total_perms
chance_to_hit
}

chance_2 <- chance_value(2,total_perms)
ev_2 <- payouts_on_horn[1] * chance_2
ev_2
## [1] 0.8611111
chance_3 <- chance_value(3,total_perms)
ev_3 <- payouts_on_horn[2] * chance_3
ev_3
## [1] 0.8888889
chance_11 <- chance_value(11,total_perms)
ev_11 <- payouts_on_horn[3] * chance_11
ev_11
## [1] 0.8888889
chance_12 <- chance_value(12,total_perms)
ev_12 <- payouts_on_horn[4] * chance_12
ev_12
## [1] 0.8611111

Note how the expected value of 11 and 12 are the same as for 3 and 2 respectively, since the number of rolls possible to hit a 12 is the same as the number of rolls to to a 2, and the payout on a 12 [31 to 1] is the same as the payout on a roll of 2.

So here isan interesting point; even though the payout of 31 to 1 on a 12 sounds outrageously high compared to other bets - there are fewer ways to roll 12 than 11 - the EV of a 3 or 11 (sometimes called C and E) is slightly higher, assuming 16 to 1 and 31 to 1 odds. If the payout on 12 were exactly double the payout on 11 - the EV would be exactly the same. So always remember to consider the tiny difference in payout that different tables offer - this willassist you in making safer (but still bad) bets!

Any craps bet

One other unusual bet that is available is the “any craps” bet. This bet means that you win if the roller hits a 2, 3, or 12

chance_2 <- chance_value(2,total_perms)
ev_2 <- payouts_on_craps[1] * chance_2
ev_2
## [1] 0.2222222
chance_3 <- chance_value(3,total_perms)
ev_3 <- payouts_on_craps[2] * chance_3
ev_3
## [1] 0.4444444
chance_12 <- chance_value(12,total_perms)
ev_12 <- payouts_on_craps[3] * chance_12
ev_12
## [1] 0.2222222
ev_anycraps <- ev_2 + ev_3 + ev_12
ev_anycraps
## [1] 0.8888889

Once again, for this proposition bet - the actual payout may seem like you have better shot at winning money since there is 3 ways to win… but actually it is EXACTLY the same as a bet on a 3 or 11, because the combined expected value of these 3 possible rolls, is equal to the individual expected value of rolling an 11 or 3.

Seven bet

The final proposition bet we will consider here is the seven bet. This bet, paying out 5 to 1, once again might seem like a good bet, given that there are so many ways to hit the seven. But once again looks can be deceiving. The EV of the seven bet is the lowest of the proposition bets - it only offers a 5 to one payout with 6 ways to roll.

chance_7 <- chance_value(7,total_perms)
ev_7 <- payouts_on_seven[1] * chance_7
ev_7
## [1] 0.8333333

As a rule of thumb, you can multiply the number of ways to roll * the payout to determine the (relative) value of each bet. Even without using a bunch of decimal points, you can see that 3, 11 or any craps are the best proposition bets.

ways_to_roll_2 <- ways_to_roll(2)
ways_to_roll_3 <- ways_to_roll(3)
ways_to_roll_craps <- ways_to_roll(2) + ways_to_roll(3) + ways_to_roll(12)
ways_to_roll_seven <- ways_to_roll(7)
  • 2 or 12 - 1 way * 31 payout = 31
  • 3 or 11 - 2 ways * 16 payout = 32
  • Any Craps - 4 ways * 8 payout = 32
  • Seven - 6 ways * 5 payout = 30

Now that we have explored some of the underlying statistical concepts - we may now build a simulator to explore some of the more complex ideas that might come into play in a craps betting strategy. Although you can calculate the EV for a single throw of the dice - the effective expected value equation becomes more nuanced when you have persistent bets, with multiple chances to hit a number before your bet is lost.

This simulation will help illustrate why certain bets like the odds bets are significantly better than one time bets - as they maximize the expected value of each roll, and, over time, you can actually win some money with these bets rather than just losing over and over, and scratching your head woinderiong why anyone plays this game!

Setting your preferred bet amounts

Set up what amounts you wish to wager on each eligible rule. Every opportunity to place the indicated bet will be taken. Since not all bets can be placed at all times, only the valid bets will occur depending on the current state of the game. The game will always begin in the off state with a come out roll.

# set your preferred bets

# what you wish to bet on the pass line at every opportunity
usual_passline_bet_amount <- 0

# what you wish to bet on the don't pass bar at every opportunity
usual_dontpass_bet_amount <- 5

# what you wish to bet on the pass line odds at every opportunity  (up to the max allowed)
usual_odds_bet_amount <- 0

# what you wish to bet on the don't pass bar odds at every opportunity  (up to the max allowed)
usual_dpodds_bet_amount <- 50

# what you wish to bet on the field bet at every opportunity
usual_field_bet_amount <- 0

# what to bet on each of the hard ways: 4,6,8,10
usual_hard4 <- 0 #pays 8 to 1
usual_hard6 <- 0 #pays 10 to 1
usual_hard8 <- 0 #pays 10 to 1
usual_hard10 <- 0 #pays 8 to 1

# what to bet on each of the proposition bets deuce, three, yo, twelve
usual_proposition2 <- 0 #pays 31 to 1
usual_proposition3 <- 0 #pays 16 to 1
usual_proposition11 <- 0 #pays 16 to 1
usual_proposition12 <- 0 #pays 31 to 1
usual_proposition_craps <- 0 #pays 31 to 1
usual_proposition_seven <- 0 #pays 31 to 1

# what to bet on each of the place bets: 4,5,6,8,9,10
usual_place4 <- 0 #pays 9 to 5 (min $5 bet)
usual_place5 <- 0 #pays 7 to 5 (min $5 bet)
usual_place6 <- 0 #pays 7 to 6 (min $6 bet)
usual_place8 <- 0 #pays 7 to 6 (min $6 bet)
usual_place9 <- 0  #pays 7 to 5 (min $5 bet)
usual_place10 <- 0 #pays 9 to 5 (min $5 bet)

# what you wish to bet on the come bar
usual_come_bet_amount <- 0

# what you wish to bet on the don't come bar
usual_dontcome_bet_amount <- 0

#set BANK
start_bankroll <- 10000

#how may rolls to simulate
rollcount <- seq(1:1000)
trialcount <- seq(1:10)

#compile into a vector
usual_place <- c(usual_place4,usual_place5,usual_place6,usual_place8,usual_place9,usual_place10)
usual_hard <- c(usual_hard4,usual_hard6,usual_hard8,usual_hard10)
usual_prop <- c(usual_proposition2,
                            usual_proposition3,
                            usual_proposition11,
                            usual_proposition12)

#Enter the name of this strategy
#example: "Only Come Bets" or "Iron Cross" or "Just the Hard Ways"
strategy_name <- paste("Don't Pass Line with 10X Odds")

strategy_desc = ""
if(usual_passline_bet_amount > 0){
  strategy_desc = paste(strategy_desc,"Passline:",usual_passline_bet_amount) 
}
if(usual_odds_bet_amount > 0){
  strategy_desc = paste(strategy_desc,"PL Odds:",usual_odds_bet_amount) 
}
if(usual_dontpass_bet_amount > 0){
  strategy_desc = paste(strategy_desc,"Don't Pass:",usual_dontpass_bet_amount) 
}
if(usual_dpodds_bet_amount > 0){
  strategy_desc = paste(strategy_desc,"DP Odds:",usual_dpodds_bet_amount) 
}
if(usual_come_bet_amount > 0){
  strategy_desc = paste(strategy_desc,"Come:",usual_come_bet_amount) 
}
if(usual_field_bet_amount > 0){
  strategy_desc = paste(strategy_desc,"Field:",usual_field_bet_amount) 
}
if(sum(usual_place) > 0){
  strategy_desc = paste(strategy_desc,"Places:",sum(usual_place)) 
}
if(sum(usual_hard) > 0){
  strategy_desc = paste(strategy_desc,"Hardways:",sum(usual_hard)) 
}
if(sum(usual_prop) > 0){
  strategy_desc = paste(strategy_desc,"Propositions:",sum(usual_prop)) 
}

#strategy_desc <- paste("Passline:",usual_passline_bet_amount," Odds:",usual_odds_bet_amount," Come:",usual_come_bet_amount," Field:",usual_field_bet_amount," Places:",sum(usual_place)," Hardways:",sum(usual_hard),"  Propositions:",sum(usual_prop))

Visualize the Table

This code will show the image magick configuration.

str(magick::magick_config())
## List of 24
##  $ version           :Class 'numeric_version'  hidden list of 1
##   ..$ : int [1:4] 6 9 12 3
##  $ modules           : logi FALSE
##  $ cairo             : logi TRUE
##  $ fontconfig        : logi FALSE
##  $ freetype          : logi TRUE
##  $ fftw              : logi TRUE
##  $ ghostscript       : logi TRUE
##  $ heic              : logi TRUE
##  $ jpeg              : logi TRUE
##  $ lcms              : logi TRUE
##  $ libopenjp2        : logi TRUE
##  $ lzma              : logi TRUE
##  $ pangocairo        : logi TRUE
##  $ pango             : logi TRUE
##  $ png               : logi TRUE
##  $ raw               : logi TRUE
##  $ rsvg              : logi TRUE
##  $ tiff              : logi TRUE
##  $ webp              : logi TRUE
##  $ wmf               : logi FALSE
##  $ x11               : logi FALSE
##  $ xml               : logi TRUE
##  $ zero-configuration: logi TRUE
##  $ threads           : int 1

This function generates a table image given a list of bets to be placed and the current state of the table.

getchipcolor <- function(a){
  chipcolor='white'
  if(a>=100){chipcolor='black'}
  if(a<100){chipcolor='purple'}
  if(a<50){chipcolor='blue'}
  if(a<25){chipcolor='green'}
  if(a<10){chipcolor='red'}
  if(a<5){chipcolor='darkorange3'}
  chipcolor
}
getchipcolorbg <- function(a){
  chipcolor='gray'
  if(a>=100){chipcolor='gray'}
  if(a<100){chipcolor='orchid'}
  if(a<50){chipcolor='skyblue'}
  if(a<25){chipcolor='palegreen'}
  if(a<10){chipcolor='pink'}
  if(a<5){chipcolor='gold'}
  chipcolor
}

generate_crapstable <- function(game_state,
                                current_point,
                                usual_passline_bet_amount,
                                usual_dontpass_bet_amount,
                                usual_odds_bet_amount,
                                usual_dpodds_bet_amount,
                                usual_field_bet_amount,
                                usual_come_bet_amount,
                                usual_hard4,
                                usual_hard6,
                                usual_hard8,
                                usual_hard10,
                                usual_place4,
                                usual_place5,
                                usual_place6,
                                usual_place8,
                                usual_place9,
                                usual_place10,
                                usual_proposition2,
                                usual_proposition3,
                                usual_proposition11,
                                usual_proposition12,
                                usual_proposition_craps,
                                usual_proposition_seven){
  
craps_table <- image_read('D:/RProjects/CrapR/1024px-Craps_table_layout.png')
bet_table <- craps_table

position_list <- c("+220+10","+300+10","+380+10","+460+10","+540+10","+620+10")
point_list <- c(4,5,6,8,9,10)
point_positions <- data.frame(pt=point_list,pos=position_list)



#if the state of the game is ON, show all the bets that can be placed during ON state
if(game_state=='ON'){
  pt_pos <- point_positions %>% filter(pt==current_point) %>% pull(pos)
  bet_table <- image_annotate(bet_table, game_state, size = 30, 
                              color = 'black', 
                              boxcolor = 'white',
  location = pt_pos)
   
if(usual_passline_bet_amount > 0){
  bet_table <- image_annotate(bet_table, usual_passline_bet_amount, size = 30, 
                              color = getchipcolor(usual_passline_bet_amount), 
                              boxcolor = getchipcolorbg(usual_passline_bet_amount),
  location = "+500+375")
}
if(usual_dontpass_bet_amount > 0){
  bet_table <- image_annotate(bet_table, usual_dontpass_bet_amount, size = 30, 
                              color = getchipcolor(usual_dontpass_bet_amount), 
                              boxcolor = getchipcolorbg(usual_dontpass_bet_amount),
  location = "+500+325")
}
if(usual_odds_bet_amount > 0){
  bet_table <- image_annotate(bet_table, paste('PL Odds:',usual_odds_bet_amount), size = 30, 
                              color = getchipcolor(usual_odds_bet_amount), 
                              boxcolor = getchipcolorbg(usual_odds_bet_amount),
  location = "+400+420")
}
  if(usual_dpodds_bet_amount > 0){
  bet_table <- image_annotate(bet_table, paste('DP Odds:',usual_dpodds_bet_amount), size = 30, 
                              color = getchipcolor(usual_odds_bet_amount), 
                              boxcolor = getchipcolorbg(usual_odds_bet_amount),
  location = "+400+420")
}
if(usual_field_bet_amount > 0){
  bet_table <- image_annotate(bet_table, usual_field_bet_amount, size = 30, 
                              color = getchipcolor(usual_field_bet_amount), 
                              boxcolor = getchipcolorbg(usual_field_bet_amount),
  location = "+500+280")
}
if(usual_come_bet_amount > 0){
  bet_table <- image_annotate(bet_table, usual_come_bet_amount, size = 30, 
                              color = getchipcolor(usual_come_bet_amount), 
                              boxcolor = getchipcolorbg(usual_come_bet_amount),
  location = "+500+200")
}
if(usual_hard4 > 0){
  bet_table <- image_annotate(bet_table, usual_hard4, size = 30, 
                              color = getchipcolor(usual_hard4), 
                              boxcolor = getchipcolorbg(usual_hard4),
  location = "+860+290")
}
if(usual_hard6 > 0){
  bet_table <- image_annotate(bet_table, usual_hard6, size = 30, 
                              color = getchipcolor(usual_hard6), 
                              boxcolor = getchipcolorbg(usual_hard6),
  location = "+720+230")
}
if(usual_hard8 > 0){
  bet_table <- image_annotate(bet_table, usual_hard8, size = 30, 
                              color = getchipcolor(usual_hard8), 
                              boxcolor = getchipcolorbg(usual_hard8),
  location = "+720+290")
}
if(usual_hard10 > 0){
  bet_table <- image_annotate(bet_table, usual_hard10, size = 30, 
                              color = getchipcolor(usual_hard10), 
                              boxcolor = getchipcolorbg(usual_hard10),
  location = "+860+230")
}

if(usual_place4 > 0){
  bet_table <- image_annotate(bet_table, usual_place4, size = 30, 
                              color = getchipcolor(usual_place4), 
                              boxcolor = getchipcolorbg(usual_place4),
  location = "+220+110")
}
if(usual_place5 > 0){
  bet_table <- image_annotate(bet_table, usual_place5, size = 30, 
                              color = getchipcolor(usual_place5), 
                              boxcolor = getchipcolorbg(usual_place5),
  location = "+300+110")
}
if(usual_place6 > 0){
  bet_table <- image_annotate(bet_table, usual_place6, size = 30, 
                              color = getchipcolor(usual_place6), 
                              boxcolor = getchipcolorbg(usual_place6),
  location = "+380+110")
}
if(usual_place8 > 0){
  bet_table <- image_annotate(bet_table, usual_place8, size = 30, 
                              color = getchipcolor(usual_place8), 
                              boxcolor = getchipcolorbg(usual_place8),
  location = "+460+110")
}
if(usual_place9 > 0){
  bet_table <- image_annotate(bet_table, usual_place9, size = 30, 
                              color = getchipcolor(usual_place9), 
                              boxcolor = getchipcolorbg(usual_place9),
  location = "+540+110")
}
if(usual_place10 > 0){
  bet_table <- image_annotate(bet_table, usual_place10, size = 30, 
                              color = getchipcolor(usual_place10), 
                              boxcolor = getchipcolorbg(usual_place10),
  location = "+620+110")
}
if(usual_proposition2 > 0){
  bet_table <- image_annotate(bet_table, usual_proposition2, size = 30, 
                              color = getchipcolor(usual_proposition2), 
                              boxcolor = getchipcolorbg(usual_proposition2),
  location = "+820+350")
}
if(usual_proposition3 > 0){
  bet_table <- image_annotate(bet_table, usual_proposition3, size = 30, 
                              color = getchipcolor(usual_proposition3), 
                              boxcolor = getchipcolorbg(usual_proposition3),
  location = "+720+350")
}
if(usual_proposition11 > 0){
  bet_table <- image_annotate(bet_table, usual_proposition11, size = 30, 
                              color = getchipcolor(usual_proposition11), 
                              boxcolor = getchipcolorbg(usual_proposition11),
  location = "+720+400")
}
if(usual_proposition12 > 0){
  bet_table <- image_annotate(bet_table, usual_proposition12, size = 30, 
                              color = getchipcolor(usual_proposition12), 
                              boxcolor = getchipcolorbg(usual_proposition12),
  location = "+920+350")
}

if(usual_proposition_craps > 0){
  bet_table <- image_annotate(bet_table, usual_proposition_craps, size = 30, 
                              color = getchipcolor(usual_proposition_craps), 
                              boxcolor = getchipcolorbg(usual_proposition_craps),
  location = "+720+450")
}
if(usual_proposition_seven > 0){
  bet_table <- image_annotate(bet_table, usual_proposition_seven, size = 30, 
                              color = getchipcolor(usual_proposition_seven), 
                              boxcolor = getchipcolorbg(usual_proposition_seven),
  location = "+720+190")
}
  #if the state of the game is OFF, show all the bets that can be placed during OFF state
}else{
  bet_table <- image_annotate(bet_table, game_state, size = 30, 
                              color = 'white', 
                              boxcolor = 'black',
  location = "+800+10")
  
  if(usual_passline_bet_amount > 0){
  bet_table <- image_annotate(bet_table, usual_passline_bet_amount, size = 30, 
                              color = getchipcolor(usual_passline_bet_amount), 
                              boxcolor = getchipcolorbg(usual_passline_bet_amount),
  location = "+500+375")
  }
  if(usual_dontpass_bet_amount > 0){
  bet_table <- image_annotate(bet_table, usual_dontpass_bet_amount, size = 30, 
                              color = getchipcolor(usual_dontpass_bet_amount), 
                              boxcolor = getchipcolorbg(usual_dontpass_bet_amount),
  location = "+500+325")
}
}

bet_table

}

Call the function in the OFF state.

generate_crapstable('OFF',0,
                    usual_passline_bet_amount,
                    usual_dontpass_bet_amount,
                    usual_odds_bet_amount,
                    usual_dpodds_bet_amount,
                    usual_field_bet_amount,
                    usual_come_bet_amount,
                    usual_hard4,
                    usual_hard6,
                    usual_hard8,
                    usual_hard10,
                    usual_place4,
                    usual_place5,
                    usual_place6,
                    usual_place8,
                    usual_place9,
                    usual_place10,
                    usual_proposition2,
                    usual_proposition3,
                    usual_proposition11,
                    usual_proposition12,
                    usual_proposition_craps,
                    usual_proposition_seven)

Call the function in the ON state.

generate_crapstable('ON',6,
                    usual_passline_bet_amount,
                    usual_dontpass_bet_amount,
                    usual_odds_bet_amount,
                    usual_dpodds_bet_amount,
                    usual_field_bet_amount,
                    usual_come_bet_amount,
                    usual_hard4,
                    usual_hard6,
                    usual_hard8,
                    usual_hard10,
                    usual_place4,
                    usual_place5,
                    usual_place6,
                    usual_place8,
                    usual_place9,
                    usual_place10,
                    usual_proposition2,
                    usual_proposition3,
                    usual_proposition11,
                    usual_proposition12,
                    usual_proposition_craps,
                    usual_proposition_seven)

Reset trials list

Run this to code to clear the trials list.

result_df <- data.frame()
#create trials / results tables
trials <- data.frame()


#init
trial_id <- 0 
point_on <- FALSE
point_value <- 0

pay_on_passline <-0
pay_on_odds <-0
pay_on_dontpass <-0
pay_on_dpodds <-0
pay_on_come <-0
pay_on_comeplaces <-0
pay_on_places <-0
pay_on_field <-0
pay_on_hardways <-0
pay_on_horn <-0

total_on_passline <- 0
total_on_odds <- 0
total_on_dontpass <- 0
total_on_dpodds <- 0
total_on_field <- 0

total_on_hard <- c(0,0,0,0)
total_on_proposition <- c(0,0,0,0)
total_on_place <- c(0,0,0,0,0,0)
total_on_come <- c(0,0,0,0,0,0)

Bet & Roll Function

This function is where the actual work happens. Each roll consists of a bet phase, a random roll of 2, 6-sided dice, and a payout phase.

rollcount <- seq(1:1000)
trialcount <- seq(1:10)

all_results <- list()
#doroll <- function(roll){
#start rolling
for(trial in trialcount){
  #reset the bankroll for each trial
  current_balance <- start_bankroll
  
  #add one to trial ID
  trial_id <- trial_id + 1
  
  #set random seed
  set.seed(10+trial_id)
  result_df  <- data.frame()

  #start the trial by resetting all the bets
  total_on_passline <- 0
  total_on_odds <- 0
  total_on_field <- 0
  total_on_places <- 0
  total_on_comeplaces <- 0
  total_on_props <- 0
  total_on_hardways <- 0
  total_on_comebar <- 0
  total_on_dontcome <- 0
  total_on_dontpass <- 0
  total_on_dpodds <- 0
  total_on_table <- 0
  
for(roll in rollcount){
  #before each roll, reset the crap out boolean
  crap_out <- FALSE
  
  #reset all variables
  pay_on_passline <-0
  pay_on_odds <-0
  pay_on_field <- 0
  pay_on_propositions  <- 0
  pay_on_hardways  <- 0
  pay_on_places  <- 0
  pay_on_comeplaces  <- 0
  pay_on_come  <- 0
  pay_on_dontcome  <- 0
  pay_on_dontpass  <- 0
  pay_on_dpodds  <- 0
 
  #reset new bet amounts
  bets_on_hardways <- c()
  bets_on_come <- c()
  bets_on_place <- c()
  bets_on_prop <- c()
  
  #reset the amount bet this roll to 0
  passline_bet_amount <-0
  odds_bet_amount <-0
  place_bet_amount <- 0
  hardway_bet_amount <- 0
  proposition_bet_amount <- 0
  places_bet_amount <- 0
  come_bet_amount <- 0
  dontpass_bet_amount <-0
  dpodds_bet_amount <-0
  
  #reset the collection of bets for this roll
  all_bets <- c()
  hard_bet_amount <- c(0,0,0,0)
  place_bet_amount <- c(0,0,0,0)
  prop_bet_amount <- c(0,0,0,0)
  
  #PLACE YOUR BETS!
 
  if(point_on == TRUE){
    #----------------------
    # POINT ON BETS
    #----------------------
    
    #the point was hit 
    field_bet_amount <- usual_field_bet_amount
    total_on_field <- field_bet_amount
   
    #place the come bet if not already placed
    if(total_on_comebar == 0){
      come_bet_amount <- usual_come_bet_amount
      total_on_comebar <- come_bet_amount
    }
    
    #the pass line or don't pass bet is already on the table at this point
    #now check for odds bets
    if(total_on_odds == 0){
      odds_limit <- 0
      i <- 0
      for(way in points){
        i <- i + 1
        if(point_value == way & total_on_passline > 0){
          #find the odds limit for this point
          odds_limit <- max_odds[i] * total_on_passline
        }
       
      }
      #bet the lesser of the odds limit or your odds preferred bet
      odds_bet_amount <- min(usual_odds_bet_amount,odds_limit)
      total_on_odds <- odds_bet_amount
    }
    #the pass line or don't pass bet is already on the table at this point
    #now check for odds bets
    if(total_on_dpodds == 0){
      odds_limit <- 0
      i <- 0
      for(way in points){
        i <- i + 1
        if(point_value == way & total_on_dontpass > 0){
          #find the odds limit for this point
          odds_limit <- max_odds[i] * total_on_dontpass
        }
      }
      #bet the lesser of the odds limit or your odds preferred bet
      dpodds_bet_amount <- min(usual_dpodds_bet_amount,odds_limit)
      total_on_dpodds <- dpodds_bet_amount
    }
   #look for any usual place bets and add them if possible.
   if(sum(usual_place)>0){
      i <- 0
      for(place in points){
        i <- i + 1 
        if(total_on_place[i] == 0){
          bet <- usual_place[i]
          place_bet_amount[i] <- bet
          total_on_place[i] <- bet
        }else{
          bet <- 0
          place_bet_amount[i] <- bet
        }
        
      }
      places_bet_amount <- sum(place_bet_amount)
    }
    
 
  
  }else{
    #----------------------
    # POINT OFF BETS
    #----------------------
    #bet your usual amount on the field if it's not already on.
    field_bet_amount <- usual_field_bet_amount
    total_on_field <- field_bet_amount
    
     if(total_on_passline == 0){
      #bet your usual amount on the pass line if its not already on.
      #no odds bets allowed when the button is OFF
      passline_bet_amount <-usual_passline_bet_amount
      total_on_passline <- passline_bet_amount
     }
    
     if(total_on_dontpass == 0){
      #bet your usual amount on the don't pass bar if its not already on.
      #no odds bets allowed when the button is OFF
      dontpass_bet_amount <-usual_dontpass_bet_amount
      total_on_dontpass <- dontpass_bet_amount
     }
  }
  
  #----------------------
  #ANY TIME BETS
  #----------------------
    
  #look for any usual Proposition bets and add them if possible.
  if(sum(usual_prop)>0){
    i <- 0
    for(proposition in horn){
      i <- i + 1 
      if(total_on_proposition[i] == 0){
        bet <- usual_prop[i]
        prop_bet_amount[i] <- bet
        total_on_proposition[i] <- bet
      }else{
        bet <- 0
        prop_bet_amount[i] <- bet
      }
     
    }
    proposition_bet_amount <- sum(prop_bet_amount)
  }
  
  #look for any usual hardway bets and add them if possible.
  if(sum(usual_hard)>0){
    i <- 0
    for(way in hardways){
      i <- i + 1 
      if(total_on_hard[i] == 0){
        bet <- usual_hard[i]
        hard_bet_amount[i] <- bet
        total_on_hard[i] <- bet
      }else{
        bet <- 0
        hard_bet_amount[i] <- bet
      }
     
    }
    hardway_bet_amount <- sum(hard_bet_amount)
  }
  
  #add up total on hardways
  #all_hardways <- c(total_on_hard4,total_on_hard6,total_on_hard8,total_on_hard10)
  total_on_hardways <- sum(total_on_hard)
  total_on_places <- sum(total_on_place)
  total_on_comeplaces <- sum(total_on_come)
  total_on_props <- sum(total_on_proposition)
  
  #add up all new bets
  all_bets <- c(passline_bet_amount,
                odds_bet_amount,
                dontpass_bet_amount,
                dpodds_bet_amount,
                field_bet_amount,
                places_bet_amount,
                hardway_bet_amount,
                proposition_bet_amount,
                come_bet_amount)
  
  total_bets <- sum(all_bets)
  
  #deduct the chips from your bankroll
  current_balance <- current_balance - total_bets
  
  #ROLL!
  dice1 <- sample(dicesides,1)
  dice2 <- sample(dicesides,1)
  dice_total <- dice1 + dice2
  
  
  pay_on_passline <- 0
  pay_on_odds <- 0
  pay_on_dontpass <- 0
  pay_on_dpodds <- 0
  pay_on_field <- 0
  pay_on_come <- 0
  payouts_on_hard <- c(0,0,0,0)
  payouts_on_place <- c(0,0,0,0,0,0)
  payouts_on_come <- c(0,0,0,0,0,0)
  payouts_on_prop <- c(0,0,0,0)
  
  #Get Roll Results
  hard <- FALSE
  #if both dice are the same, its a hard way
  if(dice1==dice2){
    hard <- TRUE
  }
  
  #Get Results for PASS LINE & ODDS
  hit_point <- FALSE
  if(point_on == TRUE & dice_total == point_value){
    
    #HIT!
    hit_point <- TRUE
    point_on <- FALSE
    point_value <- 0
    ix <- match(point_value,points)
      
    if(total_on_passline > 0){
      pay_on_passline <- total_on_passline * 2
    }
    if(total_on_odds > 0){
      pay_on_odds <- (payouts_on_odds[ix] * total_on_odds) + total_on_odds
    }
    
    pay_on_dontpass <- 0
    pay_on_dpodds <- 0
    
    #clear the don't pass bets
    total_on_dontpass <- 0
    total_on_dpodds <- 0
      
    #clear line bets
    total_on_passline <- 0
    total_on_odds <- 0
  }else{
    reset_point <- FALSE
    
    if(point_on == TRUE & dice_total == 7){
      # LOSE! 
      # a point was on and a 7 was rolled - the roller crapped out
      
      ix <- match(point_value,points)
      pay_on_dontpass <- 0
      pay_on_dpodds <- 0
      
      #don't pass WINS on 7
      if(total_on_dontpass > 0){
        pay_on_dontpass <- total_on_dontpass * 2
      }
      
      #don't pass ODDS WINS on 7
      if(total_on_dpodds > 0){
        pay_on_dpodds <- (payouts_on_dpodds[ix] * total_on_dpodds) + total_on_dpodds
       }
      
      #reset the point
      reset_point <- TRUE

      #no pass line/odds payouts
      pay_on_passline <- 0
      pay_on_odds <- 0
      pay_on_come <- 0
     
      #line away, remove bets
      total_on_passline <- 0
      total_on_odds <- 0
      total_on_dontpass <- 0
      total_on_dpodds <- 0
      
      total_on_place <- c(0,0,0,0,0,0)
      total_on_come <- c(0,0,0,0,0,0)
      
      crap_out <- TRUE
      
      
    }
    
    if(point_on == FALSE & dice_total %in% come){
     
      #a point was not on and the roller rolled 7 or 11 - you win even money on pass line bet or come bet and lose a don't pass bar bet
      
      #reset the point
      reset_point <- TRUE

      #WIN! 7 or 11 pays even money on the pass line
      pay_on_passline <- total_on_passline * 2
      pay_on_come <- total_on_comebar * 2
      pay_on_odds <- 0
      pay_on_dontpass <- 0
      pay_on_dpodds <- 0
    
      #remove bets
      total_on_passline <- 0
      total_on_comebar <- 0
      total_on_odds <- 0
      total_on_dontpass <- 0
      total_on_dpodds <- 0
     
      
      #pay_on_odds <- 1 * total_on_odds
    }
    
    if(point_on == FALSE & dice_total %in% craps){
     
       #a point was not on and the roller rolled craps: 2,3, or 12 - you lose on pass line bet and win on don't pass bar
      point_on <- FALSE
     
       #reset the point
      reset_point <- TRUE

      pay_on_dontpass <- 0
      pay_on_dpodds <- 0
      
      #WIN! 2,3 pays even money on the don't pass bar and 12 is a push
      if(dice_total==12){
        pay_on_dontpass <- total_on_dontpass
      }else{
        pay_on_dontpass <- total_on_dontpass * 2
      }
      
      # LOSE! 2,3,12 loses on the coming out roll
      pay_on_passline <- 0
      pay_on_come <- 0
     
      #remove bets
      total_on_passline <- 0
      total_on_comebar <- 0
      total_on_odds <- 0
      total_on_dontpass <- 0
      total_on_dpodds <- 0
     
    }
    
    if(reset_point){
      point_on <- FALSE
      point_value <- 0
    }
      
    
    if(point_on == FALSE & dice_total %in% points){
      #a point was hit and now the button is ON
      point_on <- TRUE
      point_value <- dice_total
      pay_on_passline <- 0
      pay_on_odds <- 0
      pay_on_dontpass <- 0
      pay_on_dpodds <- 0
    }
     
  }
  
  #PLACE bet pays out in on state only
  if(point_on == TRUE){
  #Get Results for PLACE
    if(dice_total %in% points){
      if(total_on_places > 0){
       #has PLACE bets on one or more points
        i <- 0
        for(place in points){
            i <- i + 1
            if(dice_total == place){
              payouts_on_place[i] <- total_on_place[i] * payouts_on_places[i]
              #remove the place bet
              total_on_place[i] <- 0
            }
          }
  
      }
      if(total_on_comeplaces > 0){
       #has COME bets on one or more points
        i <- 0
        for(come in points){
            i <- i + 1
            if(dice_total == come){
              #come bets pay even money
              payouts_on_come[i] <- total_on_come[i] #* 2
              #DOMT remove the come bet
              #total_on_come[i] <- 0
            }
          }
  
      }
    }
    
  }
  
  #After figuring out the payout on existing place bets
  #now move the come bet on to the rolled point
  if(point_on == TRUE & dice_total %in% points){
       #if a come bet is placed
      if(total_on_comebar > 0){
        #move to the correct place
        if(dice_total <= 6) {
             total_on_come[dice_total-3] = total_on_come[dice_total-3] + total_on_comebar
        }else{
             total_on_come[dice_total-4] = total_on_come[dice_total-4] + total_on_comebar
        }
        #move the come bet off the come bar
        total_on_comebar = 0
      }
  }
  
  #Get Results for FIELD
  #filed bet is one time
  if(field_bet_amount > 0){
    #if theres a bet, assess for winning
    if(dice_total %in% field){
      #WIN! a field number was rolled
      ix <- match(dice_total,field)
      pay_on_field <- payouts_on_field[ix] * total_on_field
      total_on_field <- 0
    }else{
      #LOSE! a field number was rolled
      pay_on_field <- 0
      total_on_field <- 0
    }
    
  }
  
  #Get Results for HARD WAYS
  if(dice_total %in% horn){
    if(total_on_props > 0){
     #has bets on hardways
      i <- 0
      for(way in horn){
          i <- i + 1
          if(dice_total == way){
            payouts_on_prop[i] <- total_on_proposition[i] * payouts_on_horn[i]
            total_on_proposition[i] <- 0
          }else{
            #one time bet, resets each roll
            payouts_on_prop[i] <- 0
            total_on_proposition[i] <- 0
          }
        }
     }
  }
  
  #Get Results for HARD WAYS
  if(dice_total %in% hardways){
    if(total_on_hardways > 0){
     #has bets on hardways
      if(hard == TRUE){
        #rolled the hard way
        i <- 0
        for(way in hardways){
          i <- i + 1
          if(dice_total == way){
            payouts_on_hard[i] <- total_on_hard[i] * payouts_on_hardway[i]
            total_on_hard[i] <- 0
          }
        }
       
      }else{
        i <- 0
        for(way in hardways){
          i <- i + 1
          if(dice_total == way){
            #hit the easy way, resets 
            payouts_on_hard[i] <- 0
            total_on_hard[i] <- 0
          }
        }
      }
    }
  }
  
  pay_on_hardways <- sum(payouts_on_hard)
  pay_on_places <- sum(payouts_on_place)
  pay_on_comeplaces <- sum(payouts_on_come)
  pay_on_propositions <- sum(payouts_on_prop)
  
  all_winnings <- c(pay_on_passline,
                    pay_on_odds,
                    pay_on_dontpass,
                    pay_on_dpodds,
                    pay_on_come,
                    pay_on_comeplaces,
                    pay_on_propositions,
                    pay_on_field,
                    pay_on_places,
                    pay_on_hardways)
  
  total_paid <- sum(all_winnings)
  current_balance <- current_balance + total_paid
  total_on_passline <- 0
 
  all_table_bets <- c(total_on_passline,
                      total_on_odds,
                      total_on_dontpass,
                      total_on_dpodds,
                      total_on_comebar,
                      total_on_comeplaces,
                      total_on_dontcome,
                      total_on_field,
                      total_on_places,
                      total_on_hardways,
                      total_on_props)
  
  total_on_table <- sum(all_table_bets)
  
  roll_df <- data.frame(trial_id=trial,
                        roll_id=roll,
                        payout_total=total_paid,
                        balance=current_balance,
                        bet_passline=passline_bet_amount,
                        bet_dontpass=dontpass_bet_amount,
                        bet_odds=odds_bet_amount,
                        bet_dpodds=dpodds_bet_amount,
                        bet_come=come_bet_amount,
                        bet_field=field_bet_amount,
                        bet_place=places_bet_amount,
                        bet_prop=proposition_bet_amount,
                        bet_hard=hardway_bet_amount,
                        new_bets=total_bets,
                        d1=dice1,
                        d2=dice2,
                        total=dice_total,
                        hardway=hard,
                        on=point_on,
                        point=point_value,
                        hit=hit_point,
                        crap_out=crap_out,
                        total_passline=total_on_passline,
                        total_odds=total_on_odds,
                        total_dontpass=total_on_dontpass,
                        total_dpodds=total_on_dpodds,
                        total_come=total_on_comebar,
                        total_field=total_on_field,
                        total_place=total_on_places,
                        total_place4=total_on_place[1],
                        total_place5=total_on_place[2],
                        total_place6=total_on_place[3],
                        total_place8=total_on_place[4],
                        total_place9=total_on_place[5],
                        total_place10=total_on_place[6],
                        total_come4=total_on_come[1],
                        total_come5=total_on_come[2],
                        total_come6=total_on_come[3],
                        total_come8=total_on_come[4],
                        total_come9=total_on_come[5],
                        total_come10=total_on_come[6],
                        total_prop=total_on_props,
                        total_hard=total_on_hardways,
                        total_table=total_on_table,
                        payout_passline=pay_on_passline,
                        payout_dontpass=pay_on_dontpass,
                        payout_come=pay_on_come,
                        payout_comeplaces=pay_on_comeplaces,
                        payout_odds=pay_on_odds,
                        payout_dpodds=pay_on_dpodds,
                        payout_field=pay_on_field,
                        payout_place=pay_on_places,
                        payout_prop=pay_on_propositions,
                        payout_hardways=pay_on_hardways
                        )
  
  
  result_df <- result_df %>% rbind(roll_df)
  all_results[[trial_id]] <- result_df
}
  final_balance <- result_df %>% arrange(-roll_id) %>% slice(1) %>% dplyr::pull(balance)
  final_balance

  summary_df <- data.frame(t(colSums(result_df))) %>% mutate(strategy=strategy_name, description=strategy_desc) %>% dplyr::select(-total_table,-balance,-roll_id) %>% mutate(ending_balance=final_balance,trial = trial_id)
summary_df

trials <- trials %>% rbind(summary_df)
}

Trial Results

Now we can see how our strategy performed.

data.frame(t(trials %>% dplyr::select(-strategy)))
##                                           X1                         X2
## trial_id                                1000                       2000
## payout_total                        5845.833                   5555.833
## bet_passline                               0                          0
## bet_dontpass                            1565                       1410
## bet_odds                                   0                          0
## bet_dpodds                              4105                       4090
## bet_come                                   0                          0
## bet_field                                  0                          0
## bet_place                                  0                          0
## bet_prop                                   0                          0
## bet_hard                                   0                          0
## new_bets                                5670                       5500
## d1                                      3383                       3531
## d2                                      3530                       3527
## total                                   6913                       7058
## hardway                                  160                        177
## on                                       688                        717
## point                                   4618                       4860
## hit                                       73                         81
## crap_out                                 128                        118
## total_passline                             0                          0
## total_odds                                 0                          0
## total_dontpass                          3440                       3565
## total_dpodds                            9545                      10355
## total_come                                 0                          0
## total_field                                0                          0
## total_place                                0                          0
## total_place4                               0                          0
## total_place5                               0                          0
## total_place6                               0                          0
## total_place8                               0                          0
## total_place9                               0                          0
## total_place10                              0                          0
## total_come4                                0                          0
## total_come5                                0                          0
## total_come6                                0                          0
## total_come8                                0                          0
## total_come9                                0                          0
## total_come10                               0                          0
## total_prop                                 0                          0
## total_hard                                 0                          0
## payout_passline                            0                          0
## payout_dontpass                         1540                       1435
## payout_come                                0                          0
## payout_comeplaces                          0                          0
## payout_odds                                0                          0
## payout_dpodds                       4305.833                   4120.833
## payout_field                               0                          0
## payout_place                               0                          0
## payout_prop                                0                          0
## payout_hardways                            0                          0
## description        Don't Pass: 5 DP Odds: 50  Don't Pass: 5 DP Odds: 50
## ending_balance                     10175.833                  10055.833
## trial                                   1000                       2000
##                                           X3                         X4
## trial_id                                3000                       4000
## payout_total                        6035.000                   5280.000
## bet_passline                               0                          0
## bet_dontpass                            1500                       1470
## bet_odds                                   0                          0
## bet_dpodds                              4190                       4045
## bet_come                                   0                          0
## bet_field                                  0                          0
## bet_place                                  0                          0
## bet_prop                                   0                          0
## bet_hard                                   0                          0
## new_bets                                5690                       5515
## d1                                      3611                       3485
## d2                                      3514                       3544
## total                                   7125                       7029
## hardway                                  157                        174
## on                                       701                        706
## point                                   4856                       4884
## hit                                       72                         82
## crap_out                                 128                        110
## total_passline                             0                          0
## total_odds                                 0                          0
## total_dontpass                          3505                       3525
## total_dpodds                           10210                      10700
## total_come                                 0                          0
## total_field                                0                          0
## total_place                                0                          0
## total_place4                               0                          0
## total_place5                               0                          0
## total_place6                               0                          0
## total_place8                               0                          0
## total_place9                               0                          0
## total_place10                              0                          0
## total_come4                                0                          0
## total_come5                                0                          0
## total_come6                                0                          0
## total_come8                                0                          0
## total_come9                                0                          0
## total_come10                               0                          0
## total_prop                                 0                          0
## total_hard                                 0                          0
## payout_passline                            0                          0
## payout_dontpass                         1560                       1355
## payout_come                                0                          0
## payout_comeplaces                          0                          0
## payout_odds                                0                          0
## payout_dpodds                       4475.000                   3925.000
## payout_field                               0                          0
## payout_place                               0                          0
## payout_prop                                0                          0
## payout_hardways                            0                          0
## description        Don't Pass: 5 DP Odds: 50  Don't Pass: 5 DP Odds: 50
## ending_balance                     10345.000                   9765.000
## trial                                   3000                       4000
##                                           X5                         X6
## trial_id                                5000                       6000
## payout_total                        4933.333                   5301.667
## bet_passline                               0                          0
## bet_dontpass                            1485                       1450
## bet_odds                                   0                          0
## bet_dpodds                              3900                       3945
## bet_come                                   0                          0
## bet_field                                  0                          0
## bet_place                                  0                          0
## bet_prop                                   0                          0
## bet_hard                                   0                          0
## new_bets                                5385                       5395
## d1                                      3613                       3463
## d2                                      3384                       3431
## total                                   6997                       6894
## hardway                                  171                        171
## on                                       703                        710
## point                                   4891                       5200
## hit                                       89                         77
## crap_out                                 103                        114
## total_passline                             0                          0
## total_odds                                 0                          0
## total_dontpass                          3515                       3545
## total_dpodds                           10135                      10355
## total_come                                 0                          0
## total_field                                0                          0
## total_place                                0                          0
## total_place4                               0                          0
## total_place5                               0                          0
## total_place6                               0                          0
## total_place8                               0                          0
## total_place9                               0                          0
## total_place10                              0                          0
## total_come4                                0                          0
## total_come5                                0                          0
## total_come6                                0                          0
## total_come8                                0                          0
## total_come9                                0                          0
## total_come10                               0                          0
## total_prop                                 0                          0
## total_hard                                 0                          0
## payout_passline                            0                          0
## payout_dontpass                         1315                       1385
## payout_come                                0                          0
## payout_comeplaces                          0                          0
## payout_odds                                0                          0
## payout_dpodds                       3618.333                   3916.667
## payout_field                               0                          0
## payout_place                               0                          0
## payout_prop                                0                          0
## payout_hardways                            0                          0
## description        Don't Pass: 5 DP Odds: 50  Don't Pass: 5 DP Odds: 50
## ending_balance                      9548.333                   9906.667
## trial                                   5000                       6000
##                                           X7                         X8
## trial_id                                7000                       8000
## payout_total                        5100.000                   5445.000
## bet_passline                               0                          0
## bet_dontpass                            1420                       1455
## bet_odds                                   0                          0
## bet_dpodds                              3925                       4020
## bet_come                                   0                          0
## bet_field                                  0                          0
## bet_place                                  0                          0
## bet_prop                                   0                          0
## bet_hard                                   0                          0
## new_bets                                5345                       5475
## d1                                      3575                       3576
## d2                                      3526                       3491
## total                                   7101                       7067
## hardway                                  143                        177
## on                                       716                        709
## point                                   4945                       4974
## hit                                       81                         77
## crap_out                                 111                        116
## total_passline                             0                          0
## total_odds                                 0                          0
## total_dontpass                          3570                       3535
## total_dpodds                           10650                      10395
## total_come                                 0                          0
## total_field                                0                          0
## total_place                                0                          0
## total_place4                               0                          0
## total_place5                               0                          0
## total_place6                               0                          0
## total_place8                               0                          0
## total_place9                               0                          0
## total_place10                              0                          0
## total_come4                                0                          0
## total_come5                                0                          0
## total_come6                                0                          0
## total_come8                                0                          0
## total_come9                                0                          0
## total_come10                               0                          0
## total_prop                                 0                          0
## total_hard                                 0                          0
## payout_passline                            0                          0
## payout_dontpass                         1310                       1390
## payout_come                                0                          0
## payout_comeplaces                          0                          0
## payout_odds                                0                          0
## payout_dpodds                       3790.000                   4055.000
## payout_field                               0                          0
## payout_place                               0                          0
## payout_prop                                0                          0
## payout_hardways                            0                          0
## description        Don't Pass: 5 DP Odds: 50  Don't Pass: 5 DP Odds: 50
## ending_balance                      9755.000                   9970.000
## trial                                   7000                       8000
##                                           X9                        X10
## trial_id                                9000                      10000
## payout_total                        5595.833                   5625.833
## bet_passline                               0                          0
## bet_dontpass                            1440                       1510
## bet_odds                                   0                          0
## bet_dpodds                              4095                       4185
## bet_come                                   0                          0
## bet_field                                  0                          0
## bet_place                                  0                          0
## bet_prop                                   0                          0
## bet_hard                                   0                          0
## new_bets                                5535                       5695
## d1                                      3570                       3462
## d2                                      3542                       3522
## total                                   7112                       6984
## hardway                                  172                        153
## on                                       712                        697
## point                                   5038                       4777
## hit                                       81                         82
## crap_out                                 117                        118
## total_passline                             0                          0
## total_odds                                 0                          0
## total_dontpass                          3560                       3475
## total_dpodds                           10185                      10025
## total_come                                 0                          0
## total_field                                0                          0
## total_place                                0                          0
## total_place4                               0                          0
## total_place5                               0                          0
## total_place6                               0                          0
## total_place8                               0                          0
## total_place9                               0                          0
## total_place10                              0                          0
## total_come4                                0                          0
## total_come5                                0                          0
## total_come6                                0                          0
## total_come8                                0                          0
## total_come9                                0                          0
## total_come10                               0                          0
## total_prop                                 0                          0
## total_hard                                 0                          0
## payout_passline                            0                          0
## payout_dontpass                         1445                       1455
## payout_come                                0                          0
## payout_comeplaces                          0                          0
## payout_odds                                0                          0
## payout_dpodds                       4150.833                   4170.833
## payout_field                               0                          0
## payout_place                               0                          0
## payout_prop                                0                          0
## payout_hardways                            0                          0
## description        Don't Pass: 5 DP Odds: 50  Don't Pass: 5 DP Odds: 50
## ending_balance                     10060.833                   9930.833
## trial                                   9000                      10000

Check some rolls

Check out the first 25 rolls of the #1 first trial

view_result <- all_results[[1]]
view_result_clean <- view_result %>% select_if(colSums(.) != 0)
  
t(head(view_result_clean,25))
##                    1    2    3    4    5    6    7    8    9   10   11   12
## trial_id           1    1    1    1    1    1    1    1    1    1    1    1
## roll_id            1    2    3    4    5    6    7    8    9   10   11   12
## payout_total       0    0    0    0    0    0    0    0    0    0    0    0
## balance         9995 9980 9980 9980 9980 9980 9980 9980 9980 9980 9980 9980
## bet_dontpass       5    0    0    0    0    0    0    0    0    0    0    0
## bet_dpodds         0   15    0    0    0    0    0    0    0    0    0    0
## new_bets           5   15    0    0    0    0    0    0    0    0    0    0
## d1                 2    1    5    6    5    6    6    3    3    2    6    3
## d2                 2    1    4    4    6    6    5    5    5    1    6    3
## total              4    2    9   10   11   12   11    8    8    3   12    6
## hardway            1    1    0    0    0    1    0    0    0    0    1    1
## on                 1    1    1    1    1    1    1    1    1    1    1    1
## point              4    4    4    4    4    4    4    4    4    4    4    4
## hit                0    0    0    0    0    0    0    0    0    0    0    0
## crap_out           0    0    0    0    0    0    0    0    0    0    0    0
## total_dontpass     5    5    5    5    5    5    5    5    5    5    5    5
## total_dpodds       0   15   15   15   15   15   15   15   15   15   15   15
## total_table        5   20   20   20   20   20   20   20   20   20   20   20
## payout_dontpass    0    0    0    0    0    0    0    0    0    0    0    0
## payout_dpodds      0    0    0    0    0    0    0    0    0    0    0    0
##                   13   14   15   16   17   18   19   20   21   22   23   24
## trial_id           1    1    1    1    1    1    1    1    1    1    1    1
## roll_id           13   14   15   16   17   18   19   20   21   22   23   24
## payout_total       0    0    0    0    0    0    0    0    0    0    0    0
## balance         9980 9980 9980 9980 9975 9955 9950 9930 9930 9930 9930 9930
## bet_dontpass       0    0    0    0    5    0    5    0    0    0    0    0
## bet_dpodds         0    0    0    0    0   20    0   20    0    0    0    0
## new_bets           0    0    0    0    5   20    5   20    0    0    0    0
## d1                 3    4    2    2    3    1    1    4    1    4    5    6
## d2                 2    5    3    2    2    4    4    5    5    2    4    3
## total              5    9    5    4    5    5    5    9    6    6    9    9
## hardway            0    0    0    1    0    0    0    0    0    0    0    0
## on                 1    1    1    0    1    0    1    1    1    1    1    1
## point              4    4    4    0    5    0    5    5    5    5    5    5
## hit                0    0    0    1    0    1    0    0    0    0    0    0
## crap_out           0    0    0    0    0    0    0    0    0    0    0    0
## total_dontpass     5    5    5    0    5    0    5    5    5    5    5    5
## total_dpodds      15   15   15    0    0    0    0   20   20   20   20   20
## total_table       20   20   20    0    5    0    5   25   25   25   25   25
## payout_dontpass    0    0    0    0    0    0    0    0    0    0    0    0
## payout_dpodds      0    0    0    0    0    0    0    0    0    0    0    0
##                         25
## trial_id           1.00000
## roll_id           25.00000
## payout_total      43.33333
## balance         9973.33333
## bet_dontpass       0.00000
## bet_dpodds         0.00000
## new_bets           0.00000
## d1                 1.00000
## d2                 6.00000
## total              7.00000
## hardway            0.00000
## on                 0.00000
## point              0.00000
## hit                0.00000
## crap_out           1.00000
## total_dontpass     0.00000
## total_dpodds       0.00000
## total_table        0.00000
## payout_dontpass   10.00000
## payout_dpodds     33.33333

View a summary of trial results

This table gives us a sanity check to make sure the simulator is running properly and following the rules.

view_result <- all_results[[1]]
transposed <- data.frame(t(head(view_result,10)))
transposed <- transposed %>% cbind(label=rownames(transposed))
transposed
##                     X1   X2   X3   X4   X5   X6   X7   X8   X9  X10
## trial_id             1    1    1    1    1    1    1    1    1    1
## roll_id              1    2    3    4    5    6    7    8    9   10
## payout_total         0    0    0    0    0    0    0    0    0    0
## balance           9995 9980 9980 9980 9980 9980 9980 9980 9980 9980
## bet_passline         0    0    0    0    0    0    0    0    0    0
## bet_dontpass         5    0    0    0    0    0    0    0    0    0
## bet_odds             0    0    0    0    0    0    0    0    0    0
## bet_dpodds           0   15    0    0    0    0    0    0    0    0
## bet_come             0    0    0    0    0    0    0    0    0    0
## bet_field            0    0    0    0    0    0    0    0    0    0
## bet_place            0    0    0    0    0    0    0    0    0    0
## bet_prop             0    0    0    0    0    0    0    0    0    0
## bet_hard             0    0    0    0    0    0    0    0    0    0
## new_bets             5   15    0    0    0    0    0    0    0    0
## d1                   2    1    5    6    5    6    6    3    3    2
## d2                   2    1    4    4    6    6    5    5    5    1
## total                4    2    9   10   11   12   11    8    8    3
## hardway              1    1    0    0    0    1    0    0    0    0
## on                   1    1    1    1    1    1    1    1    1    1
## point                4    4    4    4    4    4    4    4    4    4
## hit                  0    0    0    0    0    0    0    0    0    0
## crap_out             0    0    0    0    0    0    0    0    0    0
## total_passline       0    0    0    0    0    0    0    0    0    0
## total_odds           0    0    0    0    0    0    0    0    0    0
## total_dontpass       5    5    5    5    5    5    5    5    5    5
## total_dpodds         0   15   15   15   15   15   15   15   15   15
## total_come           0    0    0    0    0    0    0    0    0    0
## total_field          0    0    0    0    0    0    0    0    0    0
## total_place          0    0    0    0    0    0    0    0    0    0
## total_place4         0    0    0    0    0    0    0    0    0    0
## total_place5         0    0    0    0    0    0    0    0    0    0
## total_place6         0    0    0    0    0    0    0    0    0    0
## total_place8         0    0    0    0    0    0    0    0    0    0
## total_place9         0    0    0    0    0    0    0    0    0    0
## total_place10        0    0    0    0    0    0    0    0    0    0
## total_come4          0    0    0    0    0    0    0    0    0    0
## total_come5          0    0    0    0    0    0    0    0    0    0
## total_come6          0    0    0    0    0    0    0    0    0    0
## total_come8          0    0    0    0    0    0    0    0    0    0
## total_come9          0    0    0    0    0    0    0    0    0    0
## total_come10         0    0    0    0    0    0    0    0    0    0
## total_prop           0    0    0    0    0    0    0    0    0    0
## total_hard           0    0    0    0    0    0    0    0    0    0
## total_table          5   20   20   20   20   20   20   20   20   20
## payout_passline      0    0    0    0    0    0    0    0    0    0
## payout_dontpass      0    0    0    0    0    0    0    0    0    0
## payout_come          0    0    0    0    0    0    0    0    0    0
## payout_comeplaces    0    0    0    0    0    0    0    0    0    0
## payout_odds          0    0    0    0    0    0    0    0    0    0
## payout_dpodds        0    0    0    0    0    0    0    0    0    0
## payout_field         0    0    0    0    0    0    0    0    0    0
## payout_place         0    0    0    0    0    0    0    0    0    0
## payout_prop          0    0    0    0    0    0    0    0    0    0
## payout_hardways      0    0    0    0    0    0    0    0    0    0
##                               label
## trial_id                   trial_id
## roll_id                     roll_id
## payout_total           payout_total
## balance                     balance
## bet_passline           bet_passline
## bet_dontpass           bet_dontpass
## bet_odds                   bet_odds
## bet_dpodds               bet_dpodds
## bet_come                   bet_come
## bet_field                 bet_field
## bet_place                 bet_place
## bet_prop                   bet_prop
## bet_hard                   bet_hard
## new_bets                   new_bets
## d1                               d1
## d2                               d2
## total                         total
## hardway                     hardway
## on                               on
## point                         point
## hit                             hit
## crap_out                   crap_out
## total_passline       total_passline
## total_odds               total_odds
## total_dontpass       total_dontpass
## total_dpodds           total_dpodds
## total_come               total_come
## total_field             total_field
## total_place             total_place
## total_place4           total_place4
## total_place5           total_place5
## total_place6           total_place6
## total_place8           total_place8
## total_place9           total_place9
## total_place10         total_place10
## total_come4             total_come4
## total_come5             total_come5
## total_come6             total_come6
## total_come8             total_come8
## total_come9             total_come9
## total_come10           total_come10
## total_prop               total_prop
## total_hard               total_hard
## total_table             total_table
## payout_passline     payout_passline
## payout_dontpass     payout_dontpass
## payout_come             payout_come
## payout_comeplaces payout_comeplaces
## payout_odds             payout_odds
## payout_dpodds         payout_dpodds
## payout_field           payout_field
## payout_place           payout_place
## payout_prop             payout_prop
## payout_hardways     payout_hardways

Plot the bankroll timeseries

Now we can see how our bankroll went up and down over the rolls in each trial. Each trial is color coded to make it easier to tell them apwrt. The exact bank balance is the squiggly line, and a loess regression has been added to make your local average bank balance easier to follow.

plot <- result_df %>% ggplot()
for(t in trialcount){
  plot <- plot + geom_line(data=all_results[[t]],aes(x=roll_id,y=balance,color=as.factor(trial_id)))
  plot <- plot + geom_smooth(data=all_results[[t]],aes(x=roll_id,y=balance,color=as.factor(trial_id)))
}
plot <- plot + labs(title='Bankroll balance over 10 trials of 1000 rolls with Strategy:',subtitle=strategy_name,caption=strategy_desc)
plot
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

Mean Winnings

After each trial was averaged - your overall mean winnings/losses per game, using the strategy: Don’t Pass Line with 10X Odds was:

mean_balance <- -(start_bankroll-mean(trials$ending_balance))
mean_balance
## [1] -48.66667

Plot of winnings

And finally, we can see where we ended up after each trial. We can take the average of each of these (the red line) to judge whether this strategy was better or worse than another strategy we might have tried, over the course of our X trieals of N dice rolls!

trials <- trials %>% mutate(winnings=ending_balance-start_bankroll)
trials %>% ggplot() + geom_bar(aes(x=winnings,y=as.factor(trial_id),fill=as.factor(trial_id)),stat="identity") + labs(title='Final Bankroll balance for 10 trials of 1000 rolls with Strategy:',subtitle=strategy_name,caption=strategy_desc) + geom_vline(xintercept=mean_balance, linetype = "dashed")


End of Code & Functions

CrapR was created by Ryan J Cooper for private, non-commercial use only. You may copy, modify and run the provided code, but please do not republish this simulator without the authors written consent.

© 2022 Ryan J Cooper, All Rights Reserved.

Appendix: Installing R

R is a free software environment for statistical computing and graphics. It compiles and runs on a wide variety of UNIX platforms, Windows and MacOS. To get the latest version of R, please visit:

https://www.r-project.org/

Packages used in this document are available from the Comprehensive R Archive Network (CRAN):

http://cran.us.r-project.org

For more info on R packages visit:

https://cran.r-project.org/web/packages/

Notes on Publishing RMarkdown

This document was generated by RMarkdown using R code and LaTeX, and rendered to HTML.

Additional formatting has been applied to results variables using the kable and kableExtra packages. These code blocks are not shown in the output, for readability.