2
votes

So I have A and B play a game which begins with A tossing a coin. If it shows head, A wins and game over. Else, B tosses and if B gets a head, B wins and game over. Basically, the game continues until whoever's coin shows a head first.

Theoretically, the probability of A winning is 2/3, and the probability of B winning is 1/3. Referenced here

I'm trying to simulate this in Python, running 4000 simulations. However, I'm not really getting close to 2/3 for A and 1/3 for B. Below is my code:

import random

Atoss = 0
Btoss = 0

Awins = []
Bwins = []

for i in range(4001):
   head = False
   while (not head):
      A = random.randint(0, 2)  # random 0 and 1
      Atoss += 1

      if A == 1:
         head = True
      else:
         B = random.randint(0, 2)  # random 0 and 1
         Btoss += 1
         if B == 1:
            head = True

   totalToss = Atoss + Btoss
   Awin = Atoss / totalToss
   Awins.append(Awin)
   Bwin = Btoss / totalToss
   Bwins.append(Bwin)

probA = sum(Awins) / len(Awins)
probB = sum(Bwins) / len(Bwins)

print("Probability A: ", probA)
print("Probability B: ", probB)

Did I mess up somewhere?

EDIT:

Changing randint(0, 2) to randint(0, 1) solves the problem, as answered by @bart cubrich

2
Your Awin/Bwin/Awins/Bwins computations don't look anything like how victory in the game is defined. - user2357112
yeah I thought that doing # of tosses / total tosses is not right, but I couldn't figure out how to "code" it like I had it on paper - PTN
The main error is this code is a typo, so maybe deserves a downvote, but it's a cool problem, and generally I liked your solution. Plus you were upfront with that fact that it could just be a mistake. Definitely don't need to keep track of the number of tosses, but it's interesting to see how many more tosses are needed that for loops. - bart cubrich

2 Answers

2
votes

One problem you have is that the random.randomint should be

A = random.randint(0, 1)  # random 0 and 1
B = random.randint(0, 1)  # random 0 and 1

Your version was producing zeros, ones, and twos. That was totally messing up the chances of getting a heads, since you were really rolling a 3 sided die with sides=[0,1,2], where only a "1" wins. Trying the following:

import random
random.seed(123)
Atoss = 0
Btoss = 0

Awins = 0
Bwins = 0

for i in range(4000):
   head = False
   while (not head):
      A = random.randint(0, 1)  # random 0 and 1

      if A == 1:
         Awins+=1
         head = True

      else:
         B = random.randint(0, 1)  # random 0 and 1
         if B == 1:
            Bwins+=1
            head = True



probA = Awins / (Awins+Bwins)
probB = Bwins / (Awins+Bwins)

print("Probability A: ", probA)
print("Probability B: ", probB)

Out:
'Probability A:  0.6653336665833541'
'Probability B:  0.3346663334166458'

I get that the probability is ~A:66% B:33%.

Note, in the documentation from random.py

random.randint(a, b) -Return a random integer N such that a <= N <= b.

which is different than the numpy.random.randomint which gives

-a random integer N such that a <= N < b

Documentation is here

1
votes

Your Awin and Bwin computations say that if A wins on the 5th toss, then since A tossed 3 times and B tossed 2 times, A gets 3/5 of a win and B gets 2/5. This is not how victory is supposed to work.

Also, you want random.randrange, not random.randint, and your placement of the Atoss and Btoss initialization before the loop instead of inside the loop means they don't reset on a new iteration. (The toss counts are unnecessary in a correct implementation, though.)