Pawnshake v0.1.0 · draft

Protocol

Move code

A move is one byte: its position in the sorted list of legal moves. In the starting position, 1. e4 is 13.

The idea

Both players know the position. So instead of sending "e2 to e4", a player sends which of the legal moves it played. List every legal move, sort the list the same way on every device, and the move is its index. No position in chess has more than 218 legal moves, so the code always fits a byte (0 to 217), and the bytes above 217 are free for commands.

Start position: all 20 legal moves, numbered
♜♞♝♛♚♝♞♜♟♟♟♟♟♟♟♟♟♟♟♟♟♟♟♟♜♞♝♛♚♝♞♜012345678910111214151617181913abcdefgh87654321

Read the numbers on the board: the knights come first (b1 is square 1, g1 is square 6), then the pawns from a2 to h2, each with its one-step move before its two-step move.

White's 1. e4 is 13, so its record's op byte is 0d. That one byte and the signature are the whole move.

The sort key

key    = from * 320 + to * 5 + promo        sorted ascending
square = rank * 8 + file                    a1 = 0, h1 = 7, a8 = 56, h8 = 63
promo  = none 0, n 1, b 2, r 3, q 4

Castling is the king's two-square move (e1g1, e1c1), en passant is the pawn's diagonal move. Promotions are separate moves with separate codes: e7e8n, e7e8b, e7e8r, e7e8q.

Worked out

CodeMoveKey
0b1a31 × 320 + 16 × 5 = 400
1b1c31 × 320 + 18 × 5 = 410
2g1f36 × 320 + 21 × 5 = 2025
3g1h36 × 320 + 23 × 5 = 2035
4a2a38 × 320 + 16 × 5 = 2640
5a2a48 × 320 + 24 × 5 = 2680
6b2b39 × 320 + 17 × 5 = 2965
7b2b49 × 320 + 25 × 5 = 3005
8c2c310 × 320 + 18 × 5 = 3290
9c2c410 × 320 + 26 × 5 = 3330
10d2d311 × 320 + 19 × 5 = 3615
11d2d411 × 320 + 27 × 5 = 3655
12e2e312 × 320 + 20 × 5 = 3940
13e2e412 × 320 + 28 × 5 = 3980
14f2f313 × 320 + 21 × 5 = 4265
15f2f413 × 320 + 29 × 5 = 4305
16g2g314 × 320 + 22 × 5 = 4590
17g2g414 × 320 + 30 × 5 = 4630
18h2h315 × 320 + 23 × 5 = 4915
19h2h415 × 320 + 31 × 5 = 4955

Guarding against engine bugs

If two engines ever disagreed about the legal moves in a position, the same byte would mean different moves on the two boards and the game would silently split. Pawnshake prevents that: every move record's signed body includes legal, the number of legal moves in the position, and ply. A disagreement shows up as a signature failure the moment the record arrives, not ten moves later.

Conformance

vectors/movecode.json lists 13 positions (the start, castling on both sides, en passant, promotion order, a capture promotion, a check with one reply, the famous 218-move position and six positions from random games) with the full sorted legal list for each. Every port must reproduce them exactly.