Mon, 31 Mar 2014 15:03:25 +0200
introduced game state structure
1.1 --- a/src/chess/bishop.c Mon Mar 31 14:08:00 2014 +0200 1.2 +++ b/src/chess/bishop.c Mon Mar 31 15:03:25 2014 +0200 1.3 @@ -35,7 +35,7 @@ 1.4 return abs(move->torow-move->fromrow) == abs(move->tofile-move->fromfile); 1.5 } 1.6 1.7 -_Bool bishop_isblocked(Board board, Move *move) { 1.8 +_Bool bishop_isblocked(GameState *gamestate, Move *move) { 1.9 int dy = move->torow > move->fromrow ? 1 : -1; 1.10 int dx = move->tofile > move->fromfile ? 1 : -1; 1.11 1.12 @@ -45,7 +45,7 @@ 1.13 while (x != move->tofile-dx && y != move->torow-dy) { 1.14 x += dx; 1.15 y += dy; 1.16 - if (board[y][x]) { 1.17 + if (gamestate->board[y][x]) { 1.18 return 1; 1.19 } 1.20 } 1.21 @@ -53,12 +53,12 @@ 1.22 return 0; 1.23 } 1.24 1.25 -static int bishop_getloc_fixedfile(Board board, Move *move) { 1.26 +static int bishop_getloc_fixedfile(GameState *gamestate, Move *move) { 1.27 uint8_t d = abs(move->fromfile - move->tofile); 1.28 - if (board[move->torow - d][move->fromfile] == move->piece) { 1.29 + if (gamestate->board[move->torow - d][move->fromfile] == move->piece) { 1.30 move->fromrow = move->torow - d; 1.31 } 1.32 - if (board[move->torow + d][move->fromfile] == move->piece) { 1.33 + if (gamestate->board[move->torow + d][move->fromfile] == move->piece) { 1.34 if (move->fromrow == POS_UNSPECIFIED) { 1.35 move->fromrow = move->torow + d; 1.36 } else { 1.37 @@ -69,12 +69,12 @@ 1.38 INVALID_POSITION : VALID_MOVE_SYNTAX; 1.39 } 1.40 1.41 -static int bishop_getloc_fixedrow(Board board, Move *move) { 1.42 +static int bishop_getloc_fixedrow(GameState *gamestate, Move *move) { 1.43 uint8_t d = abs(move->fromrow - move->torow); 1.44 - if (board[move->fromrow][move->tofile - d] == move->piece) { 1.45 + if (gamestate->board[move->fromrow][move->tofile - d] == move->piece) { 1.46 move->fromfile = move->tofile - d; 1.47 } 1.48 - if (board[move->fromrow][move->tofile + d] == move->piece) { 1.49 + if (gamestate->board[move->fromrow][move->tofile + d] == move->piece) { 1.50 if (move->fromfile == POS_UNSPECIFIED) { 1.51 move->fromfile = move->tofile + d; 1.52 } else { 1.53 @@ -85,14 +85,14 @@ 1.54 INVALID_POSITION : VALID_MOVE_SYNTAX; 1.55 } 1.56 1.57 -int bishop_getlocation(Board board, Move *move) { 1.58 +int bishop_getlocation(GameState *gamestate, Move *move) { 1.59 1.60 if (move->fromfile != POS_UNSPECIFIED) { 1.61 - return bishop_getloc_fixedfile(board, move); 1.62 + return bishop_getloc_fixedfile(gamestate, move); 1.63 } 1.64 1.65 if (move->fromrow != POS_UNSPECIFIED) { 1.66 - return bishop_getloc_fixedrow(board, move); 1.67 + return bishop_getloc_fixedrow(gamestate, move); 1.68 } 1.69 1.70 _Bool amb = 0; 1.71 @@ -100,7 +100,7 @@ 1.72 uint8_t row = move->torow + d; 1.73 if (isidx(row)) { 1.74 uint8_t file = move->tofile + d; 1.75 - if (isidx(file) && board[row][file] == move->piece) { 1.76 + if (isidx(file) && gamestate->board[row][file] == move->piece) { 1.77 if (amb) { 1.78 return AMBIGUOUS_MOVE; 1.79 } 1.80 @@ -109,7 +109,7 @@ 1.81 move->fromfile = file; 1.82 } 1.83 file = move->tofile - d; 1.84 - if (isidx(file) && board[row][file] == move->piece) { 1.85 + if (isidx(file) && gamestate->board[row][file] == move->piece) { 1.86 if (amb) { 1.87 return AMBIGUOUS_MOVE; 1.88 }
2.1 --- a/src/chess/bishop.h Mon Mar 31 14:08:00 2014 +0200 2.2 +++ b/src/chess/bishop.h Mon Mar 31 15:03:25 2014 +0200 2.3 @@ -37,8 +37,8 @@ 2.4 #endif 2.5 2.6 _Bool bishop_chkrules(Move *move); 2.7 -_Bool bishop_isblocked(Board board, Move *move); 2.8 -int bishop_getlocation(Board board, Move *move); 2.9 +_Bool bishop_isblocked(GameState *gamestate, Move *move); 2.10 +int bishop_getlocation(GameState *gamestate, Move *move); 2.11 2.12 #ifdef __cplusplus 2.13 }
3.1 --- a/src/chess/king.c Mon Mar 31 14:08:00 2014 +0200 3.2 +++ b/src/chess/king.c Mon Mar 31 15:03:25 2014 +0200 3.3 @@ -30,17 +30,17 @@ 3.4 #include "rules.h" 3.5 #include "king.h" 3.6 3.7 -_Bool king_chkrules(Board board, Move* move) { 3.8 +_Bool king_chkrules(GameState *gamestate, Move* move) { 3.9 // TODO: implement 3.10 return 0; 3.11 } 3.12 3.13 -_Bool king_isblocked(Board board, Move *move) { 3.14 +_Bool king_isblocked(GameState *gamestate, Move *move) { 3.15 // TODO: implement 3.16 return 1; 3.17 } 3.18 3.19 -int king_getlocation(Board board, Move *move) { 3.20 +int king_getlocation(GameState *gamestate, Move *move) { 3.21 // TODO: implement 3.22 return INVALID_MOVE_SYNTAX; 3.23 }
4.1 --- a/src/chess/king.h Mon Mar 31 14:08:00 2014 +0200 4.2 +++ b/src/chess/king.h Mon Mar 31 15:03:25 2014 +0200 4.3 @@ -37,9 +37,9 @@ 4.4 extern "C" { 4.5 #endif 4.6 4.7 -_Bool king_chkrules(Board board, Move *move); 4.8 -_Bool king_isblocked(Board board, Move *move); 4.9 -int king_getlocation(Board board, Move *move); 4.10 +_Bool king_chkrules(GameState *gamestate, Move *move); 4.11 +_Bool king_isblocked(GameState *gamestate, Move *move); 4.12 +int king_getlocation(GameState *gamestate, Move *move); 4.13 4.14 #ifdef __cplusplus 4.15 }
5.1 --- a/src/chess/knight.c Mon Mar 31 14:08:00 2014 +0200 5.2 +++ b/src/chess/knight.c Mon Mar 31 15:03:25 2014 +0200 5.3 @@ -38,12 +38,12 @@ 5.4 return (dx == 2 && dy == 1) || (dx == 1 && dy == 2); 5.5 } 5.6 5.7 -static int knight_getloc_fixedrow(Board board, Move *move) { 5.8 +static int knight_getloc_fixedrow(GameState *gamestate, Move *move) { 5.9 int d = 3 - abs(move->fromrow - move->torow); 5.10 5.11 if (d == 1 || d == 2) { 5.12 if (move->tofile < 6 && 5.13 - board[move->fromrow][move->tofile + d] == move->piece) { 5.14 + gamestate->board[move->fromrow][move->tofile + d] == move->piece) { 5.15 if (move->fromfile == POS_UNSPECIFIED) { 5.16 move->fromfile = move->tofile + d; 5.17 return VALID_MOVE_SYNTAX; 5.18 @@ -52,7 +52,7 @@ 5.19 } 5.20 } 5.21 if (move->tofile > 1 && 5.22 - board[move->fromrow][move->tofile - d] == move->piece) { 5.23 + gamestate->board[move->fromrow][move->tofile - d] == move->piece) { 5.24 if (move->fromfile == POS_UNSPECIFIED) { 5.25 move->fromfile = move->tofile - d; 5.26 return VALID_MOVE_SYNTAX; 5.27 @@ -65,12 +65,12 @@ 5.28 return INVALID_POSITION; 5.29 } 5.30 5.31 -static int knight_getloc_fixedfile(Board board, Move *move) { 5.32 +static int knight_getloc_fixedfile(GameState *gamestate, Move *move) { 5.33 int d = 3 - abs(move->fromfile - move->tofile); 5.34 5.35 if (d == 1 || d == 2) { 5.36 if (move->torow < 6 && 5.37 - board[move->torow + d][move->fromfile] == move->piece) { 5.38 + gamestate->board[move->torow + d][move->fromfile] == move->piece) { 5.39 if (move->fromrow == POS_UNSPECIFIED) { 5.40 move->fromrow = move->torow + d; 5.41 return VALID_MOVE_SYNTAX; 5.42 @@ -79,7 +79,7 @@ 5.43 } 5.44 } 5.45 if (move->torow > 1 && 5.46 - board[move->torow - d][move->fromfile] == move->piece) { 5.47 + gamestate->board[move->torow - d][move->fromfile] == move->piece) { 5.48 if (move->fromrow == POS_UNSPECIFIED) { 5.49 move->fromrow = move->torow - d; 5.50 return VALID_MOVE_SYNTAX; 5.51 @@ -92,14 +92,14 @@ 5.52 return INVALID_POSITION; 5.53 } 5.54 5.55 -int knight_getlocation(Board board, Move *move) { 5.56 +int knight_getlocation(GameState *gamestate, Move *move) { 5.57 5.58 if (move->fromfile != POS_UNSPECIFIED) { 5.59 - return knight_getloc_fixedfile(board, move); 5.60 + return knight_getloc_fixedfile(gamestate, move); 5.61 } 5.62 5.63 if (move->fromrow != POS_UNSPECIFIED) { 5.64 - return knight_getloc_fixedrow(board, move); 5.65 + return knight_getloc_fixedrow(gamestate, move); 5.66 } 5.67 5.68 for (int x = -2 ; x <= 2 ; x++) { 5.69 @@ -113,7 +113,8 @@ 5.70 uint8_t cx = move->tofile + x; 5.71 uint8_t cy = move->torow + y; 5.72 5.73 - if (isidx(cx) && isidx(cy) && board[cy][cx] == move->piece) { 5.74 + if (isidx(cx) && isidx(cy) 5.75 + && gamestate->board[cy][cx] == move->piece) { 5.76 if (move->fromfile == POS_UNSPECIFIED 5.77 && move->fromrow == POS_UNSPECIFIED) { 5.78 move->fromfile = cx;
6.1 --- a/src/chess/knight.h Mon Mar 31 14:08:00 2014 +0200 6.2 +++ b/src/chess/knight.h Mon Mar 31 15:03:25 2014 +0200 6.3 @@ -37,8 +37,8 @@ 6.4 #endif 6.5 6.6 _Bool knight_chkrules(Move *move); 6.7 -#define knight_isblocked(b,m) 0 6.8 -int knight_getlocation(Board board, Move *move); 6.9 +#define knight_isblocked(gs,m) 0 6.10 +int knight_getlocation(GameState *gamestate, Move *move); 6.11 6.12 #ifdef __cplusplus 6.13 }
7.1 --- a/src/chess/pawn.c Mon Mar 31 14:08:00 2014 +0200 7.2 +++ b/src/chess/pawn.c Mon Mar 31 15:03:25 2014 +0200 7.3 @@ -30,7 +30,7 @@ 7.4 #include "pawn.h" 7.5 #include "rules.h" 7.6 7.7 -_Bool pawn_chkrules(Board board, Move *move) { 7.8 +_Bool pawn_chkrules(GameState *gamestate, Move *move) { 7.9 int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1); 7.10 7.11 if (move->torow == (d < 0 ? 7 : 0)) { 7.12 @@ -53,8 +53,9 @@ 7.13 move->fromfile == move->tofile + 1 || 7.14 move->fromfile == move->tofile - 1)) { 7.15 7.16 - return mdst(board,move) 7.17 - || (board[move->fromrow][move->tofile] & ENPASSANT_THREAT); 7.18 + return mdst(gamestate->board, move) || 7.19 + (gamestate->board[move->fromrow][move->tofile] 7.20 + & ENPASSANT_THREAT); 7.21 } else { 7.22 return 0; 7.23 } 7.24 @@ -69,11 +70,11 @@ 7.25 } 7.26 } 7.27 7.28 -_Bool pawn_isblocked(Board board, Move *move) { 7.29 - return mdst(board,move) && !move->capture; 7.30 +_Bool pawn_isblocked(GameState *gamestate, Move *move) { 7.31 + return mdst(gamestate->board, move) && !move->capture; 7.32 } 7.33 7.34 -int pawn_getlocation(Board board, Move *move) { 7.35 +int pawn_getlocation(GameState *gamestate, Move *move) { 7.36 int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1); 7.37 7.38 if (move->fromfile == POS_UNSPECIFIED) { 7.39 @@ -85,7 +86,7 @@ 7.40 } else { 7.41 /* advanced first move */ 7.42 if (move->fromrow == (d < 0 ? 2 : 5) && 7.43 - msrc(board,move) != move->piece) { 7.44 + msrc(gamestate->board,move) != move->piece) { 7.45 7.46 move->fromrow += d; 7.47 if (move->fromrow > 6) {
8.1 --- a/src/chess/pawn.h Mon Mar 31 14:08:00 2014 +0200 8.2 +++ b/src/chess/pawn.h Mon Mar 31 15:03:25 2014 +0200 8.3 @@ -36,9 +36,9 @@ 8.4 extern "C" { 8.5 #endif 8.6 8.7 -_Bool pawn_chkrules(Board board, Move *move); 8.8 -_Bool pawn_isblocked(Board board, Move *move); 8.9 -int pawn_getlocation(Board board, Move *move); 8.10 +_Bool pawn_chkrules(GameState *gamestate, Move *move); 8.11 +_Bool pawn_isblocked(GameState *gamestate, Move *move); 8.12 +int pawn_getlocation(GameState *gamestate, Move *move); 8.13 8.14 #ifdef __cplusplus 8.15 }
9.1 --- a/src/chess/queen.c Mon Mar 31 14:08:00 2014 +0200 9.2 +++ b/src/chess/queen.c Mon Mar 31 15:03:25 2014 +0200 9.3 @@ -35,12 +35,12 @@ 9.4 return 0; 9.5 } 9.6 9.7 -_Bool queen_isblocked(Board board, Move *move) { 9.8 +_Bool queen_isblocked(GameState *gamestate, Move *move) { 9.9 // TODO: implement 9.10 return 1; 9.11 } 9.12 9.13 -int queen_getlocation(Board board, Move *move) { 9.14 +int queen_getlocation(GameState *gamestate, Move *move) { 9.15 // TODO: implement 9.16 return INVALID_MOVE_SYNTAX; 9.17 }
10.1 --- a/src/chess/queen.h Mon Mar 31 14:08:00 2014 +0200 10.2 +++ b/src/chess/queen.h Mon Mar 31 15:03:25 2014 +0200 10.3 @@ -37,8 +37,8 @@ 10.4 #endif 10.5 10.6 _Bool queen_chkrules(Move *move); 10.7 -_Bool queen_isblocked(Board board, Move *move); 10.8 -int queen_getlocation(Board board, Move *move); 10.9 +_Bool queen_isblocked(GameState *gamestate, Move *move); 10.10 +int queen_getlocation(GameState *gamestate, Move *move); 10.11 10.12 #ifdef __cplusplus 10.13 }
11.1 --- a/src/chess/rook.c Mon Mar 31 14:08:00 2014 +0200 11.2 +++ b/src/chess/rook.c Mon Mar 31 15:03:25 2014 +0200 11.3 @@ -34,14 +34,14 @@ 11.4 return move->torow == move->fromrow || move->tofile == move->fromfile; 11.5 } 11.6 11.7 -_Bool rook_isblocked(Board board, Move *move) { 11.8 +_Bool rook_isblocked(GameState *gamestate, Move *move) { 11.9 11.10 if (move->torow == move->fromrow) { 11.11 int d = move->tofile > move->fromfile ? 1 : -1; 11.12 uint8_t f = move->fromfile; 11.13 while (f != move->tofile-d) { 11.14 f += d; 11.15 - if (board[move->fromrow][f]) { 11.16 + if (gamestate->board[move->fromrow][f]) { 11.17 return 1; 11.18 } 11.19 } 11.20 @@ -50,7 +50,7 @@ 11.21 uint8_t r = move->fromrow; 11.22 while (r != move->torow - d) { 11.23 r += d; 11.24 - if (board[r][move->fromfile]) { 11.25 + if (gamestate->board[r][move->fromfile]) { 11.26 return 1; 11.27 } 11.28 } 11.29 @@ -59,10 +59,10 @@ 11.30 return 0; 11.31 } 11.32 11.33 -static int rook_getloc_fixedrow(Board board, Move *move) { 11.34 +static int rook_getloc_fixedrow(GameState *gamestate, Move *move) { 11.35 uint8_t file = POS_UNSPECIFIED; 11.36 for (uint8_t f = 0 ; f < 8 ; f++) { 11.37 - if (board[move->fromrow][f] == move->piece) { 11.38 + if (gamestate->board[move->fromrow][f] == move->piece) { 11.39 if (file == POS_UNSPECIFIED) { 11.40 file = f; 11.41 } else { 11.42 @@ -78,10 +78,10 @@ 11.43 } 11.44 } 11.45 11.46 -static int rook_getloc_fixedfile(Board board, Move *move) { 11.47 +static int rook_getloc_fixedfile(GameState *gamestate, Move *move) { 11.48 uint8_t row = POS_UNSPECIFIED; 11.49 for (uint8_t r = 0 ; r < 8 ; r++) { 11.50 - if (board[r][move->fromfile] == move->piece) { 11.51 + if (gamestate->board[r][move->fromfile] == move->piece) { 11.52 if (row == POS_UNSPECIFIED) { 11.53 row = r; 11.54 } else { 11.55 @@ -97,13 +97,13 @@ 11.56 } 11.57 } 11.58 11.59 -int rook_getlocation(Board board, Move *move) { 11.60 +int rook_getlocation(GameState *gamestate, Move *move) { 11.61 11.62 if (move->fromfile != POS_UNSPECIFIED) { 11.63 if (move->fromfile == move->tofile) { 11.64 - return rook_getloc_fixedfile(board, move); 11.65 + return rook_getloc_fixedfile(gamestate, move); 11.66 } else { 11.67 - if (board[move->torow][move->fromfile] == move->piece) { 11.68 + if (gamestate->board[move->torow][move->fromfile] == move->piece) { 11.69 move->fromrow = move->torow; 11.70 return VALID_MOVE_SYNTAX; 11.71 } else { 11.72 @@ -114,9 +114,9 @@ 11.73 11.74 if (move->fromrow != POS_UNSPECIFIED) { 11.75 if (move->fromrow == move->torow) { 11.76 - return rook_getloc_fixedrow(board, move); 11.77 + return rook_getloc_fixedrow(gamestate, move); 11.78 } else { 11.79 - if (board[move->fromrow][move->tofile] == move->piece) { 11.80 + if (gamestate->board[move->fromrow][move->tofile] == move->piece) { 11.81 move->fromfile = move->tofile; 11.82 return VALID_MOVE_SYNTAX; 11.83 } else { 11.84 @@ -128,10 +128,10 @@ 11.85 Move chkrowmove = *move, chkfilemove = *move; 11.86 11.87 chkrowmove.fromrow = move->torow; 11.88 - int chkrow = rook_getloc_fixedrow(board, &chkrowmove); 11.89 + int chkrow = rook_getloc_fixedrow(gamestate, &chkrowmove); 11.90 11.91 chkfilemove.fromfile = move->tofile; 11.92 - int chkfile = rook_getloc_fixedfile(board, &chkfilemove); 11.93 + int chkfile = rook_getloc_fixedfile(gamestate, &chkfilemove); 11.94 11.95 if ((chkrow == VALID_MOVE_SYNTAX && chkfile == VALID_MOVE_SYNTAX) || 11.96 chkrow == AMBIGUOUS_MOVE || chkfile == AMBIGUOUS_MOVE) {
12.1 --- a/src/chess/rook.h Mon Mar 31 14:08:00 2014 +0200 12.2 +++ b/src/chess/rook.h Mon Mar 31 15:03:25 2014 +0200 12.3 @@ -37,8 +37,8 @@ 12.4 #endif 12.5 12.6 _Bool rook_chkrules(Move *move); 12.7 -_Bool rook_isblocked(Board board, Move *move); 12.8 -int rook_getlocation(Board board, Move *move); 12.9 +_Bool rook_isblocked(GameState *gamestate, Move *move); 12.10 +int rook_getlocation(GameState *gamestate, Move *move); 12.11 12.12 #ifdef __cplusplus 12.13 }
13.1 --- a/src/chess/rules.c Mon Mar 31 14:08:00 2014 +0200 13.2 +++ b/src/chess/rules.c Mon Mar 31 15:03:25 2014 +0200 13.3 @@ -30,6 +30,30 @@ 13.4 #include "rules.h" 13.5 #include "chess.h" 13.6 #include <string.h> 13.7 +#include <stdlib.h> 13.8 + 13.9 +void gamestate_cleanup(GameState *gamestate) { 13.10 + MoveList *elem; 13.11 + elem = gamestate->movelist; 13.12 + while (elem) { 13.13 + MoveList *cur = elem; 13.14 + elem = elem->next; 13.15 + free(cur); 13.16 + }; 13.17 +} 13.18 + 13.19 +static void addmove(GameState* gamestate, Move *move) { 13.20 + MoveList *elem = malloc(sizeof(MoveList)); 13.21 + elem->next = NULL; 13.22 + elem->move = *move; 13.23 + 13.24 + if (gamestate->lastmove) { 13.25 + gamestate->lastmove->next = elem; 13.26 + gamestate->lastmove = elem; 13.27 + } else { 13.28 + gamestate->movelist = gamestate->lastmove = elem; 13.29 + } 13.30 +} 13.31 13.32 char getpiecechr(uint8_t piece) { 13.33 switch (piece & PIECE_MASK) { 13.34 @@ -53,41 +77,34 @@ 13.35 } 13.36 } 13.37 13.38 -/** 13.39 - * Guesses the location of a piece for short algebraic notation. 13.40 - * 13.41 - * @param board the current state of the board 13.42 - * @param move the move date to operate on 13.43 - * @return status code (see rules/rules.h for the codes) 13.44 - */ 13.45 -static int getlocation(Board board, Move *move) { 13.46 +static int getlocation(GameState *gamestate, Move *move) { 13.47 uint8_t piece = move->piece & PIECE_MASK; 13.48 switch (piece) { 13.49 - case PAWN: return pawn_getlocation(board, move); 13.50 - case ROOK: return rook_getlocation(board, move); 13.51 - case KNIGHT: return knight_getlocation(board, move); 13.52 - case BISHOP: return bishop_getlocation(board, move); 13.53 - case QUEEN: return queen_getlocation(board, move); 13.54 - case KING: return king_getlocation(board, move); 13.55 + case PAWN: return pawn_getlocation(gamestate, move); 13.56 + case ROOK: return rook_getlocation(gamestate, move); 13.57 + case KNIGHT: return knight_getlocation(gamestate, move); 13.58 + case BISHOP: return bishop_getlocation(gamestate, move); 13.59 + case QUEEN: return queen_getlocation(gamestate, move); 13.60 + case KING: return king_getlocation(gamestate, move); 13.61 default: return INVALID_MOVE_SYNTAX; 13.62 } 13.63 } 13.64 13.65 13.66 -void apply_move(Board board, Move *move) { 13.67 +void apply_move(GameState *gamestate, Move *move) { 13.68 uint8_t piece = move->piece & PIECE_MASK; 13.69 uint8_t color = move->piece & COLOR_MASK; 13.70 13.71 /* en passant capture */ 13.72 if (move->capture && piece == PAWN && 13.73 - mdst(board, move) == 0) { 13.74 - board[move->fromrow][move->tofile] = 0; 13.75 + mdst(gamestate->board, move) == 0) { 13.76 + gamestate->board[move->fromrow][move->tofile] = 0; 13.77 } 13.78 13.79 /* remove old en passant threats */ 13.80 for (uint8_t file = 0 ; file < 8 ; file++) { 13.81 - board[3][file] &= ~ENPASSANT_THREAT; 13.82 - board[4][file] &= ~ENPASSANT_THREAT; 13.83 + gamestate->board[3][file] &= ~ENPASSANT_THREAT; 13.84 + gamestate->board[4][file] &= ~ENPASSANT_THREAT; 13.85 } 13.86 13.87 /* add new en passant threat */ 13.88 @@ -98,11 +115,11 @@ 13.89 } 13.90 13.91 /* move (and maybe capture or promote) */ 13.92 - msrc(board, move) = 0; 13.93 + msrc(gamestate->board, move) = 0; 13.94 if (move->promotion) { 13.95 - mdst(board, move) = move->promotion; 13.96 + mdst(gamestate->board, move) = move->promotion; 13.97 } else { 13.98 - mdst(board, move) = move->piece; 13.99 + mdst(gamestate->board, move) = move->piece; 13.100 } 13.101 13.102 /* castling */ 13.103 @@ -110,16 +127,18 @@ 13.104 move->fromfile == fileidx('e')) { 13.105 13.106 if (move->tofile == fileidx('g')) { 13.107 - board[move->torow][fileidx('h')] = 0; 13.108 - board[move->torow][fileidx('f')] = color|ROOK; 13.109 + gamestate->board[move->torow][fileidx('h')] = 0; 13.110 + gamestate->board[move->torow][fileidx('f')] = color|ROOK; 13.111 } else if (move->tofile == fileidx('c')) { 13.112 - board[move->torow][fileidx('a')] = 0; 13.113 - board[move->torow][fileidx('d')] = color|ROOK; 13.114 + gamestate->board[move->torow][fileidx('a')] = 0; 13.115 + gamestate->board[move->torow][fileidx('d')] = color|ROOK; 13.116 } 13.117 } 13.118 + 13.119 + addmove(gamestate, move); 13.120 } 13.121 13.122 -_Bool validate_move(Board board, Move *move) { 13.123 +_Bool validate_move(GameState *gamestate, Move *move) { 13.124 _Bool result; 13.125 13.126 /* validate indices (don't trust opponent) */ 13.127 @@ -133,38 +152,39 @@ 13.128 } 13.129 13.130 /* does piece exist */ 13.131 - result = msrc(board, move) == move->piece; 13.132 + result = msrc(gamestate->board, move) == move->piece; 13.133 13.134 /* can't capture own pieces */ 13.135 - if ((mdst(board, move) & COLOR_MASK) == (move->piece & COLOR_MASK)) { 13.136 + if ((mdst(gamestate->board, move) & COLOR_MASK) 13.137 + == (move->piece & COLOR_MASK)) { 13.138 return 0; 13.139 } 13.140 13.141 /* validate individual rules */ 13.142 switch (move->piece & PIECE_MASK) { 13.143 case PAWN: 13.144 - result = result && pawn_chkrules(board, move); 13.145 - result = result && !pawn_isblocked(board, move); 13.146 + result = result && pawn_chkrules(gamestate, move); 13.147 + result = result && !pawn_isblocked(gamestate, move); 13.148 break; 13.149 case ROOK: 13.150 result = result && rook_chkrules(move); 13.151 - result = result && !rook_isblocked(board, move); 13.152 + result = result && !rook_isblocked(gamestate, move); 13.153 break; 13.154 case KNIGHT: 13.155 result = result && knight_chkrules(move); 13.156 - result = result && !knight_isblocked(board, move); 13.157 + result = result && !knight_isblocked(gamestate, move); 13.158 break; 13.159 case BISHOP: 13.160 result = result && bishop_chkrules(move); 13.161 - result = result && !bishop_isblocked(board, move); 13.162 + result = result && !bishop_isblocked(gamestate, move); 13.163 break; 13.164 case QUEEN: 13.165 result = result && queen_chkrules(move); 13.166 - result = result && !queen_isblocked(board, move); 13.167 + result = result && !queen_isblocked(gamestate, move); 13.168 break; 13.169 case KING: 13.170 - result = result && king_chkrules(board, move); 13.171 - result = result && !king_isblocked(board, move); 13.172 + result = result && king_chkrules(gamestate, move); 13.173 + result = result && !king_isblocked(gamestate, move); 13.174 break; 13.175 default: 13.176 result = 0; 13.177 @@ -179,7 +199,7 @@ 13.178 return result; 13.179 } 13.180 13.181 -int eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { 13.182 +int eval_move(GameState *gamestate, char *mstr, Move *move) { 13.183 memset(move, 0, sizeof(Move)); 13.184 move->fromfile = POS_UNSPECIFIED; 13.185 move->fromrow = POS_UNSPECIFIED; 13.186 @@ -201,7 +221,7 @@ 13.187 if (!move->promotion) { 13.188 return INVALID_MOVE_SYNTAX; 13.189 } else { 13.190 - move->promotion |= mycolor; 13.191 + move->promotion |= gamestate->mycolor; 13.192 len -= 2; 13.193 mstr[len] = 0; 13.194 } 13.195 @@ -218,7 +238,7 @@ 13.196 move->piece = KING; 13.197 move->fromfile = fileidx('e'); 13.198 move->tofile = fileidx('g'); 13.199 - move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 13.200 + move->fromrow = move->torow = gamestate->mycolor == WHITE ? 0 : 7; 13.201 } else { 13.202 /* move (e.g. "Nf3") */ 13.203 move->piece = getpiece(mstr[0]); 13.204 @@ -254,7 +274,7 @@ 13.205 move->piece = KING; 13.206 move->fromfile = fileidx('e'); 13.207 move->tofile = fileidx('c'); 13.208 - move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 13.209 + move->fromrow = move->torow = gamestate->mycolor == WHITE ? 0 : 7; 13.210 } else { 13.211 move->piece = getpiece(mstr[0]); 13.212 if (mstr[2] == 'x') { 13.213 @@ -290,15 +310,16 @@ 13.214 13.215 13.216 if (move->piece) { 13.217 - if (move->piece == PAWN && move->torow == (mycolor==WHITE?7:0) 13.218 + if (move->piece == PAWN 13.219 + && move->torow == (gamestate->mycolor==WHITE?7:0) 13.220 && !move->promotion) { 13.221 return NEED_PROMOTION; 13.222 } 13.223 13.224 - move->piece |= mycolor; 13.225 + move->piece |= gamestate->mycolor; 13.226 if (move->fromfile == POS_UNSPECIFIED 13.227 || move->fromrow == POS_UNSPECIFIED) { 13.228 - return getlocation(board, move); 13.229 + return getlocation(gamestate, move); 13.230 } else { 13.231 return chkidx(move) ? VALID_MOVE_SYNTAX : INVALID_POSITION; 13.232 }
14.1 --- a/src/chess/rules.h Mon Mar 31 14:08:00 2014 +0200 14.2 +++ b/src/chess/rules.h Mon Mar 31 15:03:25 2014 +0200 14.3 @@ -68,6 +68,7 @@ 14.4 14.5 typedef uint8_t Board[8][8]; 14.6 14.7 + 14.8 typedef struct { 14.9 uint8_t piece; 14.10 uint8_t fromfile; 14.11 @@ -80,6 +81,20 @@ 14.12 _Bool capture; 14.13 } Move; 14.14 14.15 +typedef struct MoveList MoveList; 14.16 + 14.17 +struct MoveList { 14.18 + Move move; 14.19 + MoveList* next; 14.20 +}; 14.21 + 14.22 +typedef struct { 14.23 + Board board; 14.24 + uint8_t mycolor; 14.25 + MoveList* movelist; 14.26 + MoveList* lastmove; 14.27 +} GameState; 14.28 + 14.29 #define POS_UNSPECIFIED UINT8_MAX 14.30 #define mdst(b,m) b[(m)->torow][(m)->tofile] 14.31 #define msrc(b,m) b[(m)->fromrow][(m)->fromfile] 14.32 @@ -102,6 +117,8 @@ 14.33 #define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED) 14.34 #define rowidx_s(c) (isrow(c)?rowidx(c):POS_UNSPECIFIED) 14.35 14.36 +void gamestate_cleanup(GameState *gamestate); 14.37 + 14.38 /** 14.39 * Maps a character to a piece. 14.40 * 14.41 @@ -126,29 +143,28 @@ 14.42 * Evaluates a move syntactically and stores the move data in the specified 14.43 * object. 14.44 * 14.45 - * @param board the current state of the board 14.46 - * @param mycolor the color of the current player 14.47 + * @param gamestate the current game state 14.48 * @param mstr the input string to parse 14.49 * @param move a pointer to object where the move data shall be stored 14.50 * @return status code (see rules/rules.h for the list of codes) 14.51 */ 14.52 -int eval_move(Board board, uint8_t mycolor, char *mstr, Move *move); 14.53 +int eval_move(GameState *gamestate, char *mstr, Move *move); 14.54 14.55 /** 14.56 * Validates move by applying chess rules. 14.57 - * @param board the current board state 14.58 + * @param gamestate the current game state 14.59 * @param move the move to validate 14.60 * @return TRUE, if the move complies to chess rules, FALSE otherwise 14.61 */ 14.62 -_Bool validate_move(Board board, Move *move); 14.63 +_Bool validate_move(GameState *gamestate, Move *move); 14.64 14.65 /** 14.66 * Applies a move and deletes captured pieces. 14.67 * 14.68 - * @param board the current board state 14.69 + * @param gamestate the current game state 14.70 * @param move the move to apply 14.71 */ 14.72 -void apply_move(Board board, Move *move); 14.73 +void apply_move(GameState *gamestate, Move *move); 14.74 14.75 #endif /* RULES_H */ 14.76
15.1 --- a/src/game.c Mon Mar 31 14:08:00 2014 +0200 15.2 +++ b/src/game.c Mon Mar 31 15:03:25 2014 +0200 15.3 @@ -35,12 +35,12 @@ 15.4 15.5 static const uint8_t boardx = 10, boardy = 10; 15.6 15.7 -static void draw_board(Board board, MoveListRoot *movelist, uint8_t mycolor) { 15.8 +static void draw_board(GameState *gamestate) { 15.9 15.10 for (uint8_t y = 0 ; y < 8 ; y++) { 15.11 for (uint8_t x = 0 ; x < 8 ; x++) { 15.12 - uint8_t col = board[y][x] & COLOR_MASK; 15.13 - uint8_t piece = board[y][x] & PIECE_MASK; 15.14 + uint8_t col = gamestate->board[y][x] & COLOR_MASK; 15.15 + uint8_t piece = gamestate->board[y][x] & PIECE_MASK; 15.16 char piecec; 15.17 if (piece) { 15.18 piecec = piece == PAWN ? 'P' : getpiecechr(piece); 15.19 @@ -51,8 +51,8 @@ 15.20 attrset((col == WHITE ? A_BOLD : A_DIM) | 15.21 COLOR_PAIR((y&1)==(x&1) ? COL_WB : COL_BW)); 15.22 15.23 - int cy = mycolor == WHITE ? boardy-y : boardy-7+y; 15.24 - int cx = mycolor == WHITE ? boardx+x*3 : boardx+21-x*3; 15.25 + int cy = gamestate->mycolor == WHITE ? boardy-y : boardy-7+y; 15.26 + int cx = gamestate->mycolor == WHITE ? boardx+x*3 : boardx+21-x*3; 15.27 mvaddch(cy, cx, ' '); 15.28 mvaddch(cy, cx+1, piecec); 15.29 mvaddch(cy, cx+2, ' '); 15.30 @@ -61,8 +61,8 @@ 15.31 15.32 attrset(A_NORMAL); 15.33 for (uint8_t i = 0 ; i < 8 ; i++) { 15.34 - int x = mycolor == WHITE ? boardx+i*3+1 : boardx+22-i*3; 15.35 - int y = mycolor == WHITE ? boardy-i : boardy-7+i; 15.36 + int x = gamestate->mycolor == WHITE ? boardx+i*3+1 : boardx+22-i*3; 15.37 + int y = gamestate->mycolor == WHITE ? boardy-i : boardy-7+i; 15.38 mvaddch(boardy+1, x, 'a'+i); 15.39 mvaddch(y, boardx-2, '1'+i); 15.40 } 15.41 @@ -72,14 +72,14 @@ 15.42 uint8_t logy = 0; 15.43 const uint8_t logx = boardx + 30; 15.44 int logi = 1; 15.45 - MoveList *logelem = movelist->first; 15.46 + MoveList *logelem = gamestate->movelist; 15.47 15.48 while (logelem) { 15.49 logi++; 15.50 if (logi % 2 == 0) { 15.51 if ((logi - 2) % 4 == 0) { 15.52 logy++; 15.53 - wmove(tchess_window, logy, logx); 15.54 + move(logy, logx); 15.55 } 15.56 printw("%d. ", logi / 2); 15.57 } 15.58 @@ -108,15 +108,14 @@ 15.59 } 15.60 15.61 15.62 -static int sendmove(Board board, MoveListRoot *movelist, 15.63 - uint8_t mycolor, int opponent) { 15.64 +static int sendmove(GameState *gamestate, int opponent) { 15.65 15.66 const size_t buflen = 8; 15.67 char movestr[buflen]; 15.68 _Bool remisrejected = FALSE; 15.69 uint8_t code; 15.70 15.71 - int inputy = getmaxy(tchess_window) - 6; 15.72 + int inputy = getmaxy(stdscr) - 6; 15.73 while (1) { 15.74 move(inputy, 0); 15.75 if (remisrejected) { 15.76 @@ -156,7 +155,7 @@ 15.77 } 15.78 } else { 15.79 Move move; 15.80 - int eval_result = eval_move(board, mycolor, movestr, &move); 15.81 + int eval_result = eval_move(gamestate, movestr, &move); 15.82 switch (eval_result) { 15.83 case VALID_MOVE_SYNTAX: 15.84 net_send_data(opponent, NETCODE_MOVE, &move, sizeof(Move)); 15.85 @@ -166,8 +165,7 @@ 15.86 if (code == NETCODE_DECLINE) { 15.87 printw("Invalid move."); 15.88 } else { 15.89 - apply_move(board, &move); 15.90 - addmove(movelist, &move); 15.91 + apply_move(gamestate, &move); 15.92 if (move.checkmate) { 15.93 printw("Checkmate!"); 15.94 clrtoeol(); 15.95 @@ -194,9 +192,9 @@ 15.96 } 15.97 } 15.98 15.99 -static int recvmove(Board board, MoveListRoot *movelist, int opponent) { 15.100 +static int recvmove(GameState *gamestate, int opponent) { 15.101 15.102 - int inputy = getmaxy(tchess_window) - 6; 15.103 + int inputy = getmaxy(stdscr) - 6; 15.104 while (1) { 15.105 move(inputy, 0); 15.106 printw("Awaiting opponent move..."); 15.107 @@ -225,9 +223,8 @@ 15.108 break; 15.109 case NETCODE_MOVE: 15.110 net_recieve_data(opponent, &move, sizeof(Move)); 15.111 - if (validate_move(board, &move)) { 15.112 - apply_move(board, &move); 15.113 - addmove(movelist, &move); 15.114 + if (validate_move(gamestate, &move)) { 15.115 + apply_move(gamestate, &move); 15.116 if (move.check) { 15.117 net_send_code(opponent, NETCODE_CHECK); 15.118 } else if (move.checkmate) { 15.119 @@ -243,40 +240,12 @@ 15.120 } 15.121 } 15.122 15.123 -void freemovelist(MoveListRoot* list) { 15.124 - MoveList *elem; 15.125 - elem = list->first; 15.126 - while (elem) { 15.127 - MoveList *cur = elem; 15.128 - elem = elem->next; 15.129 - free(cur); 15.130 - }; 15.131 - free(list); 15.132 -} 15.133 - 15.134 -void addmove(MoveListRoot* list, Move *move) { 15.135 - MoveList *elem = malloc(sizeof(MoveList)); 15.136 - elem->next = NULL; 15.137 - elem->move = *move; 15.138 - 15.139 - if (list->last) { 15.140 - list->last->next = elem; 15.141 - list->last = elem; 15.142 - } else { 15.143 - list->first = list->last = elem; 15.144 - } 15.145 -} 15.146 - 15.147 void game_start(Settings *settings, int opponent) { 15.148 _Bool myturn = is_server(settings) == 15.149 (settings->gameinfo.servercolor == WHITE); 15.150 - uint8_t mycolor = myturn ? WHITE:BLACK; 15.151 15.152 - _Bool running; 15.153 - 15.154 - MoveListRoot* movelist = calloc(1, sizeof(MoveListRoot)); 15.155 - 15.156 - Board board = { 15.157 + GameState gamestate; 15.158 + Board initboard = { 15.159 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK}, 15.160 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN}, 15.161 {0, 0, 0, 0, 0, 0, 0, 0}, 15.162 @@ -286,22 +255,26 @@ 15.163 {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN}, 15.164 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK} 15.165 }; 15.166 + memcpy(gamestate.board, initboard, sizeof(Board)); 15.167 + gamestate.mycolor = myturn ? WHITE:BLACK; 15.168 + gamestate.movelist = gamestate.lastmove = NULL; 15.169 15.170 + _Bool running; 15.171 do { 15.172 clear(); 15.173 - draw_board(board, movelist, mycolor); 15.174 + draw_board(&gamestate); 15.175 if (myturn) { 15.176 - running = !sendmove(board, movelist, mycolor, opponent); 15.177 + running = !sendmove(&gamestate, opponent); 15.178 } else { 15.179 - running = !recvmove(board, movelist, opponent); 15.180 + running = !recvmove(&gamestate, opponent); 15.181 flushinp(); // flush any input the user hacked in while waiting 15.182 } 15.183 myturn ^= TRUE; 15.184 } while (running); 15.185 15.186 - freemovelist(movelist); 15.187 + gamestate_cleanup(&gamestate); 15.188 15.189 - mvaddstr(getmaxy(tchess_window)-1, 0, 15.190 + mvaddstr(getmaxy(stdscr)-1, 0, 15.191 "Game has ended. Press any key to leave..."); 15.192 getch(); 15.193 }
16.1 --- a/src/game.h Mon Mar 31 14:08:00 2014 +0200 16.2 +++ b/src/game.h Mon Mar 31 15:03:25 2014 +0200 16.3 @@ -37,25 +37,8 @@ 16.4 extern "C" { 16.5 #endif 16.6 16.7 -typedef struct MoveList MoveList; 16.8 -typedef struct MoveListRoot MoveListRoot; 16.9 - 16.10 -struct MoveListRoot { 16.11 - MoveList* first; 16.12 - MoveList* last; 16.13 -}; 16.14 - 16.15 -struct MoveList { 16.16 - Move move; 16.17 - MoveList* next; 16.18 -}; 16.19 - 16.20 - 16.21 void game_start(Settings *settings, int opponent); 16.22 16.23 -void freemovelist(MoveListRoot* list); 16.24 -void addmove(MoveListRoot *movelist, Move *move); 16.25 - 16.26 #ifdef __cplusplus 16.27 } 16.28 #endif
17.1 --- a/src/main.c Mon Mar 31 14:08:00 2014 +0200 17.2 +++ b/src/main.c Mon Mar 31 15:03:25 2014 +0200 17.3 @@ -160,7 +160,7 @@ 17.4 ); 17.5 return EXIT_SUCCESS; 17.6 } 17.7 - tchess_window = initscr(); 17.8 + initscr(); 17.9 cbreak(); 17.10 if (has_colors()) { 17.11 start_color();
18.1 --- a/src/terminal-chess.h Mon Mar 31 14:08:00 2014 +0200 18.2 +++ b/src/terminal-chess.h Mon Mar 31 15:03:25 2014 +0200 18.3 @@ -39,8 +39,6 @@ 18.4 extern "C" { 18.5 #endif 18.6 18.7 -WINDOW* tchess_window; 18.8 - 18.9 #define TIME_MAX UINT16_MAX 18.10 18.11 typedef struct {