Bingo Simulations – Long to Wait?
In this post, I share how I used Python to simulate games of Bingo, and experimentally produce the distribution of wait time before a full house is reached. This approach is similar to my exploration of Monopoly last Christmas.
Friday Night Bingo
Deep into Lockdown 2.0, our friends had long grown weary of weekly quizzes. We continue to hold them monthly, and fill the gaps with other activities. This month, virtual Bingo was up for trial. My housemate Lloyd and I settled down in front of one screen, opened up our Bingo Cards in Google Docs on another, laid out our Chinese take-away, and psyched ourselves up for for a night of competitive Bingo.
We lost the first couple of games, both for the line, and the full house. Our third game wasn’t going too well either. Our friend, and bingo host, Bernie seemed to be calling lots of numbers out that we just didn’t have on our sheet. And when we did, they rarely seemed to fall on the same line. I felt that our Bingo cards were unlucky – and I wanted to prove it.
I turned to Lloyd. “How many numbers do we expect to be called before we get a line (Horizontal or Vertical)? How about a full house?” Asking such a question in a room with a couple of maths grads was never going to be ignored. We sprang to the living room whiteboard (every living room should have one), and set about mapping the Bingo setup into a mathematical framework.
A Question in 2 Parts
There are a few different Bingo Card variations. That evening, we were playing on a 5 x 5 square card, with numbers from 1 up to 90, example below.
To attack the problem of expected calls before a line, we split the task into 2, and introduced a variable, T, the count of numbers that we have ticked off. In professional bingo circles, I think this is known as ‘dabbing’. (To be clear, dabbing is the process of ticking numbers off, and not the process of introducing variables called T, nor splitting tasks into 2…)
- How big will T be after c numbers have been called?
- How big will T be before we have 5 numbers ticked in a vertical or horizontal line?
With a good grasp on the framework of permutations and combinations, the first question is relatively straightforward. Excluding the cases where t > c (you can’t tick off more number than have been called!) or where c > 90 (There are only 90 numbers to be called out, at which point everyone has a full house and the game is over), the following formula gives the probability of having t numbers ticked when c numbers have been called.
Now, we turn to the second question – how many numbers can we expect to tick before we get our first line. Let’s start by calculating the likelihood of having a line when 5 numbers have been ticked.
While the first of these 5 ticks can land anywhere, the second then has only 8 available squares to ensure that it is on the same line or column, see picture below.
Once the first 2 squares are fixed, the 3 remaining are determined to fall on the 3 light yellow boxes in order to generate a line.
So, overall, the probability of a line after only 5 ticks is (25 x 8 x 3 x 2 x 1) / (25 x 24 x 23 x 22 x 21), which is roughly 1 in 10,000.
Okay, let’s move forward. How about the chance of having your first line after exactly 6 ticks?
The first tick can go anywhere as before. This time, however, the second and third tick doesn’t necessarily need to be confined to a set few squares. 6 ticks gives us a ‘spare tick to play with, there are 4 separate scenarios we need to consider.
To begin with, let’s suppose that the second tick goes on the same line or column as the first. There are 8 squares it could land on, shaded in light yellow on the below example.
Once the second tick has been placed, there are two scenarios: Either the third tick lands on the same row or column as one of the first 2 ticks, or it doesn’t. If it does, then there are 11 squares on which it could land, shade below.
In this scenario, once the third square is ticked, there are 6 squares which could be ticked 4th, shaded below. From here the final 2 squares are determined, up to order.
Hence in this first scenario, there are 25 x 8 x 11 x 6 x 2 x 1 possibilities = 26400. Let’s continue with the other scenarios.
In scenario 2, our second tick has landed in the same row or column as the first tick, but the 3rd tick does not land in the same row or column as either of the first 2 ticks. There are 12 squares the 3rd tick could occupy, shaded below.
In this scenario, once the 3rd tick has been placed, the final 3 ticks are determined up to order, shaded below. They must complete the line started by the first 2 ticks. There are 3 x 2 x 1 ways possibilities for these final 3 ticks.
Hence, in this second scenario, there are 25 x 8 x 12 x 3 x 2 x 1 possibilities = 14400. Let’s look at the other 2 scenarios, in which the second tick is not on the same row or column as the first.
By asserting that the second tick does not fall in the same row/column as the first, we have in essence ‘used’ our spare tick. The 3rd tick must fall in the same row or column as at least one of the first 2 ticks, else we can not get a line after only 6 ticks. The distinction between the final 2 scenarios is whether the 3rd tick falls in the same row/column as both of the first 2 ticks, or just one of them.
There are 2 squares in which it falls in the same row/column as both ticks, shaded below.
In this scenario, the 4th tick can land in any of the 6 squares shaded below, but the 5th and 6th squares are then determined up to order.
Hence, in this scenario, there are 25 x 24 x 2 x 6 x 2 x 1 = 14400 possibilities. Finally, let’s numerate the final scenario, where the 3rd tick falls in the same row/column as one of the first 2 ticks.
In this case, there are 6 possibilities for the 3rd tick, shaded below.
Then, with the 3rd square in place, the final 3 ticks are determined up to order, see example below.
So, in this final scenario, there are 25 x 24 x 6 x 3 x 2 x 1 = 21600 possibilities
Adding the possibilities of all 4 scenarios together, we arrive at the probability of getting the first line after exactly 6 squares have been ticked as (26400 + 14400 + 14400 + 21600) / (25x24x23x22x21x20), roughly a 6 in 10000 chance. Still very unlikely.
At this point (truth be told, even before I fleshed out this example), I could see this combinatoric approach was going to take time, as the number of scenarios would explode. Calculating the probability of getting the first line after exactly 11 ticks was almost a non-starter! It was time to code!
Python Bingo Simulation
Full code (Single and N player variants) available on my github: https://github.com/scottjenkins97/bingo_simulations
Initialising set up. I used a coordinate like system, so that I could iterate over the rows and columns easier than a 1-25 list would enable. I created two lists which were always the complement of each other (ticked squares and empty squares)
This next code block simulates another tick being added to a random square, so that this square is moved from empty to ticked. This continues until check for line is True.
Below is my function which checks for a horizontal or vertical line:
This code answers the question: How many ticks before a line. I then added a counter on the number of calls and a check whether the call appeared on our bingo card.
I set my simulation running for 10,000 games, here’s what I found.
But Nobody Plays Bingo by Themselves!
So far, we have a 1 player Bingo simulation, and have shown experimentally from 1 million games (separate running to the graphs above), that the expected number of calls before a line is 53, and that the expected number of calls before a full house is 87. Time to take it up a notch and build an n player Bingo simulation in Python.
N Player Bingo Simulation
Moving up to n players, I needed to be careful to keep track of all the variables – each player had a different bingo card, with their own set of ticked and empty squares. I turned to Dynamic Variable creation to help here:
Here’s what I found:
We see that as the number of players increases, the expected number of calls before a line or full house decreases at a decreasing rate
The wait before a line falls quicker than a the the wait for a full house. This means that as the number of players increases, there may be a greater tension produced before the card is won.
Theoretically, with enough players, the blue line will fall to 5 and the red line will fall to 25.
I also plotted the distributions. For each number of players I played 1000 games (so not very smooth). Though perhaps more difficult to explain, I like how effectively this compares set ups. More people = shorter games and less variance in game time.
E.g. with 100 players expect only 22 calls until first line with a standard deviation of 4.8 calls.
Some Mathematical Validation
We rushed into the n player simulation, but given our 1 player distribution, we could have have reached the answer another way: using statistics!
An extension could be to compare my simulated results to the above CDF relationship.
Takeaway – The Power of Simulation
From what was going to be a difficult combinatoric problem, this approach shows how a few hours of coding could churn through millions of games of bingo and provide some insight into the game mechanics.
An extension to this work could be to run similar analysis on the other popular card format. I expect that this card results in slower lines (only 3 options), but faster full houses (only 15 numbers)
Until next time,
Scott