5.8. Mathematical Games#

Many games that people play for pleasure have mathematical aspects. Indeed game theory is a field of mathematics.

We can identify properties of games mathematically and via computer simulation. In this section, we focus on modeling, simulation, and visualization of the results of a few games that involve randomness. The goal is to get insights into the likelihoods of different outcomes, given rules, rather than actually to engage in games for pure entertainment. No prior familiarity with the games is assumed, and we do not include any betting, which some people consider morally objectionable.

5.8.1. Craps#

The game of craps uses two six-sided dice. The rules for two versions of the game are as follows:

  1. “Pass Line”:

  • If the first roll is a 7 or 11, you win.

  • Otherwise, if the first roll is a 2, 3, or 12, you lose.

  • In all other cases, the specific number rolled is “the point”, and you roll again until one of the following outcomes:

    • If you roll “the point” again, you win.

    • If you roll a 7, you lose.

  1. “Don’t Pass”:

  • If the first roll is a 7 or 11, you lose.

  • Otherwise, if the first roll is a 2, 3, or 12, you win.

  • In all other cases, the specific number rolled is “the point”, and you roll again until one of the following outcomes:

    • If you roll “the point” again, you lose.

    • If you roll a 7, you win.

If you neither win, nor lose, we call the result a draw or a tie.

We can implement these two versions of the game in Python. We see possible output below.

def roll_two_dice():
    die1 = random.randint(1, 6)
    die2 = random.randint(1, 6)
    return die1 + die2

def pass_line():
    roll = roll_two_dice()
    if (roll == 7) or (roll == 11):
        return "win"
    elif (roll == 2) or (roll == 3) or (roll == 12):
        return "lose"
    else:
        the_point = roll
        roll = roll_two_dice()
        if (roll == the_point):
            return "win"
        elif (roll == 7):
            return "lose"
        else:
            return "draw"

def dont_pass():
    roll = roll_two_dice()
    if (roll == 7) or (roll == 11):
        return "lose"
    elif (roll == 2) or (roll == 3) or (roll == 12):
        return "win"
    else:
        the_point = roll
        roll = roll_two_dice()
        if (roll == the_point):
            return "lose"
        elif (roll == 7):
            return "win"
        else:
            return "draw"

print("Pass line:")
print(pass_line())
print("\nPlay again\n")
print("Don't pass:")
print(dont_pass())
Pass line:
draw

Play again

Don't pass:
lose

Explore these two versions of the game craps in the Exercises section.

5.8.2. Choosing the Right One#

Consider the following problem:

You arrive at a hotel and are invited to walk down the hall and choose what you consider the best out of \(n\) rooms. The rooms are varied with no underlying organization. You will view them one-by-one, and the person in charge says you must accept or reject a room immediately after viewing it because a stream of others seeking lodging is coming in behind you. If you have not accepted a room before you reach the end of the hall, you will get the last of the \(n\) rooms.

Problem: How can you maximize the chance that you will accept the room you consider the best?

Optimal stopping problems like this one arise in various contexts, including financial markets (choosing when to sell stock in an \(n\)-day period), housing markets (choosing when to sell a house in an \(n\)-day period), and hiring or marriage (selecting someone when \(n\) candidates “dribble in” sequentially).

Notice that if your strategy is to pick a room at random, your chance of getting the best room is \(1/n\). If your strategy is to choose the first, second, last, or “middle” room, your chance of getting the best room is also \(1/n\). For larger values of \(n\), this strategy performs increasingly poorly.

An insight here is that you can benefit from a “preview process.” Set a strategy in which you preview \(r\) rooms (rejecting each one) and record the maximum score \(m\) from the preview set. Then pick the first room with a score that is better than \(m\).

For example, suppose \(n = 10\). Previewing \(r\) rooms is possible if \(0 \le r < n\). Suppose your strategy is to preview \(r = 3\) rooms. If the scores for the rooms are [67, 91, 85, 92, 2, 71, 32, 56, 37, 34], then \(m = 91\). The first room with a score better than \(m\) is the fourth room with a score of 92. In this case, the strategy yielded the best room.

We can explore the game of choosing the right one with the following algorithm:

# 1. Generate a list ratings of n rooms, from 0 to 100.

# 2. Define the number_rooms_to_preview as int(0.37 * n).

# 3. Find max among the first 37% by looping through the rooms to be visited.

