Solving Dōbutsu Shōgi
Dōbutsu shōgi (“animal chess”) is a children’s shogi game on a 3×4 board with eight pieces. It has been completely solved: with perfect play, the player who moves first loses.
A professional shogi player, Madoka Kitao, designed it in 2008 to teach the game to children. In 2009, Tetsuro Tanaka computed the exact value of every reachable position. The second player wins, in 78 plies.
This post covers what the solution turned up and why such a small board produces a deep game. The depth traces to one rule from shogi that most small abstract games omit: captured pieces return to play.
Source: Tetsuro Tanaka, “An Analysis of a Board Game ‘Doubutsu Shogi’” (IPSJ SIG Notes, Vol. 2009-GI-22, 2009). NII permalink
Explore the full solution below. Every legal move is coloured by its result under perfect play, from any position you can reach.
Green wins, grey draws, red loses; the badge is the distance to mate. Drag a piece or click a move to follow a line.
The game
Each player has four pieces: a Lion, a Giraffe, an Elephant, and a Chick, set up as mirror images of each other. The dots on each piece mark the squares it can step to.
Moves
Each piece moves one square per turn:
- Lion: any of the 8 directions (a chess king).
- Giraffe: one square horizontally or vertically.
- Elephant: one square diagonally.
- Chick: one square straight forward. Advancing onto the far row promotes it to a Hen (one step in any direction except the two back diagonals). A chick dropped onto the far row does not promote, so it is stuck there.
Drops
Each turn, you either move a piece or drop one. When you capture a piece it joins your hand, and on a later turn you can drop it onto any empty square as your own. Captured pieces switch sides instead of leaving the board. This is shogi’s signature rule, the one chess lacks.
Winning
Two ways to win: capture the opponent’s Lion, or get your Lion to the enemy’s back rank, onto a square the opponent can’t immediately capture (a Try).
The result
Dōbutsu shōgi is strongly solved: a lookup table (a tablebase) holds the exact value of every reachable position, so a program with it plays perfectly from any position, not just the opening. Tanaka built the table by working backward from finished positions, covering every position the game can reach.
The starting position is a second-player win in 78 plies (a ply is one player’s move, so 78 plies is 39 moves each side). The first player loses to zugzwang: every move worsens the position, and passing isn’t allowed, so moving first is itself the disadvantage.
You can watch that 78-ply game play out, one perfect move at a time, to the lion capture that ends it.
I reproduced this from scratch in Rust, a rules engine and a retrograde solver. Enumerating from the start recovers Tanaka’s reachable count exactly, 246,803,167 positions (99,485,568 non-terminal), once I matched his position-counting convention (a Try resolves one ply later). Position values are checked against Robert Clausecker’s open-source dobutsu, an independent complete solution, with zero mismatches on the 50,000 I sampled. The starting position evaluates to #-78 (the side to move is lost in 78 plies), and its four legal first moves all lose:
Gc4-c3 : #-78
Lb4-c3 : #-78
Lb4-a3 : #-78
Cb3xb2 : #-76
The full solution, in numbers (Tanaka’s figures; my enumeration reproduces the position counts exactly, the value split is his):
| Quantity | Value |
|---|---|
| Reachable positions | 246,803,167 |
| Non-terminal positions | 99,485,568 |
| Wins / draws / losses (side to move) | 56,474,473 / 2,682,700 / 40,328,395 |
| Average legal moves per position | 9.4 |
The compute footprint is small enough to rerun on one machine. Tanaka’s 2009 run used a 2.6 GHz Opteron box with 16 GB RAM: about 19 minutes to enumerate positions and 5.5 hours for retrograde analysis. My Rust rerun on Apple Silicon took about 75 minutes and about 7 GB RAM, wrote a 2.14 GB sorted-record tablebase, then packed it to a 333 MB compact table. The live explorer serves that compact file through a probe process that holds about 400 MB resident.
That first pass leaned on a hash map spread across 8 GB, which is why it ran far slower than Clausecker’s reference solve (about a minute, 167 MB). His version gives each position a computed address built from its contents: which pieces are in play, where the two lions sit, how the rest are arranged. Nothing is hashed, so the whole table is one contiguous byte array. Porting that index brought my solve to 243 MB and 3.5 minutes, faster and smaller at once, since random access across 8 GB thrashes the cache and a packed array does not. The values come out identical, checked against Clausecker’s probe to the ply. Reaching his exact 167 MB needs one more symmetry he folds and I have not, which is bookkeeping more than insight.
Notable findings
Beyond the headline result, a few things stand out.
Wins finish fast, with a long tail. Most won positions end within 15 plies; the deepest forced win runs 173 plies, far past the opening’s 78, reached by only 14 positions. The chart counts won positions by distance to win on a log scale: a steep drop after a few moves, then a thin tail stretching out to 173.
That deepest win starts from the position below, where the side to move is down material and still wins, 173 plies later:
Explore this position in the tablebase →
In 68 positions, the only winning move is to drop a chick where it can’t move. A chick on the opponent’s back row has no square ahead of it, so the drop barely changes anything, close to passing a turn. Yet every other move loses, and that near-pass is the one that wins. The position below circles the only saving drop.
Explore this position in the tablebase →
A few more findings, without diagrams:
- Often only one move wins. In about a third of won positions a single move keeps the win; every other move loses it.
- Zugzwang is common. The opening isn’t a special case: at least 21,839 positions are traps where moving loses but passing, if it were allowed, would hold.
- About 30% of won positions contain a forced mate, and the mates stay short: the longest is 23 plies.
Take the drop rule away
The depth has a single suspect: the drop rule. Captured pieces come back, so material never leaves the board, and the position keeps recombining instead of thinning out toward an endgame. To check that drops really are the cause, I re-solved the game with the rule removed, captured pieces leaving the board as in chess. It collapses. Reachable positions fall from 246,803,167 to 962,894, and the deepest forced win from 173 plies to 37. The opening flips too: the first player, lost in 78 in the real game, now draws. Same board, same eight pieces, one rule pulled out. (No external solver covers this variant, so it rides on the machinery I validated on the standard game.)
| With drops | Without drops | |
|---|---|---|
| Reachable positions | 246,803,167 | 962,894 |
| Deepest forced win | 173 plies | 37 plies |
| Opening value | second player wins in 78 | draw |
Conclusion
Twelve squares and eight pieces, solved to a 78-ply forced win with a tail running out to 173. A small game runs deep when its material recirculates.
Resources:
- Tanaka, “An Analysis of a Board Game ‘Doubutsu Shogi’”: the original solve (Japanese).
- brianhliou/dobutsu-shogi: my from-scratch Rust solver and the explorer.
- clausecker/dobutsu: Robert Clausecker’s independent open-source solution — the complete tablebase my solver is checked against.
- Piece and board artwork © Maiko Fujita (藤田麻衣子), from Dōbutsu Shōgi (どうぶつしょうぎ / “Let’s Catch the Lion!”) designed by Madoka Kitao (北尾まどか), Nekomado — used with permission.