325 /* cancel processing to save resources */ |
325 /* cancel processing to save resources */ |
326 if (result != VALID_MOVE_SEMANTICS) { |
326 if (result != VALID_MOVE_SEMANTICS) { |
327 return result; |
327 return result; |
328 } |
328 } |
329 |
329 |
330 /* find kings for check validation */ |
|
331 uint8_t piececolor = (move->piece & COLOR_MASK); |
|
332 |
|
333 uint8_t mykingfile = 0, mykingrow = 0, opkingfile = 0, opkingrow = 0; |
|
334 for (uint8_t row = 0 ; row < 8 ; row++) { |
|
335 for (uint8_t file = 0 ; file < 8 ; file++) { |
|
336 if (gamestate->board[row][file] == |
|
337 (piececolor == WHITE?WKING:BKING)) { |
|
338 mykingfile = file; |
|
339 mykingrow = row; |
|
340 } else if (gamestate->board[row][file] == |
|
341 (piececolor == WHITE?BKING:WKING)) { |
|
342 opkingfile = file; |
|
343 opkingrow = row; |
|
344 } |
|
345 } |
|
346 } |
|
347 |
|
348 /* simulate move for check validation */ |
330 /* simulate move for check validation */ |
349 GameState simulation = gamestate_copy_sim(gamestate); |
331 GameState simulation = gamestate_copy_sim(gamestate); |
350 Move simmove = *move; |
332 Move simmove = *move; |
351 apply_move_impl(&simulation, &simmove, 1); |
333 apply_move_impl(&simulation, &simmove, 1); |
|
334 |
|
335 /* find kings for check validation */ |
|
336 uint8_t piececolor = (move->piece & COLOR_MASK); |
|
337 |
|
338 uint8_t mykingfile = 0, mykingrow = 0, opkingfile = 0, opkingrow = 0; |
|
339 for (uint8_t row = 0 ; row < 8 ; row++) { |
|
340 for (uint8_t file = 0 ; file < 8 ; file++) { |
|
341 if (simulation.board[row][file] == |
|
342 (piececolor == WHITE?WKING:BKING)) { |
|
343 mykingfile = file; |
|
344 mykingrow = row; |
|
345 } else if (simulation.board[row][file] == |
|
346 (piececolor == WHITE?BKING:WKING)) { |
|
347 opkingfile = file; |
|
348 opkingrow = row; |
|
349 } |
|
350 } |
|
351 } |
352 |
352 |
353 /* don't move into or stay in check position */ |
353 /* don't move into or stay in check position */ |
354 if (is_covered(&simulation, mykingrow, mykingfile, |
354 if (is_covered(&simulation, mykingrow, mykingfile, |
355 opponent_color(piececolor))) { |
355 opponent_color(piececolor))) { |
356 |
356 |
493 } |
493 } |
494 |
494 |
495 _Bool is_pinned(GameState *gamestate, Move *move) { |
495 _Bool is_pinned(GameState *gamestate, Move *move) { |
496 uint8_t color = move->piece & COLOR_MASK; |
496 uint8_t color = move->piece & COLOR_MASK; |
497 |
497 |
|
498 GameState simulation = gamestate_copy_sim(gamestate); |
|
499 Move simmove = *move; |
|
500 apply_move(&simulation, &simmove); |
|
501 |
498 uint8_t kingfile = 0, kingrow = 0; |
502 uint8_t kingfile = 0, kingrow = 0; |
499 for (uint8_t row = 0 ; row < 8 ; row++) { |
503 for (uint8_t row = 0 ; row < 8 ; row++) { |
500 for (uint8_t file = 0 ; file < 8 ; file++) { |
504 for (uint8_t file = 0 ; file < 8 ; file++) { |
501 if (gamestate->board[row][file] == (color|KING)) { |
505 if (simulation.board[row][file] == (color|KING)) { |
502 kingfile = file; |
506 kingfile = file; |
503 kingrow = row; |
507 kingrow = row; |
504 } |
508 } |
505 } |
509 } |
506 } |
510 } |
507 |
511 |
508 GameState simulation = gamestate_copy_sim(gamestate); |
|
509 Move simmove = *move; |
|
510 apply_move(&simulation, &simmove); |
|
511 _Bool covered = is_covered(&simulation, |
512 _Bool covered = is_covered(&simulation, |
512 kingrow, kingfile, opponent_color(color)); |
513 kingrow, kingfile, opponent_color(color)); |
513 gamestate_cleanup(&simulation); |
514 gamestate_cleanup(&simulation); |
514 |
515 |
515 return covered; |
516 return covered; |
568 threats, &threatcount)) { |
569 threats, &threatcount)) { |
569 |
570 |
570 int reason = INVALID_POSITION; |
571 int reason = INVALID_POSITION; |
571 |
572 |
572 // find threats for the specified position |
573 // find threats for the specified position |
573 for (uint8_t i = 0 ; i < threatcount ; i++) { |
574 for (uint8_t i = 0 ; i < threatcount ; i++) { |
574 if ((threats[i].piece & (PIECE_MASK | COLOR_MASK)) |
575 if ((threats[i].piece & (PIECE_MASK | COLOR_MASK)) |
575 == move->piece && |
576 == move->piece && |
576 (move->fromrow == POS_UNSPECIFIED || |
577 (move->fromrow == POS_UNSPECIFIED || |
577 move->fromrow == threats[i].fromrow) && |
578 move->fromrow == threats[i].fromrow) && |
578 (move->fromfile == POS_UNSPECIFIED || |
579 (move->fromfile == POS_UNSPECIFIED || |