Lottery Simulator in C#

The motto for the lottery is "You can't win if you don't play." I'm sure most of us have thought about what we would buy WHEN we win the lottery. My wife could tell you right now what she would do with the money, yet we might have played twice in our life. It all boils down to math. My dad used to explain the lottery in simple terms. Take an acre of land and fill it with pennies tails side up. To win the lottery, you would have to correctly choose the one penny that has a star painted on Lincoln's head. This puts the odds at about 1 in 11,151,360 (about 256 pennies can fit inside a square foot and there are 43560 square feet in an acre). When comparing those odds versus the Powerball lottery, you would actually need ~15.7 acres of pennies to match the odds (1 in 175,223,510).

Somewhere along my internet surfing, I came across a Powerball Simulator that helps visual how rare it would be to win and how long you would have to wait before you might hit the Powerball. The site has 3 speeds: Slow; Fast; and Max. The max speed is around 100 drawings every second. I liked the simplicity of game and wanted to create my own simulator in C#.

The first step was to clarify the rules.

  1. 5 balls are drawn from 1-59 (can be matched in any order)
  2. 1 Powerball is draw from 1-35 (must match exactly)
To help draw the numbers quickly, I wanted to make sure the thread didn't constantly generate duplicate numbers. I found a nice helper class at Stack Overflow for this specific case:
public static class RandomHelper
{
	private static int _seedCounter = new Random().Next();
	[ThreadStatic]
	private static Random _rng;
	public static Random Instance
	{
		get
		{
			if (_rng == null)
			{
				int seed = Interlocked.Increment(ref _seedCounter);
				_rng = new Random(seed);
			}
			return _rng;
		}
	}
}

I created a struct to help with easier readability. I could have just used an array with all of the balls, but comparing the first five regular numbers would have been more difficult:

public struct LotteryNumbers
{
	public int[] RegularNumbers;
	public int PowerBall;

	public LotteryNumbers(int[] regularNumbers, int powerBall)
	{
		RegularNumbers = regularNumbers;
		PowerBall = powerBall;
	}
}

Once I was able to consistently generate random numbers, I created a function to generate a set of lottery balls.:

private LotteryNumbers GetLoterryBalls()
{
	int[] result = new int[5];
	Random r = RandomHelper.Instance;
	for (int i = 0; i < 5; i++)
	{
		int foo;
		do
		{
			foo = r.Next(1, 59);        //1-59 for the regular balls
		} while (result.Contains(foo)); //no duplicate values

		result[i] = foo;
	}
	int powerBall = r.Next(1, 35);      //1-35 for powerball
	Array.Sort(result);                 //not necessary but makes displaying nicer
	return new LotteryNumbers(result, powerBall);
}

All of my drawings were quick picks, so I generated two sets of lottery balls and then compared their values to determine winners:

LotteryNumbers quickPick = GetLoterryBalls();
LotteryNumbers lottery = GetLoterryBalls();

int matchingNumbers = quickPick.RegularNumbers.Intersect(lottery.RegularNumbers).Count();
bool powerBall = (quickPick.PowerBall == lottery.PowerBall);

I'm able to generate about 300 drawings every second and still keep the UI updated fairly well. I ran it overnight and actually had 2 grand prize winners in less than 30,000,000 drawings. Playing 1 ticket twice a week, that would mean I would've won two grand prizes in ~288,000 years! Good luck next time you choose to play.

Show Comments