src/chess/king.c

changeset 194
619f07c95894
parent 193
d1420f5c5704
child 195
27d02ccb0cef
equal deleted inserted replaced
193:d1420f5c5704 194:619f07c95894
29 29
30 #include "rules.h" 30 #include "rules.h"
31 #include "king.h" 31 #include "king.h"
32 32
33 static bool king_castling_chkmoved( 33 static bool king_castling_chkmoved(
34 const GameState *gamestate, Row row, File file) { 34 const GameState *gamestate, Rank rank, File file) {
35 35
36 for (unsigned i = 0; i < gamestate->movecount; i++) { 36 for (unsigned i = 0; i < gamestate->movecount; i++) {
37 if (gamestate->moves[i].fromfile == file 37 if (gamestate->moves[i].fromfile == file
38 && gamestate->moves[i].fromrow == row) { 38 && gamestate->moves[i].fromrank == rank) {
39 return true; 39 return true;
40 } 40 }
41 } 41 }
42 42
43 return false; 43 return false;
44 } 44 }
45 45
46 bool king_chkrules(const GameState *gamestate, const Move* move) { 46 bool king_chkrules(const GameState *gamestate, const Move* move) {
47 if (abs(move->torow - move->fromrow) <= 1 && 47 if (abs(move->torank - move->fromrank) <= 1 &&
48 abs(move->tofile - move->fromfile) <= 1) { 48 abs(move->tofile - move->fromfile) <= 1) {
49 return true; 49 return true;
50 } else { 50 } else {
51 /* castling */ 51 /* castling */
52 if (move->fromrow == move->torow && 52 if (move->fromrank == move->torank &&
53 move->fromrow == (piece_color(move->piece) == WHITE ? 0 : 7) && 53 move->fromrank == (piece_color(move->piece) == WHITE ? 0 : 7) &&
54 move->fromfile == fileidx('e') && 54 move->fromfile == fileidx('e') &&
55 (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) { 55 (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) {
56 56
57 return !king_castling_chkmoved(gamestate, 57 return !king_castling_chkmoved(gamestate,
58 move->fromrow, move->fromfile) && 58 move->fromrank, move->fromfile) &&
59 !king_castling_chkmoved(gamestate, move->fromrow, 59 !king_castling_chkmoved(gamestate, move->fromrank,
60 move->tofile == fileidx('c') ? 0 : 7); 60 move->tofile == fileidx('c') ? 0 : 7);
61 } else { 61 } else {
62 return false; 62 return false;
63 } 63 }
64 } 64 }
65 } 65 }
66 66
67 bool king_isblocked(const GameState *gamestate, const Move *move) { 67 bool king_isblocked(const GameState *gamestate, const Move *move) {
68 68
69 uint8_t op_color = opponent_color(piece_color(move->piece)); 69 Color op_color = opponent_color(piece_color(move->piece));
70 70
71 /* 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 */
72 bool blocked = false; 72 bool blocked = false;
73 73
74 /* just test, if castling move is blocked */ 74 /* just test, if castling move is blocked */
75 if (abs(move->tofile - move->fromfile) == 2) { 75 if (abs(move->tofile - move->fromfile) == 2) {
76 if (move->tofile == fileidx('c')) { 76 if (move->tofile == fileidx('c')) {
77 blocked |= gamestate->board[move->torow][fileidx('b')]; 77 blocked |= gamestate->board[move->torank][fileidx('b')];
78 } 78 }
79 uint8_t midfile = (move->tofile+move->fromfile)/2; 79 File midfile = (move->tofile+move->fromfile)/2;
80 bool incheck = false; 80 bool incheck = false;
81 if (gamestate->movecount > 0) { 81 if (gamestate->movecount > 0) {
82 incheck = is_check_position(gamestate); 82 incheck = is_check_position(gamestate);
83 } 83 }
84 blocked |= incheck || gamestate->board[move->torow][midfile] || 84 blocked |= incheck || gamestate->board[move->torank][midfile] ||
85 is_covered(gamestate, move->torow, midfile, op_color); 85 is_covered(gamestate, move->torank, midfile, op_color);
86 } 86 }
87 87
88 return blocked; 88 return blocked;
89 } 89 }
90 90
91 size_t king_moves(const GameState *gamestate, 91 size_t king_moves(const GameState *gamestate,
92 Color c, Row r, File f, Move *moves) { 92 Color c, Rank r, File f, Move *moves) {
93 93
94 size_t count = 0; 94 size_t count = 0;
95 Piece king = mkpiece(KING, c); 95 Piece king = mkpiece(KING, c);
96 96
97 for (int dr = -1 ; dr <= 1 ; dr++) { 97 for (int dr = -1 ; dr <= 1 ; dr++) {
98 for (int df = -1 ; df <= 1 ; df++) { 98 for (int df = -1 ; df <= 1 ; df++) {
99 if (dr == 0 && df == 0) { 99 if (dr == 0 && df == 0) {
100 continue; 100 continue;
101 } 101 }
102 102
103 Row torow = r + dr; 103 Rank torank = r + dr;
104 File tofile = f + df; 104 File tofile = f + df;
105 105
106 if (!isidx(torow) || !isidx(tofile)) { 106 if (!isidx(torank) || !isidx(tofile)) {
107 continue; 107 continue;
108 } 108 }
109 109
110 moves[count] = (Move){0}; 110 moves[count] = (Move){0};
111 moves[count].piece = king; 111 moves[count].piece = king;
112 moves[count].fromrow = r; 112 moves[count].fromrank = r;
113 moves[count].fromfile = f; 113 moves[count].fromfile = f;
114 moves[count].torow = torow; 114 moves[count].torank = torank;
115 moves[count].tofile = tofile; 115 moves[count].tofile = tofile;
116 moves[count].capture = piece_at(gamestate, torow, tofile) != 0; 116 moves[count].capture = piece_at(gamestate, torank, tofile) != 0;
117 count++; 117 count++;
118 } 118 }
119 } 119 }
120 120
121 Row homerow = c == WHITE ? 0 : 7; 121 Rank homerank = c == WHITE ? 0 : 7;
122 if (r == homerow && f == fileidx('e')) { 122 if (r == homerank && f == fileidx('e')) {
123 moves[count] = (Move){0}; 123 moves[count] = (Move){0};
124 moves[count].piece = king; 124 moves[count].piece = king;
125 moves[count].fromrow = r; 125 moves[count].fromrank = r;
126 moves[count].fromfile = f; 126 moves[count].fromfile = f;
127 moves[count].torow = r; 127 moves[count].torank = r;
128 moves[count].tofile = fileidx('c'); 128 moves[count].tofile = fileidx('c');
129 count++; 129 count++;
130 130
131 moves[count] = (Move){0}; 131 moves[count] = (Move){0};
132 moves[count].piece = king; 132 moves[count].piece = king;
133 moves[count].fromrow = r; 133 moves[count].fromrank = r;
134 moves[count].fromfile = f; 134 moves[count].fromfile = f;
135 moves[count].torow = r; 135 moves[count].torank = r;
136 moves[count].tofile = fileidx('g'); 136 moves[count].tofile = fileidx('g');
137 count++; 137 count++;
138 } 138 }
139 139
140 return count; 140 return count;

mercurial