# HG changeset patch # User Mike Becker # Date 1787571755 -7200 # Node ID 8230904458a795c1f60f08987d3455656bb27647 # Parent c0acc89d6c010d3dfa682ae90e8f7848109b3f9e fix regression in network play: we have to transmit capture/check(mate) flags diff -r c0acc89d6c01 -r 8230904458a7 PROTOCOL.md --- a/PROTOCOL.md Mon Aug 24 13:20:19 2026 +0200 +++ b/PROTOCOL.md Mon Aug 24 13:42:35 2026 +0200 @@ -39,6 +39,9 @@ * a BYTE index for the row the piece was moved from * a BYTE index for the file the piece was moved to * a BYTE index for the row the piece was moved to + * a BYTE set to 1 if this is a capturing move and to zero if it is not + * a BYTE set to 1 if this move gives check, 2 if it gives checkmate, and + zero otherwise * a BYTE describing the selected piece for promotion (otherwise zero) Note carefully that the byte order used by this protocol is little-endian while @@ -116,7 +119,17 @@ ## Playing the Game -TODO: describe +The game is played by exchanging moves. +We call the player supposed to make the next move the _active_ player. +The other player we call the _waiting_ player. + +### Make a Move + +### Resign + +### Offer or Claim a Draw + +### Propose Resignation ## Message Code Table diff -r c0acc89d6c01 -r 8230904458a7 src/chess/pgn.c --- a/src/chess/pgn.c Mon Aug 24 13:20:19 2026 +0200 +++ b/src/chess/pgn.c Mon Aug 24 13:42:35 2026 +0200 @@ -155,6 +155,7 @@ if (move_validate_result != VALID_MOVE_SEMANTICS) { return(pgn_error_move_semantics); } + format_move(gamestate, &move); apply_move(gamestate, &move); /* skip spaces */ diff -r c0acc89d6c01 -r 8230904458a7 src/chess/rules.c --- a/src/chess/rules.c Mon Aug 24 13:20:19 2026 +0200 +++ b/src/chess/rules.c Mon Aug 24 13:42:35 2026 +0200 @@ -535,7 +535,7 @@ } -static void format_move_impl(const GameState *gamestate, Move *move) { +void format_move(const GameState *gamestate, Move *move) { char *string = &(move->string[0]); /* at least 8 characters should be available, wipe them out */ @@ -622,18 +622,6 @@ } } -void format_move(const GameState *gamestate, Move *move) { - /* correct check/checkmate flags */ - move->check = move->checkmate = false; - switch (determine_check_or_checkmate(gamestate, move)) { - case 2: move->checkmate = true; - case 1: move->check = true; - } - - /* format the move string */ - format_move_impl(gamestate, move); -} - static int validate_move_rules(const GameState *gamestate, const Move *move) { assert((move->piece & ~(PIECE_MASK|COLOR_MASK)) == 0); @@ -1025,6 +1013,7 @@ } char mstr[8]; strcpy(mstr, pstr); + strcpy(move->string, pstr); /* evaluate check/checkmate flags */ if (mstr[len-1] == '+' || mstr[len-1] == '#') { @@ -1155,7 +1144,7 @@ return VALID_MOVE_SYNTAX; } -int eval_move2(const GameState *gamestate, +static int eval_move2(const GameState *gamestate, const char *mstr, Color color, Move *move, bool lazy) { int result = eval_move1(mstr, move, color); if (result == VALID_MOVE_SYNTAX) { @@ -1172,9 +1161,6 @@ case 1: move->check = true; } } - - /* format the move string */ - format_move_impl(gamestate, move); } } return result; diff -r c0acc89d6c01 -r 8230904458a7 src/chess/rules.h --- a/src/chess/rules.h Mon Aug 24 13:20:19 2026 +0200 +++ b/src/chess/rules.h Mon Aug 24 13:42:35 2026 +0200 @@ -527,9 +527,12 @@ /** * Calculates the move string within the specified move. * - * This corrects any missing check / checkmate flags, first. + * The string calculated in short algebraic notation. + * The @p gamestate is needed to determine how to disambiguate the move, + * if necessary. * - * Do not call this function after eval_move() or eval_move_strict(). + * Recommended to be called before apply_move() so that a clean + * move string is added to the list of recorded moves. * * @param gamestate the current game state * @param move the move data diff -r c0acc89d6c01 -r 8230904458a7 src/main.c --- a/src/main.c Mon Aug 24 13:20:19 2026 +0200 +++ b/src/main.c Mon Aug 24 13:42:35 2026 +0200 @@ -478,6 +478,7 @@ if (result == VALID_MOVE_SYNTAX) { result = validate_move(gamestate, &move); if (result == VALID_MOVE_SEMANTICS) { + format_move(gamestate, &move); apply_move(gamestate, &move); if (is_game_running(gamestate)) { return 0; @@ -496,13 +497,13 @@ } } -#define NETMOVE_LEN 14 +#define NETMOVE_LEN 16 #define NETGI_LEN 8 static NetGameInfo hton_gi(GameInfo gi) { return (NetGameInfo) { .servercolor = gi.servercolor, - .timecontrol = gi.timecontrol ? 1 : 0, + .timecontrol = gi.timecontrol, .time = net_htons(gi.time), .addtime = net_htons(gi.addtime), .delay = net_htons(gi.delay) @@ -526,7 +527,9 @@ .piece = move.piece, .fromfile = move.fromfile, .fromrow = move.fromrow, .tofile = move.tofile, .torow = move.torow, - .promotion = move.promotion + .capture = move.capture, + .check_or_mate = move.checkmate + move.check, + .promotion = move.promotion, }; } @@ -540,8 +543,9 @@ .fromfile = move.fromfile, .fromrow = move.fromrow, .tofile = move.tofile, .torow = move.torow, .promotion = move.promotion, - /* flags are also calculated before applying the move */ - 0 + .check = move.check_or_mate, + .checkmate = move.check_or_mate >> 1, + .capture = move.capture }; } @@ -676,6 +680,7 @@ || code == NETCODE_CHECKMATE || code == NETCODE_STALEMATE || code == NETCODE_NOMATERIAL) { + format_move(gamestate, &move); apply_move(gamestate, &move); if (is_game_running(gamestate)) { return 0; @@ -812,9 +817,9 @@ NetMove nmove; net_recieve_data(opponent, &nmove, NETMOVE_LEN); Move move = ntoh_move(nmove); - format_move(gamestate, &move); code = validate_move(gamestate, &move); if (code == VALID_MOVE_SEMANTICS) { + format_move(gamestate, &move); apply_move(gamestate, &move); if (gamestate->checkmate) { net_send_code(opponent, NETCODE_CHECKMATE); diff -r c0acc89d6c01 -r 8230904458a7 src/network.h --- a/src/network.h Mon Aug 24 13:20:19 2026 +0200 +++ b/src/network.h Mon Aug 24 13:42:35 2026 +0200 @@ -86,6 +86,8 @@ uint8_t fromrow; uint8_t tofile; uint8_t torow; + uint8_t capture; + uint8_t check_or_mate; uint8_t promotion; } NetMove; diff -r c0acc89d6c01 -r 8230904458a7 test/run-tests.c --- a/test/run-tests.c Mon Aug 24 13:20:19 2026 +0200 +++ b/test/run-tests.c Mon Aug 24 13:42:35 2026 +0200 @@ -47,5 +47,5 @@ } printf("\nTotal success: %u | failure: %u\n", success, failure); - return failure > 0 ? 1 : 0; + return failure > 0; }