坦克遊戲實驗:Fable 5.1 只勝 1 場,Opus 的直接打法佔優
Don't Bring the Professor to a Tank Fight
作者以改編自 Battle City 的文字坦克遊戲比較四個模型,Fable 5.1 在 25 場中只勝 1 場,並有 21 場失去基地。Fable 的計劃更完整,卻常離開基地攻擊遠處目標;Opus 則採取直取最近基地、守住路線的策略,表現最佳。
Fable 5.1 is the strongest model I can run. It wrote most of the code in this game but it won one match only out of 25 and lost its base in 21 of them.
My first explanation was the obvious one: it thinks too long, and the game rewards the fastest reply. So I removed the clock. It still lost. Then I spent an evening changing the rules to find a version of the game where deep thinking pays. The ranking did not move. What moved was my understanding of why the professor loses. It is not slow. It plays a different game than the one on the table.
The setup
Battle City on the NES, reduced to what a text model can read. A 15 by 15 grid, four bases in the corners inside brick rings, four tanks with three lives each. A shell flies until it meets something: it destroys a brick, stops at steel, takes a life from a tank, and destroys a base. Lose your base and you are out. Last base standing wins. If the rounds run out with two bases alive, nobody wins.
Each player is a headless Claude Code session with no tools, resumed on every call so it keeps its memory of the game. The engine sends the board as text and asks for a plan of one to eight actions plus a one-sentence reason. The plan runs one action per round. The model is asked again when its plan runs out or when something notable happens: a hit anywhere, a tank in its lane firing, an enemy entering its lane, or its own move being blocked. The rules describe the actions and the goal. The last line is "Decide your own tactics." Nobody is told how to play.
The engine, a live viewer with the shells in flight, and the logging were written in one afternoon with Claude Code, with random bots standing in for the models until the rules were right. Then 29 games in one day: haiku, sonnet, opus and fable at the same table, two-model games, one fable against three haikus, three fables against one opus, and a set of rule changes meant to help a planner. Every game is in the repo at https://github.com/valbarov/ai-tank-battle, with every prompt and reply.
What the game asks for is simple: read a small board, pick the nearest base, take the shortest route, shoot first when someone enters your lane, and stay near home when you are down to one life. Any of the four models finds that in one careful pass. That is the whole finding, and the rest of the article is what each model did with it.
The ladder
| model | seats played | wins | bases destroyed | its base lost | first to fall | median seconds per reply |
|---|---|---|---|---|---|---|
| haiku | 40 | 4 | 20 | 28 | 11 | 4.0 |
| sonnet | 30 | 5 | 21 | 20 | 6 | 4.2 |
| opus | 21 | 10 | 26 | 7 | 0 | 4.2 |
| fable | 25 | 1 | 9 | 21 | 12 | 8.6 |
All games at --effort low unless stated. Opus was never the first base to fall, in any mode, on any map.
Opus: the boring route, every time
Opus played the same game in every seat and on every map. Its first plan of a game named the nearest enemy base, the open lane that led there, and the one brick it would have to break. It drove that lane. When an enemy entered its row or column it fired at once. When it was down to one life it parked next to its own base and waited for someone to come into its lines, and it stayed there until the others had worn each other down.
That is all. There was no feint, no reading of the opponent, no trade of bases. It was also the only model that never left its base open while a neighbour was on the way. Half of all bases destroyed across the four-model games were its shots, most of them from a plan written several rounds earlier. [check]
Sonnet: a solid second
Sonnet looked for a target rather than a base. Its openings usually went out into the middle to find an enemy tank, and it won its exchanges often: 21 bases destroyed and the second-best record of keeping its own. It split the two-model games with haiku evenly, two wins each and one draw, and won one four-model game.
Its losses had one shape. Sonnet was the neighbour of opus in most seatings, and the corridor between their two bases is exactly the lane opus drives. In the sequential games sonnet's base was the first to fall twice, both times to opus, while sonnet's tank was off hunting somebody else.
Haiku: fast, correct, and too short
Haiku was the fastest at the table and understood the game as well as anyone. Its plans were the shortest, so it was re-asked most often, and most of those extra calls went into walking. It won two-model games against sonnet and won twice against fable, but never a four-model game with opus present.
Two details from its games say more than its score. In the first version of the rules there was a tiebreak at the round limit by lives. Haiku and sonnet both read that rule and both stopped moving for the last nine rounds of a game once they were ahead, each explaining that holding position was now the winning move. I changed one sentence, nobody wins at the limit, and the next game ended as a race, with a haiku choosing to attack because it worked out that defence could not succeed. The small models were not too simple to exploit the rules. They exploited them first.
The other detail: in one game haiku had killed the last enemy tank with twelve rounds to spare and an empty board between it and the last base. It took a route three times longer than needed and ran out of time. Correct target, wrong path, no second look.
Fable: the richer game
Fable never misread the board. Its plans were the most complete at the table, and in a straight fight with a neighbour it was the best player there: it set ambushes, it stepped out of a lane one round before the shot came, it noticed that the opponent tended to dodge rather than fire and used that, and it was the only model that noticed the seat order gives the earlier seat the first shot in a fresh encounter and said so.
It lost anyway, and the logs show one cause. Fable's first plan in six of its seven games from the same corner was to leave its sealed base and go the long way round to attack the base across the board. It judged that trade in plain words: it could not stop the neighbour in time, so it would take a base of its own. Every one of those six games ended with the neighbour, opus or haiku, driving the open lane into the empty corner. The one game where fable stayed in that lane and fought the neighbour, it won. When it faced three copies of itself and one opus, the three fables took every life opus had, then spent the rest of the game on each other.
So fable plays the game it finds interesting: the duel, the feint, the trade. The game on the table pays for the boring one.
What I tried to give the professor an edge
I started with the clock, because the first version let every player think at once and applied replies in the order they arrived, which punishes slow answers. At default effort fable took 24 seconds per reply and was dead before its first plan finished. At low effort it played, and still lost every four-model game. So I made the order sequential: seat A, then B, C, D, and the next player is asked only after the previous move is on the board. Reply time cannot matter. Opus still won.
Then, one at a time:
| change | why it should help a planner | what happened |
|---|---|---|
| fog of war, enemies visible within 4 cells | memory of last positions, inference from reported hits | ranking unchanged |
| 21 by 21 board | longer plans, more routes | opus won both games |
| no fog at all | the threat is visible from round 1 | fable saw it and chose the trade anyway, out in round 16 |
| three actions per turn | step, turn, fire in one turn rewards multi-step plans | haiku won in 24 rounds; the board changes by nine actions between your turns |
| brick maze with steel posts | long corridors, dead ends, 8-move plans must be right | two draws; every model tunnelled, nobody got lost |
Fifteen more games, one fable win. The maze was the only variant where fable beat opus in a long fight, and the repeat of the same maze went the other way.
They all understood the game
In 1386 model calls there was not one invalid reply, and no model ever claimed a dead base was alive. The errors were small and specific: counting cells for a range-limited shell on the first map, and one haiku that fired from where it had died instead of where it had respawned. There was nothing in this game left for a deeper model to understand better.
Conclusion
Match the model to the depth of the task, not to the importance of the task.
A loop of many small decisions, each with a visible state and a clear goal, is a job for a fast model with enough depth to plan a few steps. Agent loops are full of these: pick the next file, choose the next tool call, decide whether the test output is a pass. Opus at low effort was the right tank. Sonnet and haiku were playable tanks.
The deep model is for the decision where a one-pass read gets the wrong answer. Designing the rules of this game, for instance. The rules that stood up were written with fable. The tanks that won were not.
And there is a cost to bringing it anyway that I did not expect. Given a shallow game, fable did not play the shallow game better. It looked for a richer one. Some of what it found was brilliant and all of it was beside the point, because the opponent was already driving down the lane. If your task has one obvious winning line, the model that looks for a cleverer one is not an upgrade.
Harness
arena.py is about 650 lines of Python with no dependencies: the engine, the player loop, random bots for testing, parallel and sequential modes, --fog, --size, --moves, --maze, and a --delay for watching planned moves at human speed. viewer.html is one file that polls state.json and draws the board, the four model panels with each reason line, and the shells in flight. Both are in the repo, together with the logs of every game: https://github.com/valbarov/ai-tank-battle
Twenty-nine games, 4345 turns, 1386 model calls, on a subscription. A four-model game takes 6 to 15 minutes in sequential mode at low effort.
來源:DEV Community · dev.to