Tue, 01 Apr 2014 12:30:25 +0200
implemented king
src/chess/king.c | file | annotate | diff | comparison | revisions | |
src/chess/rules.c | file | annotate | diff | comparison | revisions | |
src/chess/rules.h | file | annotate | diff | comparison | revisions | |
src/game.c | file | annotate | diff | comparison | revisions | |
src/network.h | file | annotate | diff | comparison | revisions |
1.1 --- a/src/chess/king.c Tue Apr 01 10:28:08 2014 +0200 1.2 +++ b/src/chess/king.c Tue Apr 01 12:30:25 2014 +0200 1.3 @@ -29,18 +29,88 @@ 1.4 1.5 #include "rules.h" 1.6 #include "king.h" 1.7 +#include <stdlib.h> 1.8 1.9 -_Bool king_chkrules(GameState *gamestate, Move* move) { 1.10 - // TODO: implement 1.11 +static _Bool king_castling_chkmoved(GameState *gamestate, 1.12 + uint8_t row, uint8_t file) { 1.13 + 1.14 + MoveList *ml = gamestate->movelist; 1.15 + while (ml) { 1.16 + if (ml->move.fromfile == file && ml->move.fromrow == row) { 1.17 + return 1; 1.18 + } 1.19 + ml = ml->next; 1.20 + } 1.21 + 1.22 return 0; 1.23 } 1.24 1.25 +_Bool king_chkrules(GameState *gamestate, Move* move) { 1.26 + if (abs(move->torow - move->fromrow) <= 1 && 1.27 + abs(move->tofile - move->fromfile) <= 1) { 1.28 + return 1; 1.29 + } else { 1.30 + /* castling */ 1.31 + if (move->fromrow == move->torow && 1.32 + move->fromrow == ((move->piece&COLOR_MASK) == WHITE ? 0 : 7) && 1.33 + move->fromfile == fileidx('e') && 1.34 + (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) { 1.35 + 1.36 + return !king_castling_chkmoved(gamestate, 1.37 + move->fromrow, move->fromfile) && 1.38 + !king_castling_chkmoved(gamestate, move->fromrow, 1.39 + move->tofile == fileidx('c') ? 0 : 7); 1.40 + } else { 1.41 + return 0; 1.42 + } 1.43 + } 1.44 +} 1.45 + 1.46 _Bool king_isblocked(GameState *gamestate, Move *move) { 1.47 - // TODO: implement 1.48 - return 1; 1.49 + 1.50 + uint8_t opponent_color = opponent_color(move->piece&COLOR_MASK); 1.51 + _Bool blocked = is_covered(gamestate, move->torow, move->tofile, 1.52 + opponent_color); 1.53 + 1.54 + if (abs(move->tofile - move->fromfile) == 2) { 1.55 + if (move->tofile == fileidx('c')) { 1.56 + blocked |= gamestate->board[move->torow][fileidx('b')]; 1.57 + } 1.58 + uint8_t midfile = (move->tofile+move->fromfile)/2; 1.59 + blocked |= gamestate->lastmove->move.check || 1.60 + gamestate->board[move->torow][midfile] || 1.61 + is_covered(gamestate, move->torow, midfile, opponent_color); 1.62 + } 1.63 + 1.64 + return blocked; 1.65 } 1.66 1.67 int king_getlocation(GameState *gamestate, Move *move) { 1.68 - // TODO: implement 1.69 - return INVALID_MOVE_SYNTAX; 1.70 + 1.71 + uint8_t file, row; 1.72 + 1.73 + for (int f = -1 ; f <= 1 ; f++) { 1.74 + for (int r = -1 ; r <= 1 ; r++) { 1.75 + if (f == 0 && r == 0) { 1.76 + continue; 1.77 + } 1.78 + file = move->tofile + f; 1.79 + row = move->torow + r; 1.80 + if (isidx(file) && isidx(row)) { 1.81 + if (gamestate->board[row][file] == move->piece) { 1.82 + if ((move->fromfile != POS_UNSPECIFIED 1.83 + && move->fromfile != file) || 1.84 + (move->fromrow != POS_UNSPECIFIED 1.85 + && move->fromrow != row)) { 1.86 + return INVALID_POSITION; 1.87 + } 1.88 + move->fromfile = file; 1.89 + move->fromrow = row; 1.90 + return VALID_MOVE_SYNTAX; 1.91 + } 1.92 + } 1.93 + } 1.94 + } 1.95 + 1.96 + return INVALID_POSITION; 1.97 }
2.1 --- a/src/chess/rules.c Tue Apr 01 10:28:08 2014 +0200 2.2 +++ b/src/chess/rules.c Tue Apr 01 12:30:25 2014 +0200 2.3 @@ -90,6 +90,30 @@ 2.4 } 2.5 } 2.6 2.7 +_Bool is_covered(GameState *gamestate,uint8_t row,uint8_t file,uint8_t color) { 2.8 + Move threats[16]; 2.9 + int threatcount = 0; 2.10 + for (uint8_t r = 0 ; r < 8 ; r++) { 2.11 + for (uint8_t f = 0 ; f < 8 ; f++) { 2.12 + if ((gamestate->board[r][f] & COLOR_MASK) == color) { 2.13 + threats[threatcount].piece = gamestate->board[r][f]; 2.14 + threats[threatcount].fromrow = r; 2.15 + threats[threatcount].fromfile = f; 2.16 + threats[threatcount].torow = row; 2.17 + threats[threatcount].tofile = file; 2.18 + threatcount++; 2.19 + } 2.20 + } 2.21 + } 2.22 + 2.23 + for (int i = 0 ; i < threatcount ; i++) { 2.24 + if (validate_move(gamestate, &(threats[i]))) { 2.25 + return 1; 2.26 + } 2.27 + } 2.28 + 2.29 + return 0; 2.30 +} 2.31 2.32 void apply_move(GameState *gamestate, Move *move) { 2.33 uint8_t piece = move->piece & PIECE_MASK; 2.34 @@ -190,10 +214,15 @@ 2.35 result = 0; 2.36 } 2.37 2.38 + /* cancel processing to avoid recursion overflow with is_covered() */ 2.39 + if (!result) { 2.40 + return 0; 2.41 + } 2.42 + 2.43 /* is piece pinned */ 2.44 // TODO: make it so 2.45 2.46 - /* correct check and checkmate flags */ 2.47 + /* correct check and checkmate flags (move is still valid) */ 2.48 // TODO: make it so 2.49 2.50 return result;
3.1 --- a/src/chess/rules.h Tue Apr 01 10:28:08 2014 +0200 3.2 +++ b/src/chess/rules.h Tue Apr 01 12:30:25 2014 +0200 3.3 @@ -95,6 +95,8 @@ 3.4 MoveList* lastmove; 3.5 } GameState; 3.6 3.7 +#define opponent_color(color) ((color)==WHITE?BLACK:WHITE) 3.8 + 3.9 #define POS_UNSPECIFIED UINT8_MAX 3.10 #define mdst(b,m) b[(m)->torow][(m)->tofile] 3.11 #define msrc(b,m) b[(m)->fromrow][(m)->fromfile] 3.12 @@ -140,6 +142,18 @@ 3.13 char getpiecechr(uint8_t piece); 3.14 3.15 /** 3.16 + * Checks, if a specified field is covered by a piece of a certain color. 3.17 + * 3.18 + * @param gamestate the current game state 3.19 + * @param row row of the field to check 3.20 + * @param file file of the field to check 3.21 + * @param color the color of the piece that should cover the field 3.22 + * @return TRUE, if any piece of the specified color threatens the specified 3.23 + * field (i.e. could capture an opponent piece) 3.24 + */ 3.25 +_Bool is_covered(GameState *gamestate,uint8_t row,uint8_t file,uint8_t color); 3.26 + 3.27 +/** 3.28 * Evaluates a move syntactically and stores the move data in the specified 3.29 * object. 3.30 *
4.1 --- a/src/game.c Tue Apr 01 10:28:08 2014 +0200 4.2 +++ b/src/game.c Tue Apr 01 12:30:25 2014 +0200 4.3 @@ -86,21 +86,26 @@ 4.4 4.5 if (logelem) { 4.6 Move move = logelem->move; 4.7 - char logstr[] = { 4.8 - getpiecechr(move.piece), 4.9 - filechr(move.fromfile), rowchr(move.fromrow), 4.10 - move.capture ? 'x':'\0', 4.11 - filechr(move.tofile), rowchr(move.torow), 4.12 - move.check ? '+' : (move.checkmate ? '#' : 4.13 - (move.promotion ? '=' : '\0')), 4.14 - move.promotion ? getpiecechr(move.promotion) : '\0', 4.15 - ' ' 4.16 - }; 4.17 - for (int stri = 0 ; stri < sizeof(logstr) ; stri++) { 4.18 - if (logstr[stri]) { 4.19 - addch(logstr[stri]); 4.20 + if ((move.piece&PIECE_MASK) == KING && 4.21 + abs(move.tofile-move.fromfile) == 2) { 4.22 + addstr(move.tofile==fileidx('c')?"O-O-O":"O-O"); 4.23 + } else { 4.24 + char logstr[] = { 4.25 + getpiecechr(move.piece), 4.26 + filechr(move.fromfile), rowchr(move.fromrow), 4.27 + move.capture ? 'x':'\0', 4.28 + filechr(move.tofile), rowchr(move.torow), 4.29 + move.check ? '+' : (move.checkmate ? '#' : 4.30 + (move.promotion ? '=' : '\0')), 4.31 + move.promotion ? getpiecechr(move.promotion) : '\0' 4.32 + }; 4.33 + for (int stri = 0 ; stri < sizeof(logstr) ; stri++) { 4.34 + if (logstr[stri]) { 4.35 + addch(logstr[stri]); 4.36 + } 4.37 } 4.38 } 4.39 + addch(' '); 4.40 4.41 logelem = logelem->next; 4.42 }
5.1 --- a/src/network.h Tue Apr 01 10:28:08 2014 +0200 5.2 +++ b/src/network.h Tue Apr 01 12:30:25 2014 +0200 5.3 @@ -45,8 +45,9 @@ 5.4 #define NETCODE_REMIS 0x22 5.5 #define NETCODE_CHECK 0x23 5.6 #define NETCODE_CHECKMATE 0x24 5.7 - 5.8 -#define NETCODE_VERSION 6 5.9 +#define NETCODE_STALEMATE 0x25 5.10 + 5.11 +#define NETCODE_VERSION 7 5.12 5.13 typedef struct { 5.14 int fd; /* -1, if we are the client */