On this page you can play against a neural network modeled on the chess engine AlphaZero but trained to play the much simpler game of mū tōrere. Mū tōrere is a Māori board game for two players with the following rules.
- Players take turns, starting with white, moving one of their pieces to an adjacent empty point.
- A player wins when their opponent can make no legal move on their turn.
- Neither player may make a winning move in the first two turns (two moves by each player).
- The game is a draw when neither player has won after both have made 25 moves.
Without a rule like #3 above, White wins on the first turn. Of several candidate rules to prevent this outcome, rule #3 leads to the best gameplay. Rule #4 is arbitrary.
Loading Model...
From time to time, by such means as clicking a few links on Wikipedia, I come across an old or uncommon board game which I can tell will not become my next favorite, but which I would like to get a feel for by playing a match or two against a skilled opponent. Mū tōrere is such a game. The number of meaningfully distinct game states is quite small, and so it is not hard to generate an algorithm which plays flawlessly, but training a neural network in the style of AlphaZero to play the game perfectly is, while overkill, a little more interesting. I trained a few such models, but the one which runs on this page is a ResNet very similar to the chess-playing ResNet of AlphaZero.
The AlphaZero recipe is to set up a ResNet with policy and value heads to pick moves by Monte Carlo tree search, and to train this network from scratch by having it play itself repeatedly. We can represent the mū tōrere board to the network in any number of ways, but the way which seemed most natural and elegant to me is to unroll the board into an 8x2 rectangle, which then flows through 1-dimensional convolution layers using circular padding (represented below in grey) so that the network sees the adjacency of the perimeter positions that were separated when we unrolled the board.
After training the ResNet for 1000 games of self-play, I found that in cases where its opponent had fumbled and handed it a winning board, it did not always reply with the winning move. Seemingly it had not encountered such fumbles often enough in its training. The fix was to train it for another 1000 games on a 50/50 mix of the same self-play (so that it would not forget what it had learned) and practice games where it started in a winning position. The fine-tuned model played flawlessly, though it did now assign small nonzero probabilities to illegal moves. As this imperfection is harmless, I let it be.
Because the search tree is so small, the success of the MCTS is somewhat overdetermined: adding noise to just the value head or just the policy head is not enough to cause the model to fumble. But both adding Gaussian noise with standard deviation 10, 15, or 20 to the policy head logits before applying softmax and adding Gaussian noise with 1/10 that magnitude to the output of the value head and then clamping the result to [-1, 1] together suffice to cause the model to play increasingly poorly, creating the AI strength levels you see above.