src/chess/king.c

changeset 216
d0c3d3016650
parent 195
27d02ccb0cef
--- a/src/chess/king.c	Thu Sep 03 15:28:54 2026 +0200
+++ b/src/chess/king.c	Thu Sep 03 16:18:24 2026 +0200
@@ -30,62 +30,57 @@
 #include "rules.h"
 #include "king.h"
 
-static bool king_castling_chkmoved(
-        const GameState *gamestate, File file, Rank rank) {
-
-    for (unsigned i = 0; i < gamestate->movecount; i++) {
-        if (gamestate->moves[i].fromfile == file
-            && gamestate->moves[i].fromrank == rank) {
-            return true;
-        }
-    }
-    
-    return false;
-}
-
 bool king_chkrules(const GameState *gamestate, const Move* move) {
     if (abs(move->torank - move->fromrank) <= 1 &&
         abs(move->tofile - move->fromfile) <= 1) {
         return true;
-    } else {
+    } else if (move->fromrank == move->torank) {
         /* castling */
-        if (move->fromrank == move->torank &&
-            move->fromrank == (piece_color(move->piece) == WHITE ? 0 : 7) &&
-            move->fromfile == fileidx('e') &&
-            (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) {
-            
-            return !king_castling_chkmoved(gamestate,
-                    move->fromfile, move->fromrank) &&
-                !king_castling_chkmoved(gamestate,
-                    move->tofile == fileidx('c') ? 0 : 7, move->fromrank);
+        Rank backrank;
+        bool k_allowed, q_allowed;
+        if (piece_color(move->piece) == WHITE) {
+            backrank = rankidx('1');
+            k_allowed = !gamestate->castling.K;
+            q_allowed = !gamestate->castling.Q;
         } else {
-            return false;
+            backrank = rankidx('8');
+            k_allowed = !gamestate->castling.k;
+            q_allowed = !gamestate->castling.q;
         }
+        bool castle_q = false, castle_k = false;
+        if (move->fromrank == backrank && move->fromfile == fileidx('e')) {
+            castle_q = move->tofile == fileidx('c');
+            castle_k = move->tofile == fileidx('g');
+        }
+        /* note that here we do not consider threats!
+         * that is what king_isblocked() does */
+        return (castle_q && q_allowed) || (castle_k && k_allowed);
+    } else {
+        return false;
     }
 }
 
 bool king_isblocked(const GameState *gamestate, const Move *move) {
-    
-    Color op_color = opponent_color(piece_color(move->piece));
-    
-    /* being in check does not "block" the king, so don't test it here */
-    bool blocked = false;
-    
     /* just test, if castling move is blocked */
     if (abs(move->tofile - move->fromfile) == 2) {
         if (move->tofile == fileidx('c')) {
-            blocked |= gamestate->board[move->torank][fileidx('b')];
+            /* check if rook can travel the queen-side */
+            if (gamestate->board[move->torank][fileidx('b')]) {
+                return true;
+            }
         }
+        /* check if new field for the rook is free */
         File midfile = (move->tofile+move->fromfile)/2;
-        bool incheck = false;
-        if (gamestate->movecount > 0) {
-            incheck = is_check_position(gamestate);
+        if (gamestate->board[move->torank][midfile]) {
+            return true;
         }
-        blocked |= incheck || gamestate->board[move->torank][midfile] ||
-            is_covered(gamestate, midfile, move->torank, op_color);
+        /* check if the king or the target field for the rook is threatened */
+        if (is_check_position(gamestate) || is_covered(gamestate,
+            midfile, move->torank, opponent_color(piece_color(move->piece)))) {
+            return true;
+        }
     }
-    
-    return blocked;
+    return false;
 }
 
 size_t king_moves(const GameState *gamestate,

mercurial