Photo by Robert Zunikoff on Unsplash

Dreidel Analytics

Moneyball for Ancient Gambling

--

Introduction

Like Disney’s Olaf sings (and is more or less singing continually at my house these days) “It’s _that_ time of year!” If you are Jewish or have a multicultural elementary school education influencing your household you might be exhorted to play some dreidel this weekend. What you can’t learn from Wikipedia is that the key to enjoying dreidel as determined by extensive analysis is to play with only 3 markers per player.

Personally, I think you should skip playing dreidel entirely and just eat the markers. But maybe playing dreidel makes you smell the wood smoke and mutton of a Maccabee camp and builds a connection to a young guerilla fighter nervously debating if he’s a freedom fighter or a militant fundamentalist . Or maybe you celebrate with kids who just will not eat their dang candy already.

In these cases you need to play, and play without frustration, so you can get back to more enjoyable parts of the holiday experience. Controlling game duration is the most accessible lever for keeping the game fun and it turns out that game length varies strongly by the number of markers available to the players. If you just want see why 3 markers and not (heaven forbid) 4, skip the approach section and get right to the results. If you want to see the inner workings, read on.

Approach

Let’s simulate game play to determine the relationship between the number of starting counters and the number of turns needed to complete the game. Along the way we will check the game for fairness (spoiler alert: Wikipedia is right; dreidel is not fair).

To simulate the game in R, we’ll build a new class ‘gameState’ that will record the state of the game after any given spin of the dreidel. That means it will track the number of counters each player has, the number of counters in the pot, the turn number, the player whose turn is next, and the number of players in the game and the number of players still having counters. We’ll make it a class so we can create a convenient print method to improve debugging and general usability of the gameState object.

This is relatively straightforward, and looks like this:

Now that we’ve got the class defined, we’ll need a method that updates the state of the game based on a dreidel spin. Let’s map the traditional {ג,ה, נ,ש } dreidel sides to {4,3,2,1} and use the integers as input to see how to update the current user’s holdings and the pot’s value, add one to the turn number, and then recount the number of players still in the game. In case we want to change the rules by varying the value of the ante, let’s include that as an input into the takeATurn function.

That function turns out to have quite a bit more fiddly bits than I expected. Most of those fiddly bits are in place to prevent infinite looping for corner cases that don’t ever happen for a ‘real’ game. There is probably a fundamental programming lesson in that, but let’s stay focused on figuring out how to play dreidel enough without playing too much.

Now that we can play a single round of dreidel, it’s pretty easy to play dreidel until only one player is left. To simplify our simulation call, let’s make a new function called runGame, which just repeatedly spins a dreidel (ceiling(runif(1,0,4)) calls takeATurn() until only one active player is left, returning the final gameState. To enable some analytics on the simulation results, runGame should take inputs that allow the creation of different games — e.g. number of players and the number of counters each player gets — as inputs.

Simulating 10,000 games feels sufficient to understand how many turns a game is likely to take. Because that many iterations can take a lot of time, we should run those games on multiple cores using foreach and doParallel packages. Here’s a loop to simulate games for varying numbers of players and the starting number of markers (per player):

Results

Charting the median number of turns against the starting number of tokens, we can see why all those past dreidel games ended in eating the markers early. Four players and 10 markers is giving a median time of 400+ spins!

But let’s look at 3 markers. even with 10 players (and surely we could make two games of 5?) a median game is 300 spins. For a more typical game of 4 players, the median time is less around 20 (22 in my simulation). That’s 5 spins each (for a median game), and that’s enough to satisfy everyone’s desire to spin a dreidel but not so many spins that you just have to eat all your markers to leave the game.

But what about the unfairness bit? That actually turns out to be pretty complicated. It appears there is some relationship between the number of markers per player, the number of players, and which player has the advantage.

Instead of understanding all of that we can focus on the preferred starting value of 3 and feel good that the simulation results return very near a fair value of 1 for all tested values of the number of players.

Conclusion

Dreidel has persisted not because it’s entertaining, but because it’s tradition. Given that tradition has an inescapable gravity during the holidays, applying some analytics to optimize how we handle tradition is an excellent way to get ready for ‘that time of year.’

From this simple simulation, we can see that a nice ~5 spins per player dreidel game requires starting with many fewer tokens than most players use (start with 3!). We can also see that if we want to steal all of the kids’ candy we should play in large groups of players, go first, and use 2 or 4 markers.

If you want to run your own dreidel simulations, you can grab the entire code used in this article from here.

I hope your holidays are cheerful, fun, and dreidel-frustration free.

--

--

I’ve been untangling data and what it implies since before data science was a thing. Currently using analytics to advise the c-suite at a healthcare company.