Gambling

Royal Match: Probabilities and Payouts

To determine the probabilities and expected return of the Royal Match bet, I wrote a Python script to simulate dealing a number of decks from fresh shuffle down to a specified number of cards. The script is made assuming:

- 3-1 odds for any 2 cards matching
- 10-1 odds for K/Q matching
- single deck

The code follows below, or can be found here: royal.py

#!/usr/bin/python
# calculate the probabilities of suit match for "royal match" bet

import random

maxdecks=100000
maxdealt=50 # number of cards dealt into deck
bet=25 # starting bet



#===================================================================
# calcprob
#
# probability of royal match win, given 'nsuitcards' cards left of
# a particular suit in a deck of 'ncards' cards, and possibility
# of K/Q pair indicated by 'royal'
#
# this assumes 1 deck and 3-1/10-1 payout
#
def calcprob(nsuitcards, ncards, royal):
    # royal match K/Q
    if royal == 1:
        prob1 = 2.0/ncards    # first card
        prob2 = 1.0/(ncards-1)    # second card has only 1 possibility to get match
        rmprob = prob1*prob2
    else:
        rmprob = 0
    payout = 11
    royalmatchreturn = rmprob*payout

    #print "Probability of royal match is ", rmprob, " with payout of ", royalmatchreturn

    # 2 cards of any suit match (non-K/Q)
    prob1 = float(nsuitcards)/ncards;
    prob2 = ((nsuitcards-1.0)/(ncards-1.0))
    mprob = (prob1*prob2)
    mprob -= rmprob
    payout = 4  # 3-1 odds
    matchreturn = mprob*payout

    #print "Probability of non-royal match is ", mprob, " with payout of ", matchreturn


    if royal == 1:
        treturn = (matchreturn+royalmatchreturn)
    else:
        treturn = (matchreturn)
    #print "Total return is ", treturn, " (",nsuitcards,",",ncards,")"
    return treturn


#=============================================================
# countsuits()
#
# Count the number of cards in each suit, returned as 4 item list
#
def countsuits(deck):
    nsuitcards = [0,0,0,0]
    for i in range(0,4):
        for j in range(0,13):
            if deck[i*13+j] == 0:    
                nsuitcards[i] += 1
            #print "deck[",i*13+j,"] = ",deck[i*13+j]
    return nsuitcards
    

#===============================================================
# calcprob2
#
# Count the expected return of royal match with current deck.
# K/Q are considered to be the first 2 cards in the suit
#
def calcprob2(deck):
    royal = [1,1,1,1]
    nsuitcards = countsuits(deck)
    ncards = sum(nsuitcards)
    prob = 0.0;
    # determine if royal can happen
    for i in range(0,4):
        # treat first 2 cards in suit as K/Q
        if deck[i*13] or deck[i*13+1]:
            royal[i] = 0
        prob += calcprob(nsuitcards[i], ncards, royal[i])

    # calculate probs
    return (prob)

#=================================================================
# playdeck()
# 
# calculate return after removing 1 random card from the deck up
# to 'ndealt' cards
#
# deck[] is a list of all cards in the deck.  we'll assume they're
# in order, first 13 cards same suit, next 13 same suit, etc...
#
def playdeck(ndealt):
    deck = []
    prob = []
    global bet
    for i in range(52):
        # reset deck    
        deck.append(0)

    for i in range(ndealt):
        #print i, " cards dealt, (", countsuits(deck),")"
        prob.append(calcprob2(deck))
        #print "Probability is ", prob(i)

        # deal out a card
        while 1==1:
            rand = random.randint(0,51)
            if deck[rand] == 0:
                deck[rand] = 1
                break
###########
    #
    # Here we apply our counting strategy
    #
    # bet when red/black count swings larger than 5

#    nsuitcards = countsuits(deck)
#    redblack = (nsuitcards[0]+nsuitcards[1]) - \
#        (nsuitcards[2]+nsuitcards[3])
#    if abs(redblack) >= 6:
#        bet *= prob[ndealt-1]

###########
    return prob

    
#=====================================
# Begin
#=====================================


#
# Play a bunch of decks and average probabilities
#

totprob = []  # list of probabilities n cards into deck
favdecks = [] # number of favorable decks, listed by number cards dealt

totprob = playdeck(maxdealt)   # initial probabilities
for i in range(maxdealt):
    if totprob[i] > 1.0:
        favdecks.append(1)
    else:
        favdecks.append(0)

for ndecks in range(1,maxdecks):
    prob = playdeck(maxdealt)
    # integrate current deck into average over all decks
    for i in range(maxdealt):
        totprob[i] += (prob[i]-totprob[i])/ndecks
        if prob[i] > 1.0:
            favdecks[i] += 1
    

# print averaged probabilities

f = open('dealtvsfavdecks.txt','w');
f.write("# cards dealt | expected payout | number of favorable decks |" \
        " % decks that are favorable\n")
print "Average of", maxdecks, "decks"
for i in range(maxdealt):
    line = "%i %f %i %f\n" % (i, totprob[i], favdecks[i], \
            float(favdecks[i])/maxdecks*100)
    f.write(line)
    print i, "cards dealt, payout = %.6f" % totprob[i], ",\t", favdecks[i], \
            " fav decks (", float(favdecks[i])/maxdecks*100, "%)"
f.close()


# now, if we were to recognize all favorable decks and only play them...



I ran the script to deal 100,000 decks down to 2 cards left, or 50 cards, and then graphed the percentage of favorable decks (1.0+ expected return) against the number of cards dealt from the deck. The results are:

DealtvsFavDecks.jpg

Here we can see that there are a good number of favorable situations in which it would be wise to bet on the Royal Match. We will need a way to recognize these situations when they occur. To do this, further analysis of the characteristics of the deck during favorable situations is needed. The wild swing at the right side of the graph are due to only a small number of cards being left in the deck. If you have a situation where there are only 4 cards left, each of a different suit, then the probability of getting a match is 0%. On the other hand, if there are 4 cards left, all of the same suit, then the probability is 100%. So in a small number of cards the probability has a potential to swing wildly.

Syndicate content