top of page

Why does the house always wins?

I assume, most of you are familiar with the saying "the house always wins". Statistically, it is correct as per the saying goes. I presume, you'll need some explanation, though.


Let us bet on a number on the roulette table. If you've no idea how it works: there's spinning wheel with numbered pockets, you bet on any of the numbered pockets and there's a ball that finds it's place in any of the pockets as soon as the wheel stops. If the ball stops at the number, you put your bet on, you win the sum of the bets.


So, we put a bet on a fair roulette wheel. Fair in the sense that the expectation value of one's winning anything more than what one bets, is 0 i.e., the sum of the money never leaves the table. The following class "fairRoulette" includes the array of pockets numbered from 1 to 35. "Spin" randomly places the ball in one of the pockets. If the ball is in the pocket you put your money on, you get the sum of the bets on all other numbers including yours' (to keep this simple only one can bet at one pocket).



class fairRoulette():
    def __init__(self):
        self.pockets = []
        for i in range (1,35):
            self.pockets.append(i)
        self.ball = None
        self.pocketOdds = len(self.pockets) - 1
    def spin(self):
        self.ball = random.choice(self.pockets)
    def withdraw(self, pocket, amt):
        if str(self.ball) == str(pocket):
            return self.pocketOdds *amt
        else:
            return -amt
    def __str__(self):
        return 'Fair Roulette'


Now, we play(simulate) the wheel for a number of spins, betting on a single number. I've got my confidence on '2'.



def playRoulette(game, spins, pocket, bet, receipt):
    won = 0
    for i in range(spins):
        game.spin()
        won += game.withdraw(pocket, bet)
    if receipt:
        print(spins, 'spins of ', game)
        print('Return on betting ',pocket,' is ',round(((won/spins)/bet), 5)*100, '%')
    return (won/spins)

game = fairRoulette()
for spins in (100, 1000000):
    for i in range(3):
        playRoulette(game, spins, 2, 1, True)
    print('\n')

SIMULATIONS:


100 spins of  Fair Roulette
Return on betting  2  is  2.0 %
100 spins of  Fair Roulette
Return on betting  2  is  36.0 %
100 spins of  Fair Roulette
Return on betting  2  is  -66.0 %


1000000 spins of  Fair Roulette
Return on betting  2  is  0.426 %
1000000 spins of  Fair Roulette
Return on betting  2  is  -0.774 %
1000000 spins of  Fair Roulette
Return on betting  2  is  0.086 %

"playRoulette" prints the percentage of net winning (excluding your bet) in units of the bet and returns per spin winnings.


We see for less rounds of spin, the winnings are completely random. For 100 spins, once you fold at winning 2% of your bet (excluding your bet), while the other times it were 36% and -66%. As the number of spins increases to be incredibly large, the net winning tends to zero and this proves me, being fair. So what's going on here is something called the law of large numbers, or sometimes Bernoulli's law. Here it says, "in repeated independent tests with the same actual probability, the chance that the fraction of times the outcome differs from p converges to 0 as the number of trials goes to infinity." So this says if I were to spin this fair roulette wheel an infinite number of times, the expected return would be 0 (again, excluding my bet). The real true probability from the mathematics.


Now the casinos aren't in the fair business and they're not interested what happens after 100 spins, it's the millionth one filling up their pockets. To consider the expectation either a positive sum or a negative sum, we leak to sum of bets on the table to the casino somehow.


In European casinos aside from the number in the blacks and white, there's a '0' in green and in American casinos, there's a '00' along with '0' in green. As per the coding goes, we simply create a subclass "euRoulette" with parent class "fairRoulette" and subclass "amRoulette" with parent class "euRoulette". We just add a pocket in the pocket array.



class euRoulette(fairRoulette):
    def __init__(self):
        fairRoulette.__init__(self)
        self.pockets.append('0')
    def __str__(self):
        return 'European Roulette'

class amRoulette(euRoulette):
    def __init__(self):
        euRoulette.__init__(self)
        self.pockets.append('00')
    def __str__(self):
        return 'American Roulette'


We set of certain number of trials (say, 20) for a number of spins i.e., say for a 100 spins, we actually try this 20 times and average the winnings in 20 different trials. Here also we bump up the spins to an incredibly large number and see what happens.



numTrials = 20
games = (fairRoulette(), euRoulette(), amRoulette())

for numSpins in (1000, 10000, 100000, 1000000):
    print('\nSimulating', numTrials, 'trials of',
          numSpins, 'spins each')
    for G in games:
        pocketReturns = []
        for t in range(numTrials):
            trialVals = playRoulette(G, spins, 2, 1, False)
            pocketReturns.append(trialVals)
        expReturn = 100*sum(pocketReturns)/len(pocketReturns)
        print('Exp. return for', G, '=',round(expReturn, 4),'%')

SIMULATIONS:


Simulating 20 trials of 1000 spins each
Exp. return for Fair Roulette = 0.3027 %
Exp. return for European Roulette = -2.769 %
Exp. return for American Roulette = -5.515 %

Simulating 20 trials of 10000 spins each
Exp. return for Fair Roulette = 0.2481 %
Exp. return for European Roulette = -2.6492 %
Exp. return for American Roulette = -5.5623 %

Simulating 20 trials of 100000 spins each
Exp. return for Fair Roulette = -0.1242 %
Exp. return for European Roulette = -2.946 %
Exp. return for American Roulette = -5.6735 %

Simulating 20 trials of 1000000 spins each
Exp. return for Fair Roulette = 0.2074 %
Exp. return for European Roulette = -2.7816 %
Exp. return for American Roulette = -5.3302 %
>>> 

We see as expected, it is a negative sum expectation, as number of spins approaches infinity.


The inference is clear, yet an amusement. Think of it as this way, "Statistically, you are neither lucky or unlucky. You just chose to believe so and blamed luck."




"Cause the house always wins. You play long enough, never change the stakes, the house takes you. Unless, when that perfect hand comes along, you bet big, and then you take the house."
-Danny Ocean


76 views0 comments

Recent Posts

See All

Comments


bottom of page