Wed, 26 Mar 2014 14:12:59 +0100
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 |
1.1 --- a/Makefile Wed Mar 26 13:16:49 2014 +0100 1.2 +++ b/Makefile Wed Mar 26 14:12:59 2014 +0100 1.3 @@ -28,9 +28,7 @@ 1.4 1.5 include conf.mk 1.6 1.7 -all: clean compile 1.8 - 1.9 -compile: build build/rules 1.10 +all: build build/rules 1.11 cd src; $(MAKE) 1.12 1.13 build:
2.1 --- a/src/game.c Wed Mar 26 13:16:49 2014 +0100 2.2 +++ b/src/game.c Wed Mar 26 14:12:59 2014 +0100 2.3 @@ -71,6 +71,12 @@ 2.4 } 2.5 } 2.6 2.7 +/** 2.8 + * Applies a move and deletes captured pieces. 2.9 + * 2.10 + * @param board the current board state 2.11 + * @param move the move to apply 2.12 + */ 2.13 static void apply_move(Board board, Move *move) { 2.14 board[move->fromrow][move->fromfile] = 0; 2.15 // TODO: care for en passant capture 2.16 @@ -91,9 +97,20 @@ 2.17 } 2.18 } 2.19 2.20 +/** 2.21 + * Validates move by applying chess rules. 2.22 + * @param board the current board state 2.23 + * @param move the move to validate 2.24 + * @return TRUE, if the move complies to chess rules, FALSE otherwise 2.25 + */ 2.26 static _Bool validate_move(Board board, Move *move) { 2.27 _Bool result; 2.28 2.29 + /* validate indices (don't trust opponent) */ 2.30 + if (!chkidx(move)) { 2.31 + return FALSE; 2.32 + } 2.33 + 2.34 /* does piece exist */ 2.35 result = board[move->fromrow][move->fromfile] == move->piece; 2.36 2.37 @@ -162,7 +179,7 @@ 2.38 * @return TRUE if the location could be retrieved, FALSE if the location is 2.39 * ambiguous 2.40 */ 2.41 -static _Bool getlocation(Board board, Move *move) { 2.42 +static _Bool getlocation(Board board, Move *move) { 2.43 uint8_t piece = move->piece & PIECE_MASK; 2.44 switch (piece) { 2.45 case PAWN: return pawn_getlocation(board, move); 2.46 @@ -203,11 +220,9 @@ 2.47 2.48 if (len == 2) { 2.49 /* pawn move (e.g. "e4") */ 2.50 - if (isfile(mstr[0]) && isrow(mstr[1])) { 2.51 - move->piece = PAWN; 2.52 - move->tofile = fileidx(mstr[0]); 2.53 - move->torow = rowidx(mstr[1]); 2.54 - } 2.55 + move->piece = PAWN; 2.56 + move->tofile = fileidx(mstr[0]); 2.57 + move->torow = rowidx(mstr[1]); 2.58 } else if (len == 3) { 2.59 if (strcmp(mstr, "O-O") == 0) { 2.60 /* king side castling */ 2.61 @@ -216,17 +231,27 @@ 2.62 move->tofile = fileidx('g'); 2.63 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 2.64 } else { 2.65 - /* unambiguous move (e.g. "Nf3") */ 2.66 + /* move (e.g. "Nf3") */ 2.67 move->piece = getpiece(mstr[0]); 2.68 - move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED; 2.69 - move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED; 2.70 + move->tofile = fileidx(mstr[1]); 2.71 + move->torow = rowidx(mstr[2]); 2.72 } 2.73 2.74 } else if (len == 4) { 2.75 - /* ambiguous move (e.g. "Ndf3") */ 2.76 - 2.77 - /* unambiguous capture (e.g. "Nxf3", "dxe5") */ 2.78 - 2.79 + move->piece = getpiece(mstr[0]); 2.80 + if (mstr[1] == 'x') { 2.81 + /* capture (e.g. "Nxf3", "dxe5") */ 2.82 + move->capture = TRUE; 2.83 + if (!move->piece) { 2.84 + move->piece = PAWN; 2.85 + move->fromfile = fileidx(mstr[0]); 2.86 + } 2.87 + } else { 2.88 + /* move (e.g. "Ndf3") */ 2.89 + move->fromfile = fileidx(mstr[1]); 2.90 + } 2.91 + move->tofile = fileidx(mstr[2]); 2.92 + move->torow = rowidx(mstr[3]); 2.93 } else if (len == 5) { 2.94 if (strcmp(mstr, "O-O-O") == 0) { 2.95 /* queen side castling "O-O-O" */ 2.96 @@ -235,26 +260,51 @@ 2.97 move->tofile = fileidx('c'); 2.98 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 2.99 } else { 2.100 - /* ambiguous capture (e.g. "Ndxf3") */ 2.101 - 2.102 - /* long notation move (e.g. "Nc5a4") */ 2.103 - 2.104 - /* long notation capture (e.g. "e5xf6") */ 2.105 + move->piece = getpiece(mstr[0]); 2.106 + if (mstr[2] == 'x') { 2.107 + move->capture = TRUE; 2.108 + if (move->piece) { 2.109 + /* capture (e.g. "Ndxf3") */ 2.110 + move->fromfile = fileidx(mstr[1]); 2.111 + } else { 2.112 + /* long notation capture (e.g. "e5xf6") */ 2.113 + move->piece = PAWN; 2.114 + move->fromfile = fileidx(mstr[0]); 2.115 + move->fromrow = rowidx(mstr[1]); 2.116 + } 2.117 + } else { 2.118 + /* long notation move (e.g. "Nc5a4") */ 2.119 + move->fromfile = fileidx(mstr[1]); 2.120 + move->fromrow = rowidx(mstr[2]); 2.121 + } 2.122 + move->tofile = fileidx(mstr[3]); 2.123 + move->torow = rowidx(mstr[4]); 2.124 } 2.125 } else if (len == 6) { 2.126 /* long notation capture (e.g. "Nc5xf3") */ 2.127 + if (mstr[3] == 'x') { 2.128 + move->capture = TRUE; 2.129 + move->piece = getpiece(mstr[0]); 2.130 + move->fromfile = fileidx(mstr[1]); 2.131 + move->fromrow = rowidx(mstr[2]); 2.132 + move->tofile = fileidx(mstr[4]); 2.133 + move->torow = rowidx(mstr[5]); 2.134 + } 2.135 } 2.136 2.137 + 2.138 if (move->piece) { 2.139 move->piece |= mycolor; 2.140 + if (move->fromfile == POS_UNSPECIFIED 2.141 + || move->fromrow == POS_UNSPECIFIED) { 2.142 + return getlocation(board, move) && chkidx(move); 2.143 + } else { 2.144 + return chkidx(move); 2.145 + } 2.146 + } else { 2.147 + return FALSE; 2.148 } 2.149 - 2.150 - if (!getlocation(board, move)) { 2.151 - // TODO: return status code to indicate the error type 2.152 - move->piece = 0; 2.153 - } 2.154 - 2.155 - return move->piece != 0; 2.156 + // TODO: return status code to indicate the error type 2.157 } 2.158 2.159 static int sendmove(Board board, uint8_t mycolor, int opponent) {
3.1 --- a/src/game.h Wed Mar 26 13:16:49 2014 +0100 3.2 +++ b/src/game.h Wed Mar 26 14:12:59 2014 +0100 3.3 @@ -78,11 +78,21 @@ 3.4 3.5 #define POS_UNSPECIFIED UINT8_MAX 3.6 3.7 +#define isidx(idx) ((uint8_t)idx < 8) 3.8 + 3.9 #define isfile(file) (file >= 'a' && file <= 'h') 3.10 #define isrow(row) (row >= '1' && row <= '8') 3.11 + 3.12 #define rowidx(row) (row-'1') 3.13 #define fileidx(file) (file-'a') 3.14 3.15 +#define chkidx(move) (isidx(move->fromfile) && isidx(move->fromrow) && \ 3.16 + isidx(move->tofile) && isidx(move->torow)) 3.17 + 3.18 +/* secure versions - use, if index is not checked with isidx() */ 3.19 +#define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED) 3.20 +#define rowidx_s(c) (isrow(c)?rowidx(c):POS_UNSPECIFIED) 3.21 + 3.22 void game_start(Settings *settings, int opponent); 3.23 3.24 #ifdef __cplusplus