--- a/src/chess/rules.c Sat Aug 01 11:26:48 2026 +0200 +++ b/src/chess/rules.c Sun Aug 02 15:08:43 2026 +0200 @@ -142,6 +142,7 @@ piece_color(move->piece), candidates, &ccount)) { unsigned int ambrows = 0, ambfiles = 0, ambpiece = 0; for (size_t i = 0 ; i < ccount ; i++) { + // TODO: check if we need to discard pinned pieces here if (candidates[i].piece == move->piece) { ambpiece++; if (candidates[i].fromrow == move->fromrow) { @@ -548,11 +549,15 @@ return INVALID_MOVE_SYNTAX; } - /* cancel processing to save resources */ - if (!chkrules) { - return RULES_VIOLATED; + return chkrules ? VALID_MOVE_SEMANTICS : RULES_VIOLATED; +} + +int validate_move(const GameState *gamestate, const Move *move) { + int result = validate_move_rules(gamestate, move); + if (result != VALID_MOVE_SEMANTICS) { + return result; } - + /* test if the move would expose our own king */ GameState simulation = gamestate_copy_sim(gamestate); Move simmove = *move; @@ -570,9 +575,7 @@ } } } - int result = VALID_MOVE_SEMANTICS; if (is_covered(&simulation, kingrow, kingfile, oppcolor)) { - gamestate_cleanup(&simulation); if (piece_type(move->piece) == KING) { result = KING_MOVES_INTO_CHECK; } else { @@ -585,15 +588,6 @@ } gamestate_cleanup(&simulation); - return result; -} - -int validate_move(const GameState *gamestate, const Move *move) { - int result = validate_move_rules(gamestate, move); - if (result != VALID_MOVE_SEMANTICS) { - return result; - } - /* validate check and checkmate flags */ int cocm = determine_check_or_checkmate(gamestate, move); if (cocm == 2) { @@ -609,7 +603,6 @@ } else if (move->check) { return INVALID_CHECK; } - return VALID_MOVE_SEMANTICS; } @@ -675,6 +668,7 @@ Color color, Move *threats, size_t *threatcount) { /* simulate a capturing move on the target position */ + // TODO: this does NOT disregard the pin, as stated in the spec! Color opcolor = opponent_color(color); GameState simulation = gamestate_copy_sim(gamestate); if (piece_color(piece_at(&simulation, row, file)) != opcolor) {