src/chess/rules.c

changeset 66
f5cc75565f7c
parent 64
4eda5df55f86
child 67
c76e46970a59
--- a/src/chess/rules.c	Wed Aug 29 14:01:41 2018 +0200
+++ b/src/chess/rules.c	Wed Aug 29 15:12:24 2018 +0200
@@ -35,6 +35,7 @@
 
 static GameState gamestate_copy_sim(GameState *gamestate) {
     GameState simulation = *gamestate;
+    simulation.movecount = 0; /* simulations do not count moves */
     if (simulation.lastmove) {
         MoveList *lastmovecopy = malloc(sizeof(MoveList));
         *lastmovecopy = *(simulation.lastmove);
@@ -70,9 +71,9 @@
     };
 }
 
-/* MUST be called IMMEDIATLY after applying a move to work correctly */
+/* MUST be called BEFORE applying a move to work correctly */
 static void format_move(GameState *gamestate, Move *move) {
-    char *string = move->string;
+    char *string = &(move->string[0]);
     
     /* at least 8 characters should be available, wipe them out */
     memset(string, 0, 8);
@@ -103,25 +104,34 @@
             /* resolve ambiguities, if any */
             Move threats[16];
             uint8_t threatcount;
-            get_real_threats(gamestate, move->torow, move->tofile,
-                move->piece&COLOR_MASK, threats, &threatcount);
-            if (threatcount > 1) {
-                int ambrows = 0, ambfiles = 0;
+            if (get_threats(gamestate, move->torow, move->tofile,
+                    move->piece&COLOR_MASK, threats, &threatcount)) {
+                unsigned int ambrows = 0, ambfiles = 0, ambpiece = 0;
                 for (uint8_t i = 0 ; i < threatcount ; i++) {
-                    if (threats[i].fromrow == move->fromrow) {
-                        ambrows++;
-                    }
-                    if (threats[i].fromfile == move->fromfile) {
-                        ambfiles++;
+                    if (threats[i].piece == move->piece) {
+                        ambpiece++;
+                        if (threats[i].fromrow == move->fromrow) {
+                            ambrows++;
+                        }
+                        if (threats[i].fromfile == move->fromfile) {
+                            ambfiles++;
+                        }
                     }
                 }
-                /* ambiguous row, name file */
-                if (ambrows > 1) {
+                /* neither file, nor row are ambiguous, name file */
+                if (ambpiece > 1 && ambrows == 1 && ambfiles == 1) {
+                    /* this is most likely the case with Knights
+                     * in diagonal opposition */
                     string[idx++] = filechr(move->fromfile);
-                }
-                /* ambiguous file, name row */
-                if (ambfiles > 1) {
-                    string[idx++] = filechr(move->fromrow);
+                } else {
+                    /* ambiguous row, name file */
+                    if (ambrows > 1) {
+                        string[idx++] = filechr(move->fromfile);
+                    }
+                    /* ambiguous file, name row */
+                    if (ambfiles > 1) {
+                        string[idx++] = filechr(move->fromrow);
+                    }
                 }
             }
         }
@@ -144,7 +154,7 @@
     
     /* check? */
     if (move->check) {
-        /* works only, if this function is called when applying the move */
+        // TODO: does not work, because checkmate is not set when format_move is called
         string[idx++] = gamestate->checkmate?'#':'+';
     }
 }
@@ -207,6 +217,13 @@
 }
 
 static void apply_move_impl(GameState *gamestate, Move *move, _Bool simulate) {
+    /* format move before moving (s.t. ambiguities can be resolved) */
+    if (!simulate) {
+        if (!move->string[0]) {
+            format_move(gamestate, move);
+        }
+    }
+    
     uint8_t piece = move->piece & PIECE_MASK;
     uint8_t color = move->piece & COLOR_MASK;
     
@@ -239,7 +256,6 @@
     
     /* castling */
     if (piece == KING && move->fromfile == fileidx('e')) {
-        
         if (move->tofile == fileidx('g')) {
             gamestate->board[move->torow][fileidx('h')] = 0;
             gamestate->board[move->torow][fileidx('f')] = color|ROOK;
@@ -248,12 +264,7 @@
             gamestate->board[move->torow][fileidx('d')] = color|ROOK;
         }
     }
-
-    if (!simulate) {
-        if (!move->string[0]) {
-            format_move(gamestate, move);
-        }
-    }
+    
     /* add move, even in simulation (checkmate test needs it) */
     addmove(gamestate, move);
 }

mercurial