Fri, 28 Mar 2014 14:32:52 +0100
introduced status codes for get_location to produce detailed error messages + added knight rules
1.1 --- a/src/game.c Fri Mar 28 11:45:01 2014 +0100 1.2 +++ b/src/game.c Fri Mar 28 14:32:52 2014 +0100 1.3 @@ -147,19 +147,19 @@ 1.4 result = result && !pawn_isblocked(board, move); 1.5 break; 1.6 case ROOK: 1.7 - result = result && rook_chkrules(board, move); 1.8 + result = result && rook_chkrules(move); 1.9 result = result && !rook_isblocked(board, move); 1.10 break; 1.11 case KNIGHT: 1.12 - result = result && knight_chkrules(board, move); 1.13 + result = result && knight_chkrules(move); 1.14 result = result && !knight_isblocked(board, move); 1.15 break; 1.16 case BISHOP: 1.17 - result = result && bishop_chkrules(board, move); 1.18 + result = result && bishop_chkrules(move); 1.19 result = result && !bishop_isblocked(board, move); 1.20 break; 1.21 case QUEEN: 1.22 - result = result && queen_chkrules(board, move); 1.23 + result = result && queen_chkrules(move); 1.24 result = result && !queen_isblocked(board, move); 1.25 break; 1.26 case KING: 1.27 @@ -203,10 +203,9 @@ 1.28 * 1.29 * @param board the current state of the board 1.30 * @param move the move date to operate on 1.31 - * @return TRUE if the location could be retrieved, FALSE if the location is 1.32 - * ambiguous 1.33 + * @return status code (see rules/rules.h for the codes) 1.34 */ 1.35 -static _Bool getlocation(Board board, Move *move) { 1.36 +static int getlocation(Board board, Move *move) { 1.37 uint8_t piece = move->piece & PIECE_MASK; 1.38 switch (piece) { 1.39 case PAWN: return pawn_getlocation(board, move); 1.40 @@ -215,7 +214,7 @@ 1.41 case BISHOP: return bishop_getlocation(board, move); 1.42 case QUEEN: return queen_getlocation(board, move); 1.43 case KING: return king_getlocation(board, move); 1.44 - default: return FALSE; 1.45 + default: return INVALID_MOVE_SYNTAX; 1.46 } 1.47 } 1.48 1.49 @@ -227,9 +226,9 @@ 1.50 * @param mycolor the color of the current player 1.51 * @param mstr the input string to parse 1.52 * @param move a pointer to object where the move data shall be stored 1.53 - * @return TRUE, if the move is syntactically valid, FALSE otherwise 1.54 + * @return status code (see rules/rules.h for the list of codes) 1.55 */ 1.56 -static _Bool eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { 1.57 +static int eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { 1.58 memset(move, 0, sizeof(Move)); 1.59 move->fromfile = POS_UNSPECIFIED; 1.60 move->fromrow = POS_UNSPECIFIED; 1.61 @@ -331,14 +330,13 @@ 1.62 move->piece |= mycolor; 1.63 if (move->fromfile == POS_UNSPECIFIED 1.64 || move->fromrow == POS_UNSPECIFIED) { 1.65 - return getlocation(board, move) && chkidx(move); 1.66 + return getlocation(board, move); 1.67 } else { 1.68 - return chkidx(move); 1.69 + return chkidx(move) ? VALID_MOVE_SYNTAX : INVALID_POSITION; 1.70 } 1.71 } else { 1.72 - return FALSE; 1.73 + return INVALID_MOVE_SYNTAX; 1.74 } 1.75 - // TODO: return status code to indicate the error type 1.76 } 1.77 1.78 static int sendmove(Board board, uint8_t mycolor, int opponent) { 1.79 @@ -366,6 +364,7 @@ 1.80 1.81 if (strncmp(movestr, "surr", buflen) == 0) { 1.82 printw("You surrendered!"); 1.83 + clrtoeol(); 1.84 refresh(); 1.85 net_send_code(opponent, NETCODE_SURRENDER); 1.86 return 1; 1.87 @@ -385,28 +384,40 @@ 1.88 } 1.89 } else { 1.90 Move move; 1.91 - if (eval_move(board, mycolor, movestr, &move)) { 1.92 - net_send_code(opponent, NETCODE_MOVE); 1.93 - net_send_data(opponent, &move, sizeof(Move)); 1.94 - code = net_recieve_code(opponent); 1.95 - move.check = code == NETCODE_CHECK; 1.96 - move.checkmate = code == NETCODE_CHECKMATE; 1.97 - // TODO: record move 1.98 - if (code == NETCODE_DECLINE) { 1.99 - printw("Invalid move."); 1.100 - clrtoeol(); 1.101 - } else { 1.102 - apply_move(board, &move); 1.103 - if (move.checkmate) { 1.104 - printw("Checkmate!"); 1.105 - return 1; 1.106 + int eval_result = eval_move(board, mycolor, movestr, &move); 1.107 + switch (eval_result) { 1.108 + case VALID_MOVE_SYNTAX: 1.109 + net_send_code(opponent, NETCODE_MOVE); 1.110 + net_send_data(opponent, &move, sizeof(Move)); 1.111 + code = net_recieve_code(opponent); 1.112 + move.check = code == NETCODE_CHECK; 1.113 + move.checkmate = code == NETCODE_CHECKMATE; 1.114 + // TODO: record move 1.115 + if (code == NETCODE_DECLINE) { 1.116 + printw("Invalid move."); 1.117 } else { 1.118 - return 0; 1.119 + apply_move(board, &move); 1.120 + if (move.checkmate) { 1.121 + printw("Checkmate!"); 1.122 + clrtoeol(); 1.123 + return 1; 1.124 + } else { 1.125 + return 0; 1.126 + } 1.127 } 1.128 - } 1.129 - } else { 1.130 - printw("Can't interpret move - please use algebraic notation."); 1.131 + break; 1.132 + case AMBIGUOUS_MOVE: 1.133 + printw("Ambiguous move - " 1.134 + "please specify the piece to move."); 1.135 + break; 1.136 + case INVALID_POSITION: 1.137 + printw("Cannot find the piece that shall be moved."); 1.138 + break; 1.139 + default: 1.140 + printw("Can't interpret move - " 1.141 + "please use algebraic notation."); 1.142 } 1.143 + clrtoeol(); 1.144 } 1.145 } 1.146 }
2.1 --- a/src/game.h Fri Mar 28 11:45:01 2014 +0100 2.2 +++ b/src/game.h Fri Mar 28 14:32:52 2014 +0100 2.3 @@ -78,8 +78,8 @@ 2.4 } Move; 2.5 2.6 #define POS_UNSPECIFIED UINT8_MAX 2.7 -#define mdst(b,m) b[m->torow][m->tofile] 2.8 -#define msrc(b,m) b[m->fromrow][m->fromfile] 2.9 +#define mdst(b,m) b[(m)->torow][(m)->tofile] 2.10 +#define msrc(b,m) b[(m)->fromrow][(m)->fromfile] 2.11 2.12 #define isidx(idx) ((uint8_t)idx < 8) 2.13 2.14 @@ -89,8 +89,8 @@ 2.15 #define rowidx(row) (row-'1') 2.16 #define fileidx(file) (file-'a') 2.17 2.18 -#define chkidx(move) (isidx(move->fromfile) && isidx(move->fromrow) && \ 2.19 - isidx(move->tofile) && isidx(move->torow)) 2.20 +#define chkidx(move) (isidx((move)->fromfile) && isidx((move)->fromrow) && \ 2.21 + isidx((move)->tofile) && isidx((move)->torow)) 2.22 2.23 /* secure versions - use, if index is not checked with isidx() */ 2.24 #define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED)
3.1 --- a/src/main.c Fri Mar 28 11:45:01 2014 +0100 3.2 +++ b/src/main.c Fri Mar 28 14:32:52 2014 +0100 3.3 @@ -159,7 +159,7 @@ 3.4 "Example: -t 150s\n" 3.5 ); 3.6 return EXIT_SUCCESS; 3.7 - } 3.8 + } 3.9 tchess_window = initscr(); 3.10 cbreak(); 3.11 if (has_colors()) {
4.1 --- a/src/rules/bishop.c Fri Mar 28 11:45:01 2014 +0100 4.2 +++ b/src/rules/bishop.c Fri Mar 28 14:32:52 2014 +0100 4.3 @@ -28,8 +28,9 @@ 4.4 */ 4.5 4.6 #include "bishop.h" 4.7 +#include "rules.h" 4.8 4.9 -_Bool bishop_chkrules(Board board, Move* move) { 4.10 +_Bool bishop_chkrules(Move* move) { 4.11 // TODO: implement 4.12 return FALSE; 4.13 } 4.14 @@ -39,7 +40,7 @@ 4.15 return TRUE; 4.16 } 4.17 4.18 -_Bool bishop_getlocation(Board board, Move *move) { 4.19 +int bishop_getlocation(Board board, Move *move) { 4.20 // TODO: implement 4.21 - return FALSE; 4.22 + return INVALID_MOVE_SYNTAX; 4.23 }
5.1 --- a/src/rules/bishop.h Fri Mar 28 11:45:01 2014 +0100 5.2 +++ b/src/rules/bishop.h Fri Mar 28 14:32:52 2014 +0100 5.3 @@ -36,9 +36,9 @@ 5.4 extern "C" { 5.5 #endif 5.6 5.7 -_Bool bishop_chkrules(Board board, Move *move); 5.8 +_Bool bishop_chkrules(Move *move); 5.9 _Bool bishop_isblocked(Board board, Move *move); 5.10 -_Bool bishop_getlocation(Board board, Move *move); 5.11 +int bishop_getlocation(Board board, Move *move); 5.12 5.13 #ifdef __cplusplus 5.14 }
6.1 --- a/src/rules/king.c Fri Mar 28 11:45:01 2014 +0100 6.2 +++ b/src/rules/king.c Fri Mar 28 14:32:52 2014 +0100 6.3 @@ -27,6 +27,7 @@ 6.4 * 6.5 */ 6.6 6.7 +#include "rules.h" 6.8 #include "king.h" 6.9 6.10 _Bool king_chkrules(Board board, Move* move) { 6.11 @@ -39,7 +40,7 @@ 6.12 return TRUE; 6.13 } 6.14 6.15 -_Bool king_getlocation(Board board, Move *move) { 6.16 +int king_getlocation(Board board, Move *move) { 6.17 // TODO: implement 6.18 - return FALSE; 6.19 + return INVALID_MOVE_SYNTAX; 6.20 }
7.1 --- a/src/rules/king.h Fri Mar 28 11:45:01 2014 +0100 7.2 +++ b/src/rules/king.h Fri Mar 28 14:32:52 2014 +0100 7.3 @@ -39,7 +39,7 @@ 7.4 7.5 _Bool king_chkrules(Board board, Move *move); 7.6 _Bool king_isblocked(Board board, Move *move); 7.7 -_Bool king_getlocation(Board board, Move *move); 7.8 +int king_getlocation(Board board, Move *move); 7.9 7.10 #ifdef __cplusplus 7.11 }
8.1 --- a/src/rules/knight.c Fri Mar 28 11:45:01 2014 +0100 8.2 +++ b/src/rules/knight.c Fri Mar 28 14:32:52 2014 +0100 8.3 @@ -28,18 +28,106 @@ 8.4 */ 8.5 8.6 #include "knight.h" 8.7 +#include "rules.h" 8.8 +#include <math.h> 8.9 8.10 -_Bool knight_chkrules(Board board, Move *move) { 8.11 - // TODO: implement 8.12 - return FALSE; 8.13 +_Bool knight_chkrules(Move *move) { 8.14 + int dx = abs(move->fromfile - move->tofile); 8.15 + int dy = abs(move->fromrow - move->torow); 8.16 + 8.17 + return (dx == 2 && dy == 1) || (dx == 1 && dy == 2); 8.18 } 8.19 8.20 -_Bool knight_isblocked(Board board, Move *move) { 8.21 - // TODO: implement 8.22 - return TRUE; 8.23 +static int knight_getloc_fixedrow(Board board, Move *move) { 8.24 + int d = 3 - abs(move->fromrow - move->torow); 8.25 + 8.26 + if (d == 1 || d == 2) { 8.27 + if (move->tofile < 6 && 8.28 + board[move->fromrow][move->tofile + d] == move->piece) { 8.29 + if (move->fromfile == POS_UNSPECIFIED) { 8.30 + move->fromfile = move->tofile + d; 8.31 + return VALID_MOVE_SYNTAX; 8.32 + } else { 8.33 + return AMBIGUOUS_MOVE; 8.34 + } 8.35 + } 8.36 + if (move->tofile > 1 && 8.37 + board[move->fromrow][move->tofile - d] == move->piece) { 8.38 + if (move->fromfile == POS_UNSPECIFIED) { 8.39 + move->fromfile = move->tofile - d; 8.40 + return VALID_MOVE_SYNTAX; 8.41 + } else { 8.42 + return AMBIGUOUS_MOVE; 8.43 + } 8.44 + } 8.45 + } 8.46 + 8.47 + return INVALID_POSITION; 8.48 } 8.49 8.50 -_Bool knight_getlocation(Board board, Move *move) { 8.51 - // TODO: implement 8.52 - return FALSE; 8.53 +static int knight_getloc_fixedfile(Board board, Move *move) { 8.54 + int d = 3 - abs(move->fromfile - move->tofile); 8.55 + 8.56 + if (d == 1 || d == 2) { 8.57 + if (move->torow < 6 && 8.58 + board[move->torow + d][move->fromfile] == move->piece) { 8.59 + if (move->fromrow == POS_UNSPECIFIED) { 8.60 + move->fromrow = move->torow + d; 8.61 + return VALID_MOVE_SYNTAX; 8.62 + } else { 8.63 + return AMBIGUOUS_MOVE; 8.64 + } 8.65 + } 8.66 + if (move->torow > 1 && 8.67 + board[move->torow - d][move->fromfile] == move->piece) { 8.68 + if (move->fromrow == POS_UNSPECIFIED) { 8.69 + move->fromrow = move->torow - d; 8.70 + return VALID_MOVE_SYNTAX; 8.71 + } else { 8.72 + return AMBIGUOUS_MOVE; 8.73 + } 8.74 + } 8.75 + } 8.76 + 8.77 + return INVALID_POSITION; 8.78 } 8.79 + 8.80 +int knight_getlocation(Board board, Move *move) { 8.81 + 8.82 + if (move->fromfile != POS_UNSPECIFIED) { 8.83 + return knight_getloc_fixedfile(board, move); 8.84 + } 8.85 + 8.86 + if (move->fromrow != POS_UNSPECIFIED) { 8.87 + return knight_getloc_fixedrow(board, move); 8.88 + } 8.89 + 8.90 + for (int x = -2 ; x <= 2 ; x++) { 8.91 + if (x == 0) { 8.92 + continue; 8.93 + } 8.94 + for (int y = -2 ; y <= 2 ; y++) { 8.95 + if (y == 0 || y == x) { 8.96 + continue; 8.97 + } 8.98 + uint8_t cx = move->tofile + x; 8.99 + uint8_t cy = move->torow + y; 8.100 + 8.101 + if (isidx(cx) && isidx(cy) && board[cy][cx] == move->piece) { 8.102 + if (move->fromfile == POS_UNSPECIFIED 8.103 + && move->fromrow == POS_UNSPECIFIED) { 8.104 + move->fromfile = cx; 8.105 + move->fromrow = cy; 8.106 + } else { 8.107 + return AMBIGUOUS_MOVE; 8.108 + } 8.109 + } 8.110 + } 8.111 + } 8.112 + 8.113 + if (move->fromfile == POS_UNSPECIFIED || move->fromrow == POS_UNSPECIFIED) { 8.114 + return INVALID_POSITION; 8.115 + } else { 8.116 + return VALID_MOVE_SYNTAX; 8.117 + } 8.118 +}
9.1 --- a/src/rules/knight.h Fri Mar 28 11:45:01 2014 +0100 9.2 +++ b/src/rules/knight.h Fri Mar 28 14:32:52 2014 +0100 9.3 @@ -36,9 +36,9 @@ 9.4 extern "C" { 9.5 #endif 9.6 9.7 -_Bool knight_chkrules(Board board, Move *move); 9.8 -_Bool knight_isblocked(Board board, Move *move); 9.9 -_Bool knight_getlocation(Board board, Move *move); 9.10 +_Bool knight_chkrules(Move *move); 9.11 +#define knight_isblocked(b,m) FALSE 9.12 +int knight_getlocation(Board board, Move *move); 9.13 9.14 #ifdef __cplusplus 9.15 }
10.1 --- a/src/rules/pawn.c Fri Mar 28 11:45:01 2014 +0100 10.2 +++ b/src/rules/pawn.c Fri Mar 28 14:32:52 2014 +0100 10.3 @@ -28,6 +28,7 @@ 10.4 */ 10.5 10.6 #include "pawn.h" 10.7 +#include "rules.h" 10.8 10.9 _Bool pawn_chkrules(Board board, Move *move) { 10.10 int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1); 10.11 @@ -56,7 +57,7 @@ 10.12 return mdst(board,move) && !move->capture; 10.13 } 10.14 10.15 -_Bool pawn_getlocation(Board board, Move *move) { 10.16 +int pawn_getlocation(Board board, Move *move) { 10.17 int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1); 10.18 10.19 if (move->fromfile == POS_UNSPECIFIED) { 10.20 @@ -64,7 +65,7 @@ 10.21 } 10.22 move->fromrow = move->torow + d; 10.23 if (move->fromrow > 6) { 10.24 - return FALSE; 10.25 + return INVALID_POSITION; 10.26 } else { 10.27 /* advanced first move */ 10.28 if (move->fromrow == (d < 0 ? 2 : 5) && 10.29 @@ -72,9 +73,9 @@ 10.30 10.31 move->fromrow += d; 10.32 if (move->fromrow > 6) { 10.33 - return FALSE; 10.34 + return INVALID_POSITION; 10.35 } 10.36 } 10.37 } 10.38 - return TRUE; 10.39 + return VALID_MOVE_SYNTAX; 10.40 }
11.1 --- a/src/rules/pawn.h Fri Mar 28 11:45:01 2014 +0100 11.2 +++ b/src/rules/pawn.h Fri Mar 28 14:32:52 2014 +0100 11.3 @@ -38,7 +38,7 @@ 11.4 11.5 _Bool pawn_chkrules(Board board, Move *move); 11.6 _Bool pawn_isblocked(Board board, Move *move); 11.7 -_Bool pawn_getlocation(Board board, Move *move); 11.8 +int pawn_getlocation(Board board, Move *move); 11.9 11.10 #ifdef __cplusplus 11.11 }
12.1 --- a/src/rules/queen.c Fri Mar 28 11:45:01 2014 +0100 12.2 +++ b/src/rules/queen.c Fri Mar 28 14:32:52 2014 +0100 12.3 @@ -27,9 +27,10 @@ 12.4 * 12.5 */ 12.6 12.7 +#include "rules.h" 12.8 #include "queen.h" 12.9 12.10 -_Bool queen_chkrules(Board board, Move* move) { 12.11 +_Bool queen_chkrules(Move* move) { 12.12 // TODO: implement 12.13 return FALSE; 12.14 } 12.15 @@ -39,7 +40,7 @@ 12.16 return TRUE; 12.17 } 12.18 12.19 -_Bool queen_getlocation(Board board, Move *move) { 12.20 +int queen_getlocation(Board board, Move *move) { 12.21 // TODO: implement 12.22 - return FALSE; 12.23 + return INVALID_MOVE_SYNTAX; 12.24 }
13.1 --- a/src/rules/queen.h Fri Mar 28 11:45:01 2014 +0100 13.2 +++ b/src/rules/queen.h Fri Mar 28 14:32:52 2014 +0100 13.3 @@ -36,9 +36,9 @@ 13.4 extern "C" { 13.5 #endif 13.6 13.7 -_Bool queen_chkrules(Board board, Move *move); 13.8 +_Bool queen_chkrules(Move *move); 13.9 _Bool queen_isblocked(Board board, Move *move); 13.10 -_Bool queen_getlocation(Board board, Move *move); 13.11 +int queen_getlocation(Board board, Move *move); 13.12 13.13 #ifdef __cplusplus 13.14 }
14.1 --- a/src/rules/rook.c Fri Mar 28 11:45:01 2014 +0100 14.2 +++ b/src/rules/rook.c Fri Mar 28 14:32:52 2014 +0100 14.3 @@ -27,9 +27,10 @@ 14.4 * 14.5 */ 14.6 14.7 +#include "rules.h" 14.8 #include "rook.h" 14.9 14.10 -_Bool rook_chkrules(Board board, Move *move) { 14.11 +_Bool rook_chkrules(Move *move) { 14.12 // TODO: implement 14.13 return FALSE; 14.14 } 14.15 @@ -39,7 +40,7 @@ 14.16 return TRUE; 14.17 } 14.18 14.19 -_Bool rook_getlocation(Board board, Move *move) { 14.20 +int rook_getlocation(Board board, Move *move) { 14.21 // TODO: implement 14.22 - return FALSE; 14.23 + return INVALID_MOVE_SYNTAX; 14.24 }
15.1 --- a/src/rules/rook.h Fri Mar 28 11:45:01 2014 +0100 15.2 +++ b/src/rules/rook.h Fri Mar 28 14:32:52 2014 +0100 15.3 @@ -36,9 +36,9 @@ 15.4 extern "C" { 15.5 #endif 15.6 15.7 -_Bool rook_chkrules(Board board, Move *move); 15.8 +_Bool rook_chkrules(Move *move); 15.9 _Bool rook_isblocked(Board board, Move *move); 15.10 -_Bool rook_getlocation(Board board, Move *move); 15.11 +int rook_getlocation(Board board, Move *move); 15.12 15.13 #ifdef __cplusplus 15.14 }
16.1 --- a/src/rules/rules.h Fri Mar 28 11:45:01 2014 +0100 16.2 +++ b/src/rules/rules.h Fri Mar 28 14:32:52 2014 +0100 16.3 @@ -37,5 +37,10 @@ 16.4 #include "queen.h" 16.5 #include "king.h" 16.6 16.7 +#define VALID_MOVE_SYNTAX 0 16.8 +#define INVALID_MOVE_SYNTAX 1 16.9 +#define INVALID_POSITION 2 16.10 +#define AMBIGUOUS_MOVE 3 16.11 + 16.12 #endif /* RULES_H */ 16.13