160 * @param board the current state of the board |
177 * @param board the current state of the board |
161 * @param move the move date to operate on |
178 * @param move the move date to operate on |
162 * @return TRUE if the location could be retrieved, FALSE if the location is |
179 * @return TRUE if the location could be retrieved, FALSE if the location is |
163 * ambiguous |
180 * ambiguous |
164 */ |
181 */ |
165 static _Bool getlocation(Board board, Move *move) { |
182 static _Bool getlocation(Board board, Move *move) { |
166 uint8_t piece = move->piece & PIECE_MASK; |
183 uint8_t piece = move->piece & PIECE_MASK; |
167 switch (piece) { |
184 switch (piece) { |
168 case PAWN: return pawn_getlocation(board, move); |
185 case PAWN: return pawn_getlocation(board, move); |
169 case ROOK: return rook_getlocation(board, move); |
186 case ROOK: return rook_getlocation(board, move); |
170 case KNIGHT: return knight_getlocation(board, move); |
187 case KNIGHT: return knight_getlocation(board, move); |
201 move->checkmate = TRUE; |
218 move->checkmate = TRUE; |
202 } |
219 } |
203 |
220 |
204 if (len == 2) { |
221 if (len == 2) { |
205 /* pawn move (e.g. "e4") */ |
222 /* pawn move (e.g. "e4") */ |
206 if (isfile(mstr[0]) && isrow(mstr[1])) { |
223 move->piece = PAWN; |
207 move->piece = PAWN; |
224 move->tofile = fileidx(mstr[0]); |
208 move->tofile = fileidx(mstr[0]); |
225 move->torow = rowidx(mstr[1]); |
209 move->torow = rowidx(mstr[1]); |
|
210 } |
|
211 } else if (len == 3) { |
226 } else if (len == 3) { |
212 if (strcmp(mstr, "O-O") == 0) { |
227 if (strcmp(mstr, "O-O") == 0) { |
213 /* king side castling */ |
228 /* king side castling */ |
214 move->piece = KING; |
229 move->piece = KING; |
215 move->fromfile = fileidx('e'); |
230 move->fromfile = fileidx('e'); |
216 move->tofile = fileidx('g'); |
231 move->tofile = fileidx('g'); |
217 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; |
232 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; |
218 } else { |
233 } else { |
219 /* unambiguous move (e.g. "Nf3") */ |
234 /* move (e.g. "Nf3") */ |
220 move->piece = getpiece(mstr[0]); |
235 move->piece = getpiece(mstr[0]); |
221 move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED; |
236 move->tofile = fileidx(mstr[1]); |
222 move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED; |
237 move->torow = rowidx(mstr[2]); |
223 } |
238 } |
224 |
239 |
225 } else if (len == 4) { |
240 } else if (len == 4) { |
226 /* ambiguous move (e.g. "Ndf3") */ |
241 move->piece = getpiece(mstr[0]); |
227 |
242 if (mstr[1] == 'x') { |
228 /* unambiguous capture (e.g. "Nxf3", "dxe5") */ |
243 /* capture (e.g. "Nxf3", "dxe5") */ |
229 |
244 move->capture = TRUE; |
|
245 if (!move->piece) { |
|
246 move->piece = PAWN; |
|
247 move->fromfile = fileidx(mstr[0]); |
|
248 } |
|
249 } else { |
|
250 /* move (e.g. "Ndf3") */ |
|
251 move->fromfile = fileidx(mstr[1]); |
|
252 } |
|
253 move->tofile = fileidx(mstr[2]); |
|
254 move->torow = rowidx(mstr[3]); |
230 } else if (len == 5) { |
255 } else if (len == 5) { |
231 if (strcmp(mstr, "O-O-O") == 0) { |
256 if (strcmp(mstr, "O-O-O") == 0) { |
232 /* queen side castling "O-O-O" */ |
257 /* queen side castling "O-O-O" */ |
233 move->piece = KING; |
258 move->piece = KING; |
234 move->fromfile = fileidx('e'); |
259 move->fromfile = fileidx('e'); |
235 move->tofile = fileidx('c'); |
260 move->tofile = fileidx('c'); |
236 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; |
261 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; |
237 } else { |
262 } else { |
238 /* ambiguous capture (e.g. "Ndxf3") */ |
263 move->piece = getpiece(mstr[0]); |
239 |
264 if (mstr[2] == 'x') { |
240 /* long notation move (e.g. "Nc5a4") */ |
265 move->capture = TRUE; |
241 |
266 if (move->piece) { |
242 /* long notation capture (e.g. "e5xf6") */ |
267 /* capture (e.g. "Ndxf3") */ |
|
268 move->fromfile = fileidx(mstr[1]); |
|
269 } else { |
|
270 /* long notation capture (e.g. "e5xf6") */ |
|
271 move->piece = PAWN; |
|
272 move->fromfile = fileidx(mstr[0]); |
|
273 move->fromrow = rowidx(mstr[1]); |
|
274 } |
|
275 } else { |
|
276 /* long notation move (e.g. "Nc5a4") */ |
|
277 move->fromfile = fileidx(mstr[1]); |
|
278 move->fromrow = rowidx(mstr[2]); |
|
279 } |
|
280 move->tofile = fileidx(mstr[3]); |
|
281 move->torow = rowidx(mstr[4]); |
243 } |
282 } |
244 } else if (len == 6) { |
283 } else if (len == 6) { |
245 /* long notation capture (e.g. "Nc5xf3") */ |
284 /* long notation capture (e.g. "Nc5xf3") */ |
246 } |
285 if (mstr[3] == 'x') { |
247 |
286 move->capture = TRUE; |
|
287 move->piece = getpiece(mstr[0]); |
|
288 move->fromfile = fileidx(mstr[1]); |
|
289 move->fromrow = rowidx(mstr[2]); |
|
290 move->tofile = fileidx(mstr[4]); |
|
291 move->torow = rowidx(mstr[5]); |
|
292 } |
|
293 } |
|
294 |
|
295 |
248 if (move->piece) { |
296 if (move->piece) { |
249 move->piece |= mycolor; |
297 move->piece |= mycolor; |
250 } |
298 if (move->fromfile == POS_UNSPECIFIED |
251 |
299 || move->fromrow == POS_UNSPECIFIED) { |
252 if (!getlocation(board, move)) { |
300 return getlocation(board, move) && chkidx(move); |
253 // TODO: return status code to indicate the error type |
301 } else { |
254 move->piece = 0; |
302 return chkidx(move); |
255 } |
303 } |
256 |
304 } else { |
257 return move->piece != 0; |
305 return FALSE; |
|
306 } |
|
307 // TODO: return status code to indicate the error type |
258 } |
308 } |
259 |
309 |
260 static int sendmove(Board board, uint8_t mycolor, int opponent) { |
310 static int sendmove(Board board, uint8_t mycolor, int opponent) { |
261 const size_t buflen = 8; |
311 const size_t buflen = 8; |
262 char movestr[buflen]; |
312 char movestr[buflen]; |