Don’t MADN – A game playing itself

I decided to write a program that plays a game without me having to interact. A simulator if you like. Here is a video of one run:

Many people know one or another variant of a game where you have to roll dice to move your pieces around a cruciform board like the British “Ludo” and American “Parcheesi”. All these games seem to be derivatives of the ancient Parchisi. The German Pachisi clone is called “Mensch ärgere dich nicht!”, and this is what my program is about. Because “Mensch ärgere dich nicht!” is is a bit of a mouthful (like all German names, some might say) I am going to abbreviate it to “MADN”. Funnily, MADN (“madden”) is the opposite of the German name’s meaning, which you can read about in this external blog post. MADN is a good game to play with children. They can practice their counting and vigilance – there is an optional rule where, given the opportunity, one must kick out other players’ pieces or receive a penalty. Overall however, MADN is not the most exciting game or complex game, its outcome largely depending on chance. A good object to simulate.

Simulation programmes are great for people who are interested in data (like me). They can help one to analyse the properties of a process (like the MADN game) and to test the effect of different parameters on the process’s outcome. Using my MADN simulator, many iterations of the game can be run in little time – much faster than observing players in the real world. In MADN, the most important parameter is probably whether a player prefers kicking or running. That is, whether they prioritise kicking out other players’ pieces or whether they try to move their own pieces into their protected goal range as fast as possible. In my simulation, there are two extreme kinds of player, a “k” player (kicker) will always kick out another player’s piece if possible. An “r” player (runner) on the other hand will run as fast as possible to their home range always choosing their furthest-ahead piece (other rules permitting). Doing so, an “r” player may occasionally kick out another player’s piece, but this is not their priority. So, what have I learned?

A screenshot of the MADN simulator. It’s player 3’s turn (colour CYAN). They’ve rolled a 4 and have moved a piece into their protected goal range (near the centre of the board). CYAN has two more pieces, which are outside the game at the moment (bottom-right corner). Upon rolling a 6, they can move one of these onto their starting field (larger field on the right-hand margin of the board).

MADN stats

Length of game

The first thing I investigated was the length of the game. A game ends when three out of four players have managed to get all their pieces into their respective home range (see histograms and table below). This differed considerably depending on whether it was a game of kickers (blue) or runners (orange). Running 10,000 replicate games for each strategy, I found the median game length (after which half of all games had finished) was 391 for all-runner games, but 512 for all-kicker games, over 100 more turns. So, if you want a quick game, then players should not kick out each other.

Two histograms showing the distribution of game lengths depending on players’ strategies (10,000 replicate simulations each).
Player strategiesMedian game length (turns)95% of games ended within this range of turns
All runners391(299, 518)
All kickers521(368, 754)

Number of kicks

I then wondered how often players kick one another out of the game. Obviously, that depends on the respective player’s strategy. The results are shown in the two plots below. The players are named 1 through 4 starting in the board’s top-left corner and going around clockwise. As players have to move their pieces in clockwise direction, it would seem quite likely that players often kick out pieces of the player ahead of them if these are a bit slow (player 1 kicks player 2, player 2 kicks player 3, etc.).

The plots below show the kicking player (“Who”) along the rows and the one kicked (“Whom”) along the columns. The mean number of kicks per game for any player combination over 10,000 games are shown after the μ signs. To get an idea of the variability of these numbers between games, I also added standard deviations (given after the σ sign). Looks like our prediction holds. No matter which strategy, players tend to kick the ones ahead of them most (lightest colours). The further order depends on the strategy. If all players are kickers, they tend to also kick out the player behind them while the player opposite receives the fewest kicks. If all players are runners however, then there is not much difference between “behind” and “opposite”.

The black plot margins have the column and row sums, showing for each payer how often, on average, they kick (rows) or are kicked (columns). The bottom-left cell gives the average total kicks per game. Unsurprisingly, these averages are higher for all-kicker games than for all-runner ones. Also, the number of kicks passed is equal to the number of kicks received. It might be interesting to see how this would change if different players had different strategies.

Where do kicks happen

The last point I want discuss is where, on average, kicks happen on the board. For this, I recoded the board positions of kicks subjectively for every player. Some MADN background – when a player rolls a 6, they can move a new piece onto their respective starting field (player field 0). They then move their pieces clockwise according to the numbers rolled up to their player field 39. The next four fields, 40 through 43, are payers’ protected goal ranges, where they cannot be kicked out. The distribution of kick fields (histograms below) looks quite interesting, I think. The field where most kicks are handed out, no matter what strategy, is the start field (player field 0). This is probably because every piece of a player hits this field at least once. Other fields may be jumped over and are thus safer.

Most kicks a handed out on a player’s start field (0).

The part of the board where most kicks are received are the six fields immediately after the start field (fields 1-6, histograms below). This is probably because pieces tend to sit around there. If a player has multiple pieces in the game, they tend to move their furthest-ahead one to get it into their protected range (except if the player is a kicker and there is a kicking opportunity). Because the MADN rules require players to move their pieces off their own start field, pieces tend to hang around one roll-of-a-die ahead of the start field – perfect kicking fodder. Other fields where kicks are commonly received are the other player’s start fields (10, 20, and 30).

The fields where players have their pieces kicked out of the game most often are immediately after the start field (1-6). Pieces are also frequently kicked out from other players’ start fields.

Can we make use of this knowledge? I reckon if players where to move their pieces off the dangerous fields 1-6, then they would be kicked elsewhere, probably not reducing the number of kicks they receive. It looks to me though that it would be a good idea to avoid moving onto other people’s start fields. I am looking forward to extending my simulation to include this strategy. Perhaps there will be an update on this post in the future!

Implementation

My MADN code is a Python package, available on GitHub. I started this project after I had talked to a friend who was doing a Python programming course and I decided that I wanted to brush up on my own Python skills. This is probably the first time that I have used classes in Python. MADN can be used as a Python package to run the MADN simulation and to collect outcomes. The code can also be run non-interactively plotting the status of the board to the terminal. This is how I made the video. The data presented here were generated with the v1.0.0-beta2 version.

The analysis code is on GitHub too, written in Julia, a high-performance language, which I am quite fond of. Using the Julia package PyCall.jl, I ran many replicate simulations and collected their results. One might object that the simulations running in (relatively) slow Python sort of defeats the purpose of Julia here. But then there are loads more package available for Python at the moment than for Julia. So, getting to grips with PyCall.jl was a useful experience.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s