completed eval_move

Wed, 26 Mar 2014 14:12:59 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 26 Mar 2014 14:12:59 +0100
changeset 13
faec61c4901f
parent 12
84880c7e1ea6
child 14
970748b9a73b

completed eval_move

Makefile file | annotate | diff | comparison | revisions
src/game.c file | annotate | diff | comparison | revisions
src/game.h file | annotate | diff | comparison | revisions
--- a/Makefile	Wed Mar 26 13:16:49 2014 +0100
+++ b/Makefile	Wed Mar 26 14:12:59 2014 +0100
@@ -28,9 +28,7 @@
 
 include conf.mk
 
-all: clean compile
-	
-compile: build build/rules
+all: build build/rules
 	cd src; $(MAKE)
 
 build:
--- a/src/game.c	Wed Mar 26 13:16:49 2014 +0100
+++ b/src/game.c	Wed Mar 26 14:12:59 2014 +0100
@@ -71,6 +71,12 @@
     }
 }
 
+/**
+ * Applies a move and deletes captured pieces.
+ * 
+ * @param board the current board state
+ * @param move the move to apply
+ */
 static void apply_move(Board board, Move *move) {
     board[move->fromrow][move->fromfile] = 0;
     // TODO: care for en passant capture
@@ -91,9 +97,20 @@
     }
 }
 
+/**
+ * Validates move by applying chess rules.
+ * @param board the current board state
+ * @param move the move to validate
+ * @return TRUE, if the move complies to chess rules, FALSE otherwise
+ */
 static _Bool validate_move(Board board, Move *move) {
     _Bool result;
     
+    /* validate indices (don't trust opponent) */
+    if (!chkidx(move)) {
+        return FALSE;
+    }
+    
     /* does piece exist */
     result = board[move->fromrow][move->fromfile] == move->piece;
     
@@ -162,7 +179,7 @@
  * @return TRUE if the location could be retrieved, FALSE if the location is
  * ambiguous
  */
-static _Bool getlocation(Board board, Move *move) {
+static _Bool getlocation(Board board, Move *move) {   
     uint8_t piece = move->piece & PIECE_MASK;
     switch (piece) {
         case PAWN: return pawn_getlocation(board, move);
@@ -203,11 +220,9 @@
     
     if (len == 2) {
         /* pawn move (e.g. "e4") */
-        if (isfile(mstr[0]) && isrow(mstr[1])) {
-            move->piece = PAWN;
-            move->tofile = fileidx(mstr[0]);
-            move->torow = rowidx(mstr[1]);
-        }
+        move->piece = PAWN;
+        move->tofile = fileidx(mstr[0]);
+        move->torow = rowidx(mstr[1]);
     } else if (len == 3) {
         if (strcmp(mstr, "O-O") == 0) {
             /* king side castling */
@@ -216,17 +231,27 @@
             move->tofile = fileidx('g');
             move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
         } else {
-            /* unambiguous move (e.g. "Nf3") */
+            /* move (e.g. "Nf3") */
             move->piece = getpiece(mstr[0]);
-            move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED;
-            move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED;
+            move->tofile = fileidx(mstr[1]);
+            move->torow = rowidx(mstr[2]);
         }
         
     } else if (len == 4) {
-        /* ambiguous move (e.g. "Ndf3") */
-        
-        /* unambiguous capture (e.g. "Nxf3", "dxe5") */
-        
+        move->piece = getpiece(mstr[0]);
+        if (mstr[1] == 'x') {
+            /* capture (e.g. "Nxf3", "dxe5") */
+            move->capture = TRUE;
+            if (!move->piece) {
+                move->piece = PAWN;
+                move->fromfile = fileidx(mstr[0]);
+            }
+        } else {
+            /* move (e.g. "Ndf3") */
+            move->fromfile = fileidx(mstr[1]);
+        }
+        move->tofile = fileidx(mstr[2]);
+        move->torow = rowidx(mstr[3]);
     } else if (len == 5) {
         if (strcmp(mstr, "O-O-O") == 0) {
             /* queen side castling "O-O-O" */
@@ -235,26 +260,51 @@
             move->tofile = fileidx('c');
             move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
         } else {
-            /* ambiguous capture (e.g. "Ndxf3") */
-
-            /* long notation move (e.g. "Nc5a4") */
-
-            /* long notation capture (e.g. "e5xf6") */
+            move->piece = getpiece(mstr[0]);
+            if (mstr[2] == 'x') {
+                move->capture = TRUE;
+                if (move->piece) {
+                    /* capture (e.g. "Ndxf3") */
+                    move->fromfile = fileidx(mstr[1]);
+                } else {
+                    /* long notation capture (e.g. "e5xf6") */
+                    move->piece = PAWN;
+                    move->fromfile = fileidx(mstr[0]);
+                    move->fromrow = rowidx(mstr[1]);
+                }
+            } else {
+                /* long notation move (e.g. "Nc5a4") */
+                move->fromfile = fileidx(mstr[1]);
+                move->fromrow = rowidx(mstr[2]);
+            }
+            move->tofile = fileidx(mstr[3]);
+            move->torow = rowidx(mstr[4]);
         }
     } else if (len == 6) {
         /* long notation capture (e.g. "Nc5xf3") */
+        if (mstr[3] == 'x') {
+            move->capture = TRUE;
+            move->piece = getpiece(mstr[0]);
+            move->fromfile = fileidx(mstr[1]);
+            move->fromrow = rowidx(mstr[2]);
+            move->tofile = fileidx(mstr[4]);
+            move->torow = rowidx(mstr[5]);
+        }
     }
 
+    
     if (move->piece) {
         move->piece |= mycolor;
+        if (move->fromfile == POS_UNSPECIFIED
+            || move->fromrow == POS_UNSPECIFIED) {
+            return getlocation(board, move) && chkidx(move);
+        } else {
+            return chkidx(move);
+        }
+    } else {
+        return FALSE;
     }
-    
-    if (!getlocation(board, move)) {
-        // TODO: return status code to indicate the error type
-        move->piece = 0;
-    }
-    
-    return move->piece != 0;
+    // TODO: return status code to indicate the error type
 }
 
 static int sendmove(Board board, uint8_t mycolor, int opponent) {
--- a/src/game.h	Wed Mar 26 13:16:49 2014 +0100
+++ b/src/game.h	Wed Mar 26 14:12:59 2014 +0100
@@ -78,11 +78,21 @@
 
 #define POS_UNSPECIFIED UINT8_MAX
 
+#define isidx(idx) ((uint8_t)idx < 8)
+
 #define isfile(file) (file >= 'a' && file <= 'h')
 #define isrow(row) (row >= '1' && row <= '8')
+
 #define rowidx(row) (row-'1')
 #define fileidx(file) (file-'a')
 
+#define chkidx(move) (isidx(move->fromfile) && isidx(move->fromrow) && \
+        isidx(move->tofile) && isidx(move->torow))
+
+/* secure versions - use, if index is not checked with isidx() */
+#define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED)
+#define rowidx_s(c) (isrow(c)?rowidx(c):POS_UNSPECIFIED)
+
 void game_start(Settings *settings, int opponent);
 
 #ifdef	__cplusplus

mercurial