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!
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)
Set up the initial starting conditions of the simulation:
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)
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.
Understanding Craps requires understanding combinations & permutations. The most important mathematical concept in craps is 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."
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.
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.
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.
“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.
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.
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.
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 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.
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 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.
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.
To understand the expected value of a one roll bet - you must look at 2 factors-
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!
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.
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)
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!
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))
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)
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)
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)
}
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 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
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
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")'
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
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.
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:
Packages used in this document are available from the Comprehensive R Archive Network (CRAN):
For more info on R packages visit:
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.