6
$\begingroup$

Suppose there're two players $A$, $B$ playing a dice game, $A$ has a normal dice whose faces are numbered 1 to 6, $B$, on the other hand, has a (regular) icosahedron dice with faces numbered 1 to 20. Each round, $A$ rolls its dice 3 times and get the sum as his score, whereas $B$ rolls only once and get the result as his score, and the one with the greater score wins and gets 1 point. If scores are equal, then they both get 0.5 points. Is this a fair game?

A quick calculation shows that the expected scores for both players are 3.5, so it looks like it's perfectly fair. But to my surprise, when I was doing a Monte Carlo in Python, the programmed told me, out of 10^5 simulations, $A$ has only around 48.x% of the total 10^5 points, and such a 1.x% disadvantage was consistent across several tests.

Now move on to a more complicated version. This time let's introduce a new player $C$, who plays by exactly the same rule as $B$ does. Again, each round the player with the highest score wins; if two player has equal scores that are higher than the third player's, then they both get 1/2 points; and if all three have equal scores then they all get 1/3 points. Is this a fair game?

I thought with a firm "yes" for the same reasons as previously. But the simulation results totally astounded me, much more than the previous 1.x% discrepancy: now in the 3 player game, out of 10^5 simulations, the player $A$ only gets about 27.x% of the points, whereas $B$ and $C$ both get about 36.x% - $A$ has an almost 9% disadvantage!

I know to get everything clear it's best to explicitly compute the probability distribution case by case, and admittedly it's not hard in any technical sense. But, before doing that, is there any easy explanation about the discrepancies between intuition and reality as shown above? Thanks!

Attached below is the code:

import random
import numpy as np
import pandas as pd

def get_A_score():
    return sum(random.randint(1, 6) for i in range(3))


def get_B_score():
    return random.randint(1, 20)


if __name__ == '__main__':
    n_sim = 100000
    A_wins = 0.0
    for i in range(n_sim):
        if get_A_score() > get_B_score():
            A_wins += 1
        elif get_A_score() == get_B_score():
            A_wins += 1/2   # in case of equal numbers
    print(A_wins / n_sim)

    print()

    wins = np.array([0.0, 0.0, 0.0])
    for i in range(n_sim):
        A_score = get_A_score()
        B_score = get_B_score()
        C_score = get_B_score()
        scores = np.array([A_score, B_score, C_score])
        winner_index = np.argwhere(scores == np.amax(scores))
        n_winners = len(winner_index)
        wins[winner_index] += 1 / n_winners

    print(wins / n_sim)
$\endgroup$
6
  • 5
    $\begingroup$ Just checking expectation is insufficient. Say each of us has a three sided die. Yours has $5$ on all sides. Mine has $2,6,7$. We both average to $5$, but I win two tosses out of three. $\endgroup$
    – lulu
    Sep 19 '18 at 11:15
  • 2
    $\begingroup$ For this particular problem, if I understand the description correctly, both the distribution of $A$ and $B$ are symmetric with the same mean, which is also the median at $10.5$. So $\Pr\{A > B\} = \Pr\{B > A\}$. But what lulu said is correct - the argument itself is insufficient. I have checked once with R and it gives pretty close to $50\%$ so I am not sure which python code you got wrong - or I misunderstood the problem. $\endgroup$
    – BGM
    Sep 19 '18 at 11:29
  • $\begingroup$ @BGM thanks. Did your simulation indicate $A$ was consistently disadvantaged, despite being pretty close to 50/50? And if possible, could you also check the second game? $\endgroup$
    – Vim
    Sep 19 '18 at 11:32
  • $\begingroup$ @lulu thanks. This is a very good point. But as BGM said, in my game all players have symmetric distributions. $\endgroup$
    – Vim
    Sep 19 '18 at 11:34
  • $\begingroup$ Why are you importing Pandas? You don't seem to be using it. And you don't really need Numpy for this either: it's not going to give a speed boost when working with 3 scores. If your code were plain Python it would be runnable by a much larger number of users of this site. $\endgroup$
    – PM 2Ring
    Sep 19 '18 at 11:54
2
$\begingroup$

In the second case. If A and B both roll above the mean, then B tends to win. If they both roll below the mean, then A tends to win.
So for three players, A needs both B and C to roll below the mean, or one chance in 4.

$\endgroup$
2
$\begingroup$

The first game is fair by a symmetry argument: there is an involution on the set of possible outcomes that replaces the result $i$ of each ordinary die by $7-i$, and the outcome $k$ of the icosahedral die by $21-k$, and under this involution the gains of the players are interchanged; therefore there expected gains are equal.

However for the three-player game no such symmetry applies, and in fact it is not fair. If every one of the $20\times20\times 6^3 = 86400$ outcomes should come up exactly once (that it one outcome for every second in a day), the gains would be $31446$ for each of the icosahedral players, but only $23508$ for the three-dice fellow. While among each pair of players either has equal change of beating the other, the ones with flatter distributions of their outcome have a markedly better chance of beating both other players at once.

$\endgroup$
2
  • $\begingroup$ Thanks. But doesn't one with flatter distribution also have a better chance to lose to both others? $\endgroup$
    – Vim
    Sep 19 '18 at 15:55
  • $\begingroup$ Yes, that is of course true. But there is no specific penalty for losing (coming third). If there were, and it were equal but opposite to the prize for coming first, then the 3-player game would be fair at least as far as expected value goes. $\endgroup$ Sep 19 '18 at 17:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.