Files
Claude d6e237ce4a Add chess
The full game: castling with every condition, en passant including the
case where taking would expose your own king, promotion to any of the
four, pins, checkmate, stalemate, insufficient material, the fifty-move
rule and threefold repetition.

Move generation is checked against the published perft counts rather
than against hand-written cases — the opening array to depth four
(197,281 positions) plus four standard test positions chosen precisely
because they break generators. Those counts are exact, so matching them
leaves very little room for a rule to be subtly wrong.

The opponent is a negamax search with alpha-beta, iterative deepening
and a capture-only quiescence tail, at three strengths. The quiescence
tail is the part that stops it hanging pieces: a fixed-depth search that
stops mid-exchange scores the position as though the recapture never
comes.

Two supporting changes:

The AI now thinks off the caller's thread. A card AI answers instantly,
but a chess search runs for a second or more, and the match controller's
scope belongs to the screen — searching there would freeze the board it
is drawn on.

Offline setup can seat the local player somewhere other than seat 0,
which is what lets you play Black. Seat 0 is White by definition, so
choosing a colour has to choose a seat.

FEN is read and written, so a table can start from a set position.

203 engine tests pass locally.
2026-08-06 13:34:31 +00:00

3.6 KiB

Chess — implemented rules

The full game, not a subset. This is the ruleset the engine enforces. Anything marked toggle is in the game setup screen.

Table

Two players. Seat 0 is always White; choosing to play Black in setup puts you in seat 1 and turns the board round so your pieces are still at the near edge.

Movement

All of it, including the parts that are usually left out:

  • Castling, both sides, with every condition: the king and the rook must not have moved, the squares between them must be empty, and the king may not castle out of check, through an attacked square, or into check. The b-file square may be attacked on the queen's side — the king does not cross it.
  • En passant, on the move immediately after a pawn steps two squares and only then. It is refused when taking would expose your own king, which is the one case a naive implementation gets wrong.
  • Promotion to queen, rook, bishop or knight, chosen when the pawn arrives.
  • Pins — a piece that shields its own king may not step off the line.

Rights are given up correctly: a rook that moves loses its castling right, and so does a rook captured on its own corner.

How a game ends

Ending When
Checkmate No legal move, and in check
Stalemate No legal move, and not in check
Insufficient material Neither side has enough to mate, whatever either plays
Fifty-move rule A hundred half-moves with no capture and no pawn move — toggle
Threefold repetition The same position, side to move and rights, three times — toggle

Insufficient material covers bare kings, a king and one minor piece, and two bishops on the same colour square. King and two knights is not included: it cannot be forced, but it can happen with cooperation, so it is not a dead position.

Both draw rules apply automatically rather than needing a claim. Switch either off in setup for a game that runs until somebody is mated.

Notation

The move list is ordinary algebraic: e4, Nf3, exd5, O-O, a8=Q+, Ra8#. Two pieces that can reach the same square are told apart by file, or by rank when they share a file, or by the whole square when they share both.

Positions

The engine reads and writes FEN, so a table can start from a set position rather than the opening array — a puzzle, or an adjourned game.

What the computer opponent does

A negamax search with alpha-beta pruning, iterative deepening, and a capture-only quiescence tail. The quiescence tail is what stops it giving pieces away: a search that simply stops after a fixed number of moves scores a position in the middle of an exchange as though the recapture never comes.

Evaluation is material plus piece placement, with a term in bare endgames that drives the losing king towards the edge — without it a won endgame just shuffles.

Toggle for three strengths:

Level Search Plays
Casual 2 ply Takes any move within about two thirds of a pawn of the best one
Club 3 ply Nearly always the best move it can see
Strong 4 ply The best move it can see

Every level is capped by a node budget, so no single move can hang the app on a sharp position — it plays the best move from the last depth it finished.

Testing

Move generation is checked against the published perft counts: the exact number of positions reachable at a given depth. The opening array is verified to depth four (197,281 positions), along with four standard test positions chosen because they break generators — castling through check, en passant that would expose a king, promotion with capture, and heavily pinned pieces.