Gambling with a statistician's brain.

Using Monte Carlo Simulation to analyze the odds of winning in a casino

Saket Garodia
Towards Data Science

--

Me wondering outside the casino @Venetian Macau ( Picture not allowed inside the casino)

Let me start with one of my casino experiences to make it more interesting. In 2016, I was there at the world's second-largest casino in the Venetian, Macau, and was trying my luck on different games until I reached the Roulette slot machine. As you could imagine the atmosphere was surreal with flashing lights and rich people seating attentive with their eyes glued to the slot machines and table full of “free alcohol bottles”.

Here’s my story, I had $1000 (HK dollars) to spend in the casino. Within 2 hours I made around $3500 (HK dollars) at the roulette machine but who stops after winning. It was 8 pm (local time ) when I started playing Roulette after some time of watching people play different games. But, I ended up being in the casino until 5 am the other morning with a net total -$1000 HK. All my money was wasted in enjoying the ‘Monte Carlo simulation’ for 9 hours with odds of winning a bit less than 0.5. Jokes apart, one of my statistician friends always used to tell me that gambling is a zero/negative-sum game but inside a casino, naive people/ tourists like me get easily seduced by the last 20 results shown on the monitor ( Gambler’s fallacy ).

Now, at least we have statistics and Monte Carlo Simulation to analyze the same.

Now, let me start by explaining the odds in a casino game. I will try to explain one game and make it simplistic for our calculations. Let’s chose the game Big and Small (Sic bo). The dealer will shuffle 3 dice which might lead to any of the combinations from (1,1,1) to (6,6,6). There are 2 options to chose from, either small — (sum of 4 to 10 ) or big — ( sum of 11 to 17). I will explain why I haven’t included the sum of 3 and 18 in a while (A similar game is very common everywhere in India and is called 7 up, 7 down). Now, we can choose either small or big. Let’s assume the payout is 1:1 which means if you win you get back your bet and if you lose you lose the same amount. By now, you might be thinking that the odds are the same for small and big but here’s where the odds change. For the triplets, the payout model is a bit tweaked which leads the game to be in the favor of the house. For our calculations, let’s assume that we won't be paid in case of triplets. Choosing small or big is similar to us. So lets chose small for our calculations.

https://www.thoughtco.com/probabilities-for-rolling-three-dice-3126558

If we chose small our odds of winning will be 105/216 ( excluding triplets (1,1,1) and (2,2,2)). which is 48.61%. So, therefore, the house odds will be 51.39%. Even then you would think how would this small amount affect me? Right? Well, I will show you through the Monte Carlo simulation.

Facts:

  1. The lowest odds in European Roulette is 2.7% ( 52.7% in favor of the house).
  2. Blackjacks is one of the games that have higher odds in our favor compared to other casino games.

Enter Monte Carlo World

For illustration, I will assume I have $50000 dollars and I will bet an equal amount of $500 in each game. Now, first, let's consider the odds value as 48.6% which is what we calculated above, and let’s calculate how much money I might end up with if I play 5 games, 50 games, 5000 games, 1000 games and10000 games respectively using Monte Carlo Simulation of the odds.

Let’s import the libraries and create a function to win or lose. We will use uniform random to generate a probability between 0 and 1 and then use the win_odds probability to decide whether we win or lose ( according to the odds).

Note: Even if you aren’t comfortable with python or programming, try reading just the text and understand the story.

#Import required librariesimport randomimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as sns#win_odds take the probability of winning, returns true if prob lies between 0 and win_oddsdef win_or_lose(win_odds):dice = random.uniform(0,1)if dice <=win_odds:return Trueelif dice > win_odds:return False

The following play function will take in input — chips in hand ( $50000 here), betting amount ( $500 ), the total number of bets and the win_odds probability, and return the final updated amount after the game (using win/lose odds).

#chips_in_hand is the amount of chips a player has in hand#betting amount is the amount a player bets in each game#total_bets is the number of bets in one seatingdef play(chips_in_hand, betting_amount, total_bets, win_odds):game_num = []updated_chips = []game = 1#lets bet for the number of bets we have in the argument and append the value of chips in hand after each bet in updated_chips listwhile game <= total_bets:#If we winif win_or_lose(win_odds):#Add the win amount to our chips valuechips_in_hand = chips_in_hand + betting_amountgame_num.append(game)#Append the updated_chips value after each gameupdated_chips.append(chips_in_hand)#If the house winselse:#Add the money to our fundschips_in_hand = chips_in_hand — betting_amountgame_num.append(game)#Append the updated_chips value after each gameupdated_chips.append(chips_in_hand)game = game + 1return(game_num,updated_chips,updated_chips[-1])

