| 27 * |
27 * |
| 28 */ |
28 */ |
| 29 |
29 |
| 30 #include "rules.h" |
30 #include "rules.h" |
| 31 #include "king.h" |
31 #include "king.h" |
| 32 #include <stdlib.h> |
|
| 33 |
32 |
| 34 static bool king_castling_chkmoved(GameState *gamestate, |
33 #include <string.h> |
| 35 uint8_t row, uint8_t file) { |
|
| 36 |
34 |
| |
35 static bool king_castling_chkmoved(GameState *gamestate, Row row, File file) { |
| 37 for (unsigned i = 0; i < gamestate->movecount; i++) { |
36 for (unsigned i = 0; i < gamestate->movecount; i++) { |
| 38 if (gamestate->moves[i].fromfile == file |
37 if (gamestate->moves[i].fromfile == file |
| 39 && gamestate->moves[i].fromrow == row) { |
38 && gamestate->moves[i].fromrow == row) { |
| 40 return true; |
39 return true; |
| 41 } |
40 } |
| 49 abs(move->tofile - move->fromfile) <= 1) { |
48 abs(move->tofile - move->fromfile) <= 1) { |
| 50 return true; |
49 return true; |
| 51 } else { |
50 } else { |
| 52 /* castling */ |
51 /* castling */ |
| 53 if (move->fromrow == move->torow && |
52 if (move->fromrow == move->torow && |
| 54 move->fromrow == ((move->piece&COLOR_MASK) == WHITE ? 0 : 7) && |
53 move->fromrow == (piece_color(move->piece) == WHITE ? 0 : 7) && |
| 55 move->fromfile == fileidx('e') && |
54 move->fromfile == fileidx('e') && |
| 56 (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) { |
55 (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) { |
| 57 |
56 |
| 58 return !king_castling_chkmoved(gamestate, |
57 return !king_castling_chkmoved(gamestate, |
| 59 move->fromrow, move->fromfile) && |
58 move->fromrow, move->fromfile) && |
| 65 } |
64 } |
| 66 } |
65 } |
| 67 |
66 |
| 68 bool king_isblocked(GameState *gamestate, Move *move) { |
67 bool king_isblocked(GameState *gamestate, Move *move) { |
| 69 |
68 |
| 70 uint8_t opponent_color = opponent_color(move->piece&COLOR_MASK); |
69 uint8_t opponent_color = opponent_color(piece_color(move->piece)); |
| 71 |
70 |
| 72 /* being in check does not "block" the king, so don't test it here */ |
71 /* being in check does not "block" the king, so don't test it here */ |
| 73 bool blocked = false; |
72 bool blocked = false; |
| 74 |
73 |
| 75 /* just test, if castling move is blocked */ |
74 /* just test, if castling move is blocked */ |
| 76 if (abs(move->tofile - move->fromfile) == 2) { |
75 if (abs(move->tofile - move->fromfile) == 2) { |
| 77 if (move->tofile == fileidx('c')) { |
76 if (move->tofile == fileidx('c')) { |
| 78 blocked |= gamestate->board[move->torow][fileidx('b')]; |
77 blocked |= gamestate->board[move->torow][fileidx('b')]; |
| 79 } |
78 } |
| 80 uint8_t midfile = (move->tofile+move->fromfile)/2; |
79 uint8_t midfile = (move->tofile+move->fromfile)/2; |
| 81 blocked |= last_move(gamestate).check || |
80 bool incheck = false; |
| 82 gamestate->board[move->torow][midfile] || |
81 if (gamestate->movecount > 0) { |
| |
82 incheck = gamestate->moves[gamestate->movecount-1].check; |
| |
83 } |
| |
84 blocked |= incheck || gamestate->board[move->torow][midfile] || |
| 83 is_covered(gamestate, move->torow, midfile, opponent_color); |
85 is_covered(gamestate, move->torow, midfile, opponent_color); |
| 84 } |
86 } |
| 85 |
87 |
| 86 return blocked; |
88 return blocked; |
| 87 } |
89 } |