# 4. While rooms still remain to be visited,
# and the rating does not surpass the first 37% of ratings,
# advance to the next room:
# while (i < n) and (ratings[i] <= max):
    # i += 1

# 5. Once you exit the while loop, if you haven't reached the final room,
# if i < n:
# then you have found a room that surpasses the first 37%.
# You found the first rating that exceeds max, so assign that rating as your choice:
    # choice = ratings[i]

# 6. Otherwise, you have been through all the rooms, and you must take the last room:
# else:
    # choice = ratings[n-1]

# 7. Sort apartments best to worst:
# ratings.sort(reverse = True)

# 8. Find the index of your choice in the sorted list
# to get the rank of your chosen room (1 <= rank <= n):
# rank = ratings.index(choice) + 1

# 9. Append the rank of the selected apartment into a list.

# 10. Plot these ranks in a histogram.

Explore this algorithm for choosing the right one in the Exercises section.

5.8.3. Coin-flipping Game#

Suppose you have a coin to flip and \(n\) tokens. In this game, you put a fraction \(F\) of your tokens (\(Fn\) tokens) on the table, \(0 <F \le 1\). You choose either heads or tails for the game, for example heads. Then you flip the coin. If it comes up with your choice (heads), then you win \(Fn\) additional tokens. If your choice is wrong (the coin comes up tails), then you lose all \(Fn\) tokens. Repeat the process, each time using the same fraction \(F\) of the number of tokens that you now have and using the same coin-flip choice (in this example, heads). Do this until you lose all your tokens or up to a maximum number of flips, for example 30, whichever comes first.

Example: You start the game with \(n=100\) tokens. You decide that you will put down \(F = 1/2\) of your tokens for each turn, use heads as your guess, and play until you lose all your tokens or up to a maximum of 30 flips, whichever comes first. As such, you put 50 tokens on the table. You flip the coin. It comes up heads, so you win 50 tokens. Therefore, you have 150 tokens altogether (150 points). So, next you put 75 tokens on the table. You flip the coin. It comes up tails, so you lose the 75 tokens. Now you have 75 tokens (75 points) altogether. In one version of the game, points must be positive integers, so you chose a convention for rounding up or rounding down when the number of tokens \(Fn\)is odd. In another version, fractional points like 37.5 are allowed. We could simulate a continuation of the game with one of these conventions to determine how many points you have at the end of the game.

It has been mathematically established that a winning strategy to maximize your points is to put down the optimal fraction \(F\) of your tokens, given by the Kelly criterion as

\[F = \frac{bp – 1 + p}{b},\]

where \(p\) is the probability of winning, like \(p = 0.5\) for heads, \(1 − p\) is the probability of losing, and \(b\) are the odds in the game. For example, odds \(b = 1\) means “put down 1 and win \(b = 1\) points” (or lose \(b = 1\) point).

Explore this game in the Exercises section.

5.8.4. Exercises#

Exercises

Exercise 1: For the game of craps, does the choice of “Pass Line” vs. “Don’t Pass” affect the likelihood of winning, under the rules given? If so, what kind of difference and how much difference? Use quantitative information to support your answer. State whether you have provided mathematical proof or computational evidence.

Exercise 2: If one of the two dice is biased in the game of craps, how does that affect the analysis and conclusions from Exercise 1? Illustrate your answer by doing some simulations and discussing the results.

Exercise 3: Simulate the optimal stopping problem for ten rooms using the algorithm discussed in this section. Execute many trials. (a) Explain whether you typically get the best room or not when you preview three of the rooms. (b) If you don’t get the best room, how good of a room do you typically get? (c) Show a histogram of the ranks of the rooms you choose. Do the shape, center, and spread of the ranks suggest that the strategy (algorithm) is a good one for winning the best room? Explain. (d) Does the strategy of previewing three rooms tend to lead to a better outcome than if you preview two or four? Support your answer. (e) It can be shown mathematically that the optimal fraction of the total rooms that you should preview is \(1/e\) as \(n\) gets very large. The probability that you will select the best room this way is also \(1/e\) for large \(n\). Are your simulations consistent with these results? Explain.

References#

Dekking, F.M., Kraaikamp, C., Lopuhaa, L.E., Meester, L.E. 2005. A Modern Introduction to Probability and Statistics: Understanding why and how. The Netherlands: Delft.

Guttag, J.V. 2021. Introduction to Computation and Programming Using Python (3E) Cambridge, MA. The MIT Press.