Now, we will simulate and call play 5000 times (number of simulations) and analyze the statistics of the final amount value ( in 5000 simulations). In simple terms, since we are doing 5000 simulations, we will have 5000 different final values after playing the game. ( 1 game basically consist of the number of bets, if the number of bets is 5, 1 game consist of 5 bets )

ending_fund= []#lets try 5000 simulations to get a good mean value ( Monte Carlo Simulation)#Let’s start with $50000 and bet $500 bets each time for simplicity#Lets play 5 times and see the final chips amount possible through monte carlo simulationplt.figure(figsize=(12,6))for x in range(1,5001):game_num,updated_chips,fund = play(50000 ,500, 5, win_odds)ending_fund.append(fund)plt.plot(game_num,updated_chips)plt.title(‘Final chips value vs number of bets (After a player starts with $5000)’)plt.ylabel(‘Final chips value’)plt.xlabel(‘Number of bets’)plt.show()#Lets print the statistics of the final_chips valuemean_final = sum(ending_fund)/len(ending_fund)variance_final_funds = sum([((x — mean_final) ** 2) for x in ending_fund]) / len(ending_fund)res_final = variance_final_funds ** 0.5min_final = min(ending_fund)max_final = max(ending_fund)print(“The player starts the game with $50000 and ends with $” + str(mean_final))print(“The standard deviation is $” + str(res_final))print(‘The minimum anad maximum funds that a player can possible end with are: {} and {}’.format(min_final,max_final))

Case 1: Number of bets = 5

If you just play for 5 times, the uncertainty will be too high to decide on some statistics. Even then we can see that the mean of the amount the player ends with is $49916 which is less than he actually had. Since he is betting just $500 in each bet he can only lose $2500 in 5 bets. So let’s increase the number of bets to 50, 500, 1000, and 10000 and analyze those. Nobody leaves a casino playing just 4–5 bets. Even I would have ended up making more than 500 bets during my time.

Case 2: Number of bets = 50

Case 3: Number of bets = 500

Case 4: Number of bets = 1000

Case 5: Number of bets = 10000

Simulation plot
Distribution Plot

From the above simulation charts and the distribution graphs, you can see an interesting trend. Let me explain to you one of them and then you can gain intuition on what is happening.

In case 5 ( number of bets = 10,000 ), you can see in the simulation plot that the plot is orienting downwards as the number of bets has increased. Also in the distribution plot just below the simulation plot, you can see that the mean final amount is around -100,000 dollars. Just imagine someone coming with a bag of $50000 and ending up giving -$100000 to the house.

Now that you have understood the odds of gambling, let’s do a sensitivity analysis on the statistics of final amounts vs the odds_probability.

We will take equally spaces decimals from 0.45(less favorable to us) to 0.495(good returns, eg blackjack but still less than the odds for the house 0.505) and see how the mean, standard deviation, the minimum and maximum values of the final amount looks like.

We will take the number of bets as 1000 which is very realistic for normal gamblers.

win_odds_list = np.linspace(.45, .495, num=100)
col_names = ['win_odds', 'mean_final', 'std_final', 'min_final', 'max_final']
final_coins = pd.DataFrame(columns = col_names)for odds in win_odds_list:mean_val, std_val, min_val, max_val = simulate_bets(50000, 500, 1000, odds, 5000)final_coins = final_coins.append({'win_odds': odds, 'mean_final': mean_val, 'std_final': std_val, 'min_final':min_val , 'max_final':max_val }, ignore_index=True)

We got the following data frame after simulating 5000 times for each of the 100 equally spaced odds we generated above.

You can see so many interesting trends from the above 4 plots. The maximum value is only around $100000 ( odds of .495) even after bringing in $50000 and playing for 1000 times.

Next time when you go to Vegas, Atlantic City or Macau, keep your statistician's brain active. If you are planning to stay long, at least try playing the game with the highest odds.

Thanks.

Connect me on Linkedin:

https://www.linkedin.com/in/saket-garodia/

References:

https://pythonprogramming.net/monte-carlo-simulator-python/

http://math.info/Misc/House_Edge/

https://wizardofodds.com/games/sic-bo/

https://towardsdatascience.com/the-house-always-wins-monte-carlo-simulation-eb82787da2a3

Note from Towards Data Science’s editors: While we allow independent authors to publish articles in accordance with our rules and guidelines, we do not endorse each author’s contribution. You should not rely on an author’s works without seeking professional advice. See our Reader Terms for details.

--

--