src/chess/rules.c

changeset 135
114e764fbae5
parent 133
c58ae152733e
child 136
1a84ee6b4bf0
equal deleted inserted replaced
134:ce2d285d2ccb 135:114e764fbae5
537 candidates[candidatecount].piece = gamestate->board[r][f]; 537 candidates[candidatecount].piece = gamestate->board[r][f];
538 candidates[candidatecount].fromrow = r; 538 candidates[candidatecount].fromrow = r;
539 candidates[candidatecount].fromfile = f; 539 candidates[candidatecount].fromfile = f;
540 candidates[candidatecount].torow = row; 540 candidates[candidatecount].torow = row;
541 candidates[candidatecount].tofile = file; 541 candidates[candidatecount].tofile = file;
542 if ((gamestate->board[r][f]&PIECE_MASK) == PAWN
543 && (row == 0 || row == 7)) {
544 /* the exact piece for promotion does not matter */
545 candidates[candidatecount].promotion = color|QUEEN;
546 }
542 candidatecount++; 547 candidatecount++;
543 548
544 /* capturing move */ 549 /* capturing move */
545 memcpy(&(candidates[candidatecount]), 550 memcpy(&(candidates[candidatecount]),
546 &(candidates[candidatecount-1]), sizeof(Move)); 551 &(candidates[candidatecount-1]), sizeof(Move));
641 uint8_t piece = move->piece & PIECE_MASK; 646 uint8_t piece = move->piece & PIECE_MASK;
642 bool incheck = gamestate->movecount > 0 ? last_move(gamestate).check:false; 647 bool incheck = gamestate->movecount > 0 ? last_move(gamestate).check:false;
643 648
644 Move threats[16], *threat = NULL; 649 Move threats[16], *threat = NULL;
645 uint8_t threatcount; 650 uint8_t threatcount;
646 651
647 if (get_threats(gamestate, move->torow, move->tofile, color, 652 if (get_threats(gamestate, move->torow, move->tofile, color,
648 threats, &threatcount)) { 653 threats, &threatcount)) {
649 654
650 int reason = INVALID_POSITION; 655 int reason = INVALID_POSITION;
651 656
652 /* find threats for the specified position */ 657 /* find threats for the specified position */
653 for (uint8_t i = 0 ; i < threatcount ; i++) { 658 for (uint8_t i = 0 ; i < threatcount ; i++) {
654 if ((threats[i].piece & PIECE_MASK) == piece 659 if (threats[i].piece == move->piece &&
655 && (threats[i].piece & COLOR_MASK) == color &&
656 (move->fromrow == POS_UNSPECIFIED || 660 (move->fromrow == POS_UNSPECIFIED ||
657 move->fromrow == threats[i].fromrow) && 661 move->fromrow == threats[i].fromrow) &&
658 (move->fromfile == POS_UNSPECIFIED || 662 (move->fromfile == POS_UNSPECIFIED ||
659 move->fromfile == threats[i].fromfile)) { 663 move->fromfile == threats[i].fromfile)) {
660 664
661 if (threat) { 665 if (threat) {
662 return AMBIGUOUS_MOVE; 666 return AMBIGUOUS_MOVE;
663 } else { 667 } else {
664 /* found threat is no real threat */ 668 /* found threat is no real threat */
669 // TODO: why didn't we call get_real_threats() ?
665 if (is_pinned(gamestate, &(threats[i]))) { 670 if (is_pinned(gamestate, &(threats[i]))) {
666 reason = incheck?KING_IN_CHECK: 671 reason = incheck?KING_IN_CHECK:
667 (piece==KING?KING_MOVES_INTO_CHECK:PIECE_PINNED); 672 (piece==KING?KING_MOVES_INTO_CHECK:PIECE_PINNED);
668 } else { 673 } else {
669 threat = &(threats[i]); 674 threat = &(threats[i]);
675 /* can't threaten specified position */ 680 /* can't threaten specified position */
676 if (!threat) { 681 if (!threat) {
677 return reason; 682 return reason;
678 } 683 }
679 684
680 memcpy(move, threat, sizeof(Move)); 685 /* found a threat, copy the source location */
686 move->fromrow = threat->fromrow;
687 move->fromfile = threat->fromfile;
681 return VALID_MOVE_SYNTAX; 688 return VALID_MOVE_SYNTAX;
682 } else { 689 } else {
683 return INVALID_POSITION; 690 return INVALID_POSITION;
684 } 691 }
685 } 692 }

mercurial