fixed crucial bug where both players could move at the same time + added pawn rules (TODO: en passant)

Wed, 26 Mar 2014 14:53:15 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 26 Mar 2014 14:53:15 +0100
changeset 14
970748b9a73b
parent 13
faec61c4901f
child 15
7ffd66591afe

fixed crucial bug where both players could move at the same time + added pawn rules (TODO: en passant)

src/game.c file | annotate | diff | comparison | revisions
src/game.h file | annotate | diff | comparison | revisions
src/rules/pawn.c file | annotate | diff | comparison | revisions
--- a/src/game.c	Wed Mar 26 14:12:59 2014 +0100
+++ b/src/game.c	Wed Mar 26 14:53:15 2014 +0100
@@ -78,9 +78,9 @@
  * @param move the move to apply
  */
 static void apply_move(Board board, Move *move) {
-    board[move->fromrow][move->fromfile] = 0;
+    msrc(board, move) = 0;
     // TODO: care for en passant capture
-    board[move->torow][move->tofile] = move->piece;
+    mdst(board, move) = move->piece;
     
     /* castling */
     if ((move->piece & PIECE_MASK) == KING &&
@@ -112,8 +112,14 @@
     }
     
     /* does piece exist */
-    result = board[move->fromrow][move->fromfile] == move->piece;
+    result = msrc(board, move) == move->piece;
     
+    /* can't capture own pieces */
+    if ((mdst(board, move) & COLOR_MASK) == (move->piece & COLOR_MASK)) {
+        return FALSE;
+    }
+    
+    /* validate individual rules */
     switch (move->piece & PIECE_MASK) {
     case PAWN:
         result = result && pawn_chkrules(board, move);
@@ -247,8 +253,9 @@
                 move->fromfile = fileidx(mstr[0]);
             }
         } else {
-            /* move (e.g. "Ndf3") */
-            move->fromfile = fileidx(mstr[1]);
+            /* move (e.g. "Ndf3", "N2c3") */
+            move->fromfile = isfile(mstr[1]) ?
+                fileidx(mstr[1]) : rowidx(mstr[1]);
         }
         move->tofile = fileidx(mstr[2]);
         move->torow = rowidx(mstr[3]);
@@ -366,6 +373,8 @@
                     if (move.checkmate) {
                         printw("Checkmate!");
                         return 1;
+                    } else {
+                        return 0;
                     }
                 }
             } else {
--- a/src/game.h	Wed Mar 26 14:12:59 2014 +0100
+++ b/src/game.h	Wed Mar 26 14:53:15 2014 +0100
@@ -37,8 +37,9 @@
 extern "C" {
 #endif
 
-#define PIECE_MASK 0x0F
-#define COLOR_MASK 0xF0
+#define PIECE_MASK       0x0F
+#define COLOR_MASK       0x30
+#define ENPASSANT_THREAT 0x40
 
 #define WHITE 0x10
 #define BLACK 0x20
@@ -77,6 +78,8 @@
 } Move;
 
 #define POS_UNSPECIFIED UINT8_MAX
+#define mdst(b,m) b[m->torow][m->tofile]
+#define msrc(b,m) b[m->fromrow][m->fromfile]
 
 #define isidx(idx) ((uint8_t)idx < 8)
 
--- a/src/rules/pawn.c	Wed Mar 26 14:12:59 2014 +0100
+++ b/src/rules/pawn.c	Wed Mar 26 14:53:15 2014 +0100
@@ -30,28 +30,44 @@
 #include "pawn.h"
 
 _Bool pawn_chkrules(Board board, Move *move) {
-    // TODO: implement
-    return TRUE;
+    int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1);
+    if (move->capture) {
+        if (move->fromrow == move->torow + d && (
+            move->fromfile == move->tofile + 1 ||
+            move->fromfile == move->tofile - 1)) {
+            // TODO: en passant
+            return mdst(board,move) != 0; /* color has been checked */
+        } else {
+            return FALSE;
+        }
+    } else {
+        if (move->fromfile == move->tofile) {
+            return (move->fromrow == move->torow + d) ||
+                (move->fromrow == (d < 0 ? 1 : 6) && /* advanced first move */
+                move->fromrow == move->torow + d*2);
+        } else {
+            return FALSE;
+        }
+    }
 }
 
 _Bool pawn_isblocked(Board board, Move *move) {
-    // TODO: implement
-    return FALSE;
+    return mdst(board,move) && !move->capture;
 }
 
 _Bool pawn_getlocation(Board board, Move *move) {
     int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1);
     
-    // TODO: battle moves
-    
-    move->fromfile = move->tofile;
+    if (move->fromfile == POS_UNSPECIFIED) {
+        move->fromfile = move->tofile;
+    }
     move->fromrow = move->torow + d;
     if (move->fromrow > 6) {
         return FALSE;
     } else {
         /* advanced first move */
         if (move->fromrow == (d < 0 ? 2 : 5) &&
-            board[move->fromrow][move->fromfile] != move->piece) {
+            msrc(board,move) != move->piece) {
 
             move->fromrow += d;
             if (move->fromrow > 6) {

mercurial