start fixing issue #895

Fri, 12 Jun 2026 15:28:00 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 12 Jun 2026 15:28:00 +0200
changeset 136
1a84ee6b4bf0
parent 135
114e764fbae5
child 137
43d1b3c33369

start fixing issue #895

src/chess/rules.c file | annotate | diff | comparison | revisions
--- a/src/chess/rules.c	Fri Jun 12 14:33:42 2026 +0200
+++ b/src/chess/rules.c	Fri Jun 12 15:28:00 2026 +0200
@@ -412,6 +412,7 @@
     
     /* find kings for check validation */
     uint8_t piececolor = (move->piece & COLOR_MASK);
+    uint8_t oppcolor = opponent_color(piececolor);
     
     uint8_t mykingfile = 0, mykingrow = 0, opkingfile = 0, opkingrow = 0;
     for (uint8_t row = 0 ; row < 8 ; row++) {
@@ -429,9 +430,7 @@
     }
     
     /* don't move into or stay in check position */
-    if (is_covered(&simulation, mykingrow, mykingfile,
-        opponent_color(piececolor))) {
-        
+    if (is_covered(&simulation, mykingrow, mykingfile, oppcolor)) {
         gamestate_cleanup(&simulation);
         if ((move->piece & PIECE_MASK) == KING) {
             return KING_MOVES_INTO_CHECK;
@@ -455,20 +454,27 @@
             for (int df = -1 ; df <= 1 && !canescape ; df++) {
                 if (!(dr == 0 && df == 0)  &&
                         isidx(opkingrow + dr) && isidx(opkingfile + df)) {
-                    
-                    /* escape field neither blocked nor covered */
-                    if ((simulation.board[opkingrow + dr][opkingfile + df]
-                            & COLOR_MASK) != opponent_color(piececolor)) {
-                        canescape |= !is_covered(&simulation,
+                    /* escape field neither occupied nor covered */
+                    canescape =
+                        !simulation.board[opkingrow + dr][opkingfile + df] &&
+                        !is_covered(&simulation,
                             opkingrow + dr, opkingfile + df, piececolor);
-                    }
                 }
             }
         }
         /* can't escape, can he capture? */
         if (!canescape && threatcount == 1) {
-            canescape = is_attacked(&simulation, threats[0].fromrow,
-                threats[0].fromfile, opponent_color(piececolor));
+            /* TODO: this is bugged - we actually need distinguish two cases
+             *       1. another piece can rescue the king
+             *          (this is what is implemented now)
+             *       2. the king can kill the attacker
+             *          - in this case, the threatcount is irrelevant, because
+             *            the king moves out of the current threat
+             *          - we must verify that the king can actually kill the
+             *            attacker without running into a new check
+             */
+            canescape = is_attacked(&simulation,
+                    threats[0].fromrow, threats[0].fromfile, oppcolor);
         }
         
         /* can't capture, can he block? */
@@ -486,7 +492,7 @@
                     while (!canescape && file != threat->tofile - d) {
                         file += d;
                         canescape |= is_protected(&simulation,
-                            threat->torow, file, opponent_color(piececolor));
+                            threat->torow, file, oppcolor);
                     }
                 } else if (threat->fromfile == threat->tofile) {
                     /* rook aspect (on file) */
@@ -495,7 +501,7 @@
                     while (!canescape && row != threat->torow - d) {
                         row += d;
                         canescape |= is_protected(&simulation,
-                            row, threat->tofile, opponent_color(piececolor));
+                            row, threat->tofile, oppcolor);
                     }
                 } else {
                     /* bishop aspect */
@@ -509,14 +515,14 @@
                         row += dr;
                         file += df;
                         canescape |= is_protected(&simulation, row, file,
-                            opponent_color(piececolor));
+                            oppcolor);
                     }
                 }
             }
         }
             
         if (!canescape) {
-            gamestate->checkmate = 1;
+            gamestate->checkmate = true;
         }
     }
     

mercurial