Cờ Tướng9 × 10 · 32 pieces

A quiet game of war.

Xiangqi rebuilt from the rules up: a real C++ engine, a board that floats, and nothing on screen that does not belong to the game.

01The stillness

The board does not arrive. It is already here.

Nine files, ten ranks, a river in the middle. The pond holds it, the lamp under the board lights it, and the water keeps moving while nothing else does.

02The pieces

Thirty-two pieces. Seven laws.

A cannon needs a screen before it can take. A horse can be stopped at the knee. A soldier crosses the river and never walks back.

03The machine

Then it thinks, eight plies deep.

Negamax with alpha–beta pruning, a transposition table, quiescence search and iterative deepening — candidate after candidate, until only one is left.

04The move

Pháo 2 → 5. The central cannon.

One of the oldest openings in the game — and the first one the engine will punish you for playing carelessly.

05Your move

The engine is already waiting.

Three difficulties, two players on one machine, or a room over the wire. The pond keeps moving either way.

01The rules, all of them

Seven pieces. No ambiguity.

Each piece carries its own rule as a class in the engine — it knows where it may go and what blocks it. Legal moves come from the piece, not from a table of exceptions, so a new piece is a new class and nothing else changes.

Chariotxe

Any distance along a rank or file, until something is in the way. The strongest piece on the board and the one that decides most endings.

Cannonpháo

Moves like a chariot, but captures only by leaping a single screen — one piece, friend or enemy, between it and the target. No screen, no capture.

Horsemã

One step straight, one step diagonally — unless a piece sits against its knee. The leg is blocked, and the move disappears.

Elephantvoi

Exactly two points diagonally, and never across the river. A piece on the midpoint closes the eye, and it stays at home for the whole game.

Advisorsĩ

One point diagonally, inside the palace only. Two of them, and together they are the general's last wall.

Generaltướng

One point orthogonally, inside the palace. The two generals may never face each other down an open file — that line is a weapon, and it wins games.

Soldiertốt

Forward, one point. After the river, sideways as well. Never backwards, never promoted — a soldier that reaches the last rank simply stays there.

02The engine

Three levels, one honest answer.

The same search runs at every difficulty; only its budget and its bookkeeping change. Easy is allowed to be careless on purpose. Hard is not.

Search configuration
LevelTimeDepthTechnique
Easy0.1 s22 pliesNegamax + alpha–beta, 35% near-best choice
Normal0.5 s44 plies+ transposition table, quiescence search
Hard2.5 s88 plies+ iterative deepening, killer & history
Transposition table

The same position reached by two move orders is searched once, keyed by a Zobrist hash. Half of the tree disappears.

Quiescence

At the depth limit it keeps capturing until the position calms down, so the score is not taken in the middle of an exchange.

Iterative deepening

It searches one ply, then two, then three — and keeps the best move from the last completed pass, so the clock is never the reason a move is lost.

04Play

Four ways in.

In the browser

No install, no account.

The same C++ engine, compiled to WebAssembly and served as static files. 28 MB, and nothing but the game once it has loaded.

Open the web build

WEB · WASM · 28 MB
Edge, Chrome, Firefox · WebGL 2

On the desktop

Windows, packed.

Electron shell, Chromium inside, the engine compiled natively. Unzip one folder and run Xiangqi.exe — no toolchain, no Node, no browser.

Download for Windows

WINDOWS 10 / 11 · x64 · 282 MB
Unsigned student build · SmartScreen may warn

Over the wire

Two rooms, one authority.

Online play runs on a Cloudflare Durable Object that holds the board and the clock, so both clients see the same legal move or the same rejection.

WSS · one live session per room

In a terminal

Yes, a console build.

The same engine, no graphics, one binary. Useful for reading the search and for proving the rules are real.

C++17 · POSIX terminal
make console && ./bin/cotuong