Rev 44 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 44 | Rev 74 | ||
---|---|---|---|
Line 8... | Line 8... | ||
8 | #define IS_FREE(li,co) (IS_VALID ((li), (co)) && (move->slots[(li)][(co)].part == PART_NONE)) |
8 | #define IS_FREE(li,co) (IS_VALID ((li), (co)) && (move->slots[(li)][(co)].part == PART_NONE)) |
9 | #define CAN_PLAY(li,co) (IS_VALID ((li), (co)) && ((move->slots[(li)][(co)].part == PART_NONE) || (move->slots[(li)][(co)].color != boardslot->color))) |
9 | #define CAN_PLAY(li,co) (IS_VALID ((li), (co)) && ((move->slots[(li)][(co)].part == PART_NONE) || (move->slots[(li)][(co)].color != boardslot->color))) |
10 | 10 | ||
11 | 11 | ||
12 | // prototypes of local functions |
12 | // prototypes of local functions |
- | 13 | static bool Move_IsWayClearBetween (boardmove_t *move, int source_line, int source_column, int target_line, int target_column); |
|
13 | static void AddPossibleMove (boardmove_t **possiblemoves, int *possiblemove_count, int color, int part, int source_line, int source_column, int target_line, int target_column, int promotion_type, bool has_captured, bool is_enpassant); |
14 | static void AddPossibleMove (boardmove_t **possiblemoves, int *possiblemove_count, int color, int part, int source_line, int source_column, int target_line, int target_column, int promotion_type, bool has_captured, bool is_enpassant); |
14 | 15 | ||
15 | 16 | ||
16 | void Move_SetSlot (boardmove_t *move, int line, int column, int color, int part_type) |
17 | void Move_SetSlot (boardmove_t *move, int line, int column, int color, int part_type) |
17 | { |
18 | { |
Line 467... | Line 468... | ||
467 | for (index_line = line + 1; index_line < 8; index_line++) |
468 | for (index_line = line + 1; index_line < 8; index_line++) |
468 | if (!CAN_PLAY (index_line, column)) |
469 | if (!CAN_PLAY (index_line, column)) |
469 | break; // if part can no longer move this way, stop searching |
470 | break; // if part can no longer move this way, stop searching |
470 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, column, color)) |
471 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, column, color)) |
471 | return (false); // this move is possible |
472 | return (false); // this move is possible |
- | 473 | else if (move->slots[index_line][column].part != PART_NONE) |
|
- | 474 | break; // no further moves are possible in the same direction |
|
472 | 475 | ||
473 | // see if rook can move downwards |
476 | // see if rook can move downwards |
474 | for (index_line = line - 1; index_line >= 0; index_line--) |
477 | for (index_line = line - 1; index_line >= 0; index_line--) |
475 | if (!CAN_PLAY (index_line, column)) |
478 | if (!CAN_PLAY (index_line, column)) |
476 | break; // if part can no longer move this way, stop searching |
479 | break; // if part can no longer move this way, stop searching |
477 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, column, color)) |
480 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, column, color)) |
478 | return (false); // this move is possible |
481 | return (false); // this move is possible |
- | 482 | else if (move->slots[index_line][column].part != PART_NONE) |
|
- | 483 | break; // no further moves are possible in the same direction |
|
479 | 484 | ||
480 | // see if rook can move right |
485 | // see if rook can move right |
481 | for (index_column = column + 1; index_column < 8; index_column++) |
486 | for (index_column = column + 1; index_column < 8; index_column++) |
482 | if (!CAN_PLAY (line, index_column)) |
487 | if (!CAN_PLAY (line, index_column)) |
483 | break; // if part can no longer move this way, stop searching |
488 | break; // if part can no longer move this way, stop searching |
484 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, line, index_column, color)) |
489 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, line, index_column, color)) |
485 | return (false); // this move is possible |
490 | return (false); // this move is possible |
- | 491 | else if (move->slots[line][index_column].part != PART_NONE) |
|
- | 492 | break; // no further moves are possible in the same direction |
|
486 | 493 | ||
487 | // see if rook can move left |
494 | // see if rook can move left |
488 | for (index_column = column - 1; index_column >= 0; index_column--) |
495 | for (index_column = column - 1; index_column >= 0; index_column--) |
489 | if (!CAN_PLAY (line, index_column)) |
496 | if (!CAN_PLAY (line, index_column)) |
490 | break; // if part can no longer move this way, stop searching |
497 | break; // if part can no longer move this way, stop searching |
491 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, line, index_column, color)) |
498 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, line, index_column, color)) |
492 | return (false); // this move is possible |
499 | return (false); // this move is possible |
- | 500 | else if (move->slots[line][index_column].part != PART_NONE) |
|
- | 501 | break; // no further moves are possible in the same direction |
|
493 | } |
502 | } |
494 | 503 | ||
495 | ////////////////////////////////////////////////////////////////////////////////////////// |
504 | ////////////////////////////////////////////////////////////////////////////////////////// |
496 | ///////////////////////////////////////// KNIGHT ///////////////////////////////////////// |
505 | ///////////////////////////////////////// KNIGHT ///////////////////////////////////////// |
497 | ////////////////////////////////////////////////////////////////////////////////////////// |
506 | ////////////////////////////////////////////////////////////////////////////////////////// |
Line 527... | Line 536... | ||
527 | for (index_line = line + 1, index_column = column + 1; (index_line < 8) && (index_column < 8); index_line++, index_column++) |
536 | for (index_line = line + 1, index_column = column + 1; (index_line < 8) && (index_column < 8); index_line++, index_column++) |
528 | if (!CAN_PLAY (index_line, index_column)) |
537 | if (!CAN_PLAY (index_line, index_column)) |
529 | break; // if part can no longer move this way, stop searching |
538 | break; // if part can no longer move this way, stop searching |
530 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
539 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
531 | return (false); // this move is possible |
540 | return (false); // this move is possible |
- | 541 | else if (move->slots[index_line][index_column].part != PART_NONE) |
|
- | 542 | break; // no further moves are possible in the same direction |
|
532 | 543 | ||
533 | // see if bishop can move SE |
544 | // see if bishop can move SE |
534 | for (index_line = line - 1, index_column = column + 1; (index_line >= 0) && (index_column < 8); index_line--, index_column++) |
545 | for (index_line = line - 1, index_column = column + 1; (index_line >= 0) && (index_column < 8); index_line--, index_column++) |
535 | if (!CAN_PLAY (index_line, index_column)) |
546 | if (!CAN_PLAY (index_line, index_column)) |
536 | break; // if part can no longer move this way, stop searching |
547 | break; // if part can no longer move this way, stop searching |
537 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
548 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
538 | return (false); // this move is possible |
549 | return (false); // this move is possible |
- | 550 | else if (move->slots[index_line][index_column].part != PART_NONE) |
|
- | 551 | break; // no further moves are possible in the same direction |
|
539 | 552 | ||
540 | // see if bishop can move NW |
553 | // see if bishop can move NW |
541 | for (index_line = line + 1, index_column = column - 1; (index_line < 8) && (index_column >= 0); index_line++, index_column--) |
554 | for (index_line = line + 1, index_column = column - 1; (index_line < 8) && (index_column >= 0); index_line++, index_column--) |
542 | if (!CAN_PLAY (index_line, index_column)) |
555 | if (!CAN_PLAY (index_line, index_column)) |
543 | break; // if part can no longer move this way, stop searching |
556 | break; // if part can no longer move this way, stop searching |
544 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
557 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
545 | return (false); // this move is possible |
558 | return (false); // this move is possible |
- | 559 | else if (move->slots[index_line][index_column].part != PART_NONE) |
|
- | 560 | break; // no further moves are possible in the same direction |
|
546 | 561 | ||
547 | // see if bishop can move SW |
562 | // see if bishop can move SW |
548 | for (index_line = line - 1, index_column = column - 1; (index_line >= 0) && (index_column >= 0); index_line--, index_column--) |
563 | for (index_line = line - 1, index_column = column - 1; (index_line >= 0) && (index_column >= 0); index_line--, index_column--) |
549 | if (!CAN_PLAY (index_line, index_column)) |
564 | if (!CAN_PLAY (index_line, index_column)) |
550 | break; // if part can no longer move this way, stop searching |
565 | break; // if part can no longer move this way, stop searching |
551 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
566 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
552 | return (false); // this move is possible |
567 | return (false); // this move is possible |
- | 568 | else if (move->slots[index_line][index_column].part != PART_NONE) |
|
- | 569 | break; // no further moves are possible in the same direction |
|
553 | } |
570 | } |
554 | 571 | ||
555 | ////////////////////////////////////////////////////////////////////////////////////////// |
572 | ////////////////////////////////////////////////////////////////////////////////////////// |
556 | ///////////////////////////////////////// QUEEN ////////////////////////////////////////// |
573 | ///////////////////////////////////////// QUEEN ////////////////////////////////////////// |
557 | ////////////////////////////////////////////////////////////////////////////////////////// |
574 | ////////////////////////////////////////////////////////////////////////////////////////// |
Line 562... | Line 579... | ||
562 | for (index_line = line + 1; index_line < 8; index_line++) |
579 | for (index_line = line + 1; index_line < 8; index_line++) |
563 | if (!CAN_PLAY (index_line, column)) |
580 | if (!CAN_PLAY (index_line, column)) |
564 | break; // if part can no longer move this way, stop searching |
581 | break; // if part can no longer move this way, stop searching |
565 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, column, color)) |
582 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, column, color)) |
566 | return (false); // this move is possible |
583 | return (false); // this move is possible |
- | 584 | else if (move->slots[index_line][column].part != PART_NONE) |
|
- | 585 | break; // no further moves are possible in the same direction |
|
567 | 586 | ||
568 | // see if queen can move downwards |
587 | // see if queen can move downwards |
569 | for (index_line = line - 1; index_line >= 0; index_line--) |
588 | for (index_line = line - 1; index_line >= 0; index_line--) |
570 | if (!CAN_PLAY (index_line, column)) |
589 | if (!CAN_PLAY (index_line, column)) |
571 | break; // if part can no longer move this way, stop searching |
590 | break; // if part can no longer move this way, stop searching |
572 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, column, color)) |
591 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, column, color)) |
573 | return (false); // this move is possible |
592 | return (false); // this move is possible |
- | 593 | else if (move->slots[index_line][column].part != PART_NONE) |
|
- | 594 | break; // no further moves are possible in the same direction |
|
574 | 595 | ||
575 | // see if queen can move right |
596 | // see if queen can move right |
576 | for (index_column = column + 1; index_column < 8; index_column++) |
597 | for (index_column = column + 1; index_column < 8; index_column++) |
577 | if (!CAN_PLAY (line, index_column)) |
598 | if (!CAN_PLAY (line, index_column)) |
578 | break; // if part can no longer move this way, stop searching |
599 | break; // if part can no longer move this way, stop searching |
579 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, line, index_column, color)) |
600 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, line, index_column, color)) |
580 | return (false); // this move is possible |
601 | return (false); // this move is possible |
- | 602 | else if (move->slots[line][index_column].part != PART_NONE) |
|
- | 603 | break; // no further moves are possible in the same direction |
|
581 | 604 | ||
582 | // see if queen can move left |
605 | // see if queen can move left |
583 | for (index_column = column - 1; index_column >= 0; index_column--) |
606 | for (index_column = column - 1; index_column >= 0; index_column--) |
584 | if (!CAN_PLAY (line, index_column)) |
607 | if (!CAN_PLAY (line, index_column)) |
585 | break; // if part can no longer move this way, stop searching |
608 | break; // if part can no longer move this way, stop searching |
586 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, line, index_column, color)) |
609 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, line, index_column, color)) |
587 | return (false); // this move is possible |
610 | return (false); // this move is possible |
- | 611 | else if (move->slots[line][index_column].part != PART_NONE) |
|
- | 612 | break; // no further moves are possible in the same direction |
|
588 | 613 | ||
589 | // see if queen can move NE |
614 | // see if queen can move NE |
590 | for (index_line = line + 1, index_column = column + 1; (index_line < 8) && (index_column < 8); index_line++, index_column++) |
615 | for (index_line = line + 1, index_column = column + 1; (index_line < 8) && (index_column < 8); index_line++, index_column++) |
591 | if (!CAN_PLAY (index_line, index_column)) |
616 | if (!CAN_PLAY (index_line, index_column)) |
592 | break; // if part can no longer move this way, stop searching |
617 | break; // if part can no longer move this way, stop searching |
593 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
618 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
594 | return (false); // this move is possible |
619 | return (false); // this move is possible |
- | 620 | else if (move->slots[index_line][index_column].part != PART_NONE) |
|
- | 621 | break; // no further moves are possible in the same direction |
|
595 | 622 | ||
596 | // see if queen can move SE |
623 | // see if queen can move SE |
597 | for (index_line = line - 1, index_column = column + 1; (index_line >= 0) && (index_column < 8); index_line--, index_column++) |
624 | for (index_line = line - 1, index_column = column + 1; (index_line >= 0) && (index_column < 8); index_line--, index_column++) |
598 | if (!CAN_PLAY (index_line, index_column)) |
625 | if (!CAN_PLAY (index_line, index_column)) |
599 | break; // if part can no longer move this way, stop searching |
626 | break; // if part can no longer move this way, stop searching |
600 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
627 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
601 | return (false); // this move is possible |
628 | return (false); // this move is possible |
- | 629 | else if (move->slots[index_line][index_column].part != PART_NONE) |
|
- | 630 | break; // no further moves are possible in the same direction |
|
602 | 631 | ||
603 | // see if queen can move NW |
632 | // see if queen can move NW |
604 | for (index_line = line + 1, index_column = column - 1; (index_line < 8) && (index_column >= 0); index_line++, index_column--) |
633 | for (index_line = line + 1, index_column = column - 1; (index_line < 8) && (index_column >= 0); index_line++, index_column--) |
605 | if (!CAN_PLAY (index_line, index_column)) |
634 | if (!CAN_PLAY (index_line, index_column)) |
606 | break; // if part can no longer move this way, stop searching |
635 | break; // if part can no longer move this way, stop searching |
607 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
636 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
608 | return (false); // this move is possible |
637 | return (false); // this move is possible |
- | 638 | else if (move->slots[index_line][index_column].part != PART_NONE) |
|
- | 639 | break; // no further moves are possible in the same direction |
|
609 | 640 | ||
610 | // see if queen can move SW |
641 | // see if queen can move SW |
611 | for (index_line = line - 1, index_column = column - 1; (index_line >= 0) && (index_column >= 0); index_line--, index_column--) |
642 | for (index_line = line - 1, index_column = column - 1; (index_line >= 0) && (index_column >= 0); index_line--, index_column--) |
612 | if (!CAN_PLAY (index_line, index_column)) |
643 | if (!CAN_PLAY (index_line, index_column)) |
613 | break; // if part can no longer move this way, stop searching |
644 | break; // if part can no longer move this way, stop searching |
614 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
645 | else if (!Move_IsColorInCheckAfterTestMove (move, line, column, index_line, index_column, color)) |
615 | return (false); // this move is possible |
646 | return (false); // this move is possible |
- | 647 | else if (move->slots[index_line][index_column].part != PART_NONE) |
|
- | 648 | break; // no further moves are possible in the same direction |
|
616 | } |
649 | } |
617 | 650 | ||
618 | ////////////////////////////////////////////////////////////////////////////////////////// |
651 | ////////////////////////////////////////////////////////////////////////////////////////// |
619 | ////////////////////////////////////////// KING ////////////////////////////////////////// |
652 | ////////////////////////////////////////// KING ////////////////////////////////////////// |
620 | ////////////////////////////////////////////////////////////////////////////////////////// |
653 | ////////////////////////////////////////////////////////////////////////////////////////// |
Line 738... | Line 771... | ||
738 | else if (boardslot->part == PART_ROOK) |
771 | else if (boardslot->part == PART_ROOK) |
739 | { |
772 | { |
740 | // quick checks |
773 | // quick checks |
741 | if ((to_column != from_column) && (to_line != from_line)) |
774 | if ((to_column != from_column) && (to_line != from_line)) |
742 | return (false); // rooks can only move horizontally or vertically |
775 | return (false); // rooks can only move horizontally or vertically |
- | 776 | else if (!Move_IsWayClearBetween (move, from_line, from_column, to_line, to_column)) |
|
- | 777 | return (false); // way must be clear between source and target |
|
743 | 778 | ||
744 | // do we want the rook to move upwards ? |
779 | // do we want the rook to move upwards ? |
745 | if (to_line > from_line) |
780 | if (to_line > from_line) |
746 | { |
781 | { |
747 | // see if rook can move upwards |
782 | // see if rook can move upwards |
748 | for (index_line = from_line + 1; index_line < 8; index_line++) |
783 | for (index_line = from_line + 1; index_line < 8; index_line++) |
749 | if (!CAN_PLAY (index_line, to_column)) |
784 | if (!CAN_PLAY (index_line, to_column)) |
750 | return (false); // if rook can no longer move this way, stop searching |
785 | return (false); // if rook can no longer move this way, stop searching |
751 | else if (index_line == to_line) |
786 | else if (index_line == to_line) |
752 | { |
- | |
753 |
|
787 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, to_line, to_column, boardslot->color)); // if move is safe for king, then it's possible |
754 | return (true); // this move is possible |
- | |
755 | - | ||
756 | return (false); // else this rook can't move in the claimed way (its king would be in check) |
- | |
757 | } |
- | |
758 | else if (move->slots[index_line][to_column].part != PART_NONE) |
- | |
759 | return (false); // rook can take a part there BUT it's not the location we want |
- | |
760 | } |
788 | } |
761 | 789 | ||
762 | // else do we want the rook to move downwards ? |
790 | // else do we want the rook to move downwards ? |
763 | else if (to_line < from_line) |
791 | else if (to_line < from_line) |
764 | { |
792 | { |
765 | // see if rook can move downwards |
793 | // see if rook can move downwards |
766 | for (index_line = from_line - 1; index_line >= 0; index_line--) |
794 | for (index_line = from_line - 1; index_line >= 0; index_line--) |
767 | if (!CAN_PLAY (index_line, to_column)) |
795 | if (!CAN_PLAY (index_line, to_column)) |
768 | return (false); // if rook can no longer move this way, stop searching |
796 | return (false); // if rook can no longer move this way, stop searching |
769 | else if (index_line == to_line) |
797 | else if (index_line == to_line) |
770 | { |
- | |
771 |
|
798 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, to_line, to_column, boardslot->color)); // if move is safe for king, then it's possible |
772 | return (true); // this move is possible |
- | |
773 | - | ||
774 | return (false); // else this rook can't move in the claimed way (its king would be in check) |
- | |
775 | } |
- | |
776 | else if (move->slots[index_line][to_column].part != PART_NONE) |
- | |
777 | return (false); // rook can take a part there BUT it's not the location we want |
- | |
778 | } |
799 | } |
779 | 800 | ||
780 | // else do we want the rook to move right ? |
801 | // else do we want the rook to move right ? |
781 | else if (to_column > from_column) |
802 | else if (to_column > from_column) |
782 | { |
803 | { |
783 | // see if rook can move right |
804 | // see if rook can move right |
784 | for (index_column = from_column + 1; index_column < 8; index_column++) |
805 | for (index_column = from_column + 1; index_column < 8; index_column++) |
785 | if (!CAN_PLAY (to_line, index_column)) |
806 | if (!CAN_PLAY (to_line, index_column)) |
786 | return (false); // if rook can no longer move this way, stop searching |
807 | return (false); // if rook can no longer move this way, stop searching |
787 | else if (index_column == to_column) |
808 | else if (index_column == to_column) |
788 | { |
- | |
789 |
|
809 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, to_line, to_column, boardslot->color)); // if move is safe for king, then it's possible |
790 | return (true); // this move is possible |
- | |
791 | - | ||
792 | return (false); // else this rook can't move in the claimed way (its king would be in check) |
- | |
793 | } |
- | |
794 | else if (move->slots[to_line][index_column].part != PART_NONE) |
- | |
795 | return (false); // rook can take a part there BUT it's not the location we want |
- | |
796 | } |
810 | } |
797 | 811 | ||
798 | // else do we want the rook to move left ? |
812 | // else do we want the rook to move left ? |
799 | else if (to_column < from_column) |
813 | else if (to_column < from_column) |
800 | { |
814 | { |
801 | // see if rook can move left |
815 | // see if rook can move left |
802 | for (index_column = from_column - 1; index_column >= 0; index_column--) |
816 | for (index_column = from_column - 1; index_column >= 0; index_column--) |
803 | if (!CAN_PLAY (to_line, index_column)) |
817 | if (!CAN_PLAY (to_line, index_column)) |
804 | return (false); // if rook can no longer move this way, stop searching |
818 | return (false); // if rook can no longer move this way, stop searching |
805 | else if (index_column == to_column) |
819 | else if (index_column == to_column) |
806 | { |
- | |
807 |
|
820 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, to_line, to_column, boardslot->color)); // if move is safe for king, then it's possible |
808 | return (true); // this move is possible |
- | |
809 | - | ||
810 | return (false); // else this rook can't move in the claimed way (its king would be in check) |
- | |
811 | } |
- | |
812 | else if (move->slots[to_line][index_column].part != PART_NONE) |
- | |
813 | return (false); // rook can take a part there BUT it's not the location we want |
- | |
814 | } |
821 | } |
815 | 822 | ||
816 | return (false); // this rook can't move in the claimed way |
823 | return (false); // this rook can't move in the claimed way |
817 | } |
824 | } |
818 | 825 | ||
Line 821... | Line 828... | ||
821 | ////////////////////////////////////////////////////////////////////////////////////////// |
828 | ////////////////////////////////////////////////////////////////////////////////////////// |
822 | // else is it a knight ? |
829 | // else is it a knight ? |
823 | else if (boardslot->part == PART_KNIGHT) |
830 | else if (boardslot->part == PART_KNIGHT) |
824 | { |
831 | { |
825 | // do we want to move that knight in one of the allowed directions ? |
832 | // do we want to move that knight in one of the allowed directions ? |
826 | if (((from_line + 2 == to_line) && (from_column - 1 == to_column)) // NNW |
833 | if ( ((from_line + 2 == to_line) && (from_column - 1 == to_column)) // NNW |
827 | || ((from_line + 2 == to_line) && (from_column + 1 == to_column)) // NNE |
834 | || ((from_line + 2 == to_line) && (from_column + 1 == to_column)) // NNE |
828 | || ((from_line + 1 == to_line) && (from_column + 2 == to_column)) // ENE |
835 | || ((from_line + 1 == to_line) && (from_column + 2 == to_column)) // ENE |
829 | || ((from_line - 1 == to_line) && (from_column + 2 == to_column)) // ESE |
836 | || ((from_line - 1 == to_line) && (from_column + 2 == to_column)) // ESE |
830 | || ((from_line - 2 == to_line) && (from_column - 1 == to_column)) // SSW |
837 | || ((from_line - 2 == to_line) && (from_column - 1 == to_column)) // SSW |
831 | || ((from_line - 2 == to_line) && (from_column + 1 == to_column)) // SSE |
838 | || ((from_line - 2 == to_line) && (from_column + 1 == to_column)) // SSE |
Line 850... | Line 857... | ||
850 | else if (boardslot->part == PART_BISHOP) |
857 | else if (boardslot->part == PART_BISHOP) |
851 | { |
858 | { |
852 | // quick checks |
859 | // quick checks |
853 | if (abs (to_column - from_column) != abs (to_line - from_line)) |
860 | if (abs (to_column - from_column) != abs (to_line - from_line)) |
854 | return (false); // bishops can only move diagonally |
861 | return (false); // bishops can only move diagonally |
- | 862 | else if (!Move_IsWayClearBetween (move, from_line, from_column, to_line, to_column)) |
|
- | 863 | return (false); // way must be clear between source and target |
|
855 | 864 | ||
856 | // do we want to move the bishop NE ? |
865 | // do we want to move the bishop NE ? |
857 | if ((to_line > from_line) && (to_column > from_column)) |
866 | if ((to_line > from_line) && (to_column > from_column)) |
858 | { |
867 | { |
859 | // see if bishop can move NE |
868 | // see if bishop can move NE |
860 | for (index_line = from_line + 1, index_column = from_column + 1; (index_line < 8) && (index_column < 8); index_line++, index_column++) |
869 | for (index_line = from_line + 1, index_column = from_column + 1; (index_line < 8) && (index_column < 8); index_line++, index_column++) |
861 | if (!CAN_PLAY (index_line, index_column)) |
870 | if (!CAN_PLAY (index_line, index_column)) |
862 | return (false); // if bishop can no longer move this way, stop searching |
871 | return (false); // if bishop can no longer move this way, stop searching |
863 | else if ((index_line == to_line) && (index_column == to_column)) |
872 | else if ((index_line == to_line) && (index_column == to_column)) |
864 | { |
- | |
865 |
|
873 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, index_line, index_column, boardslot->color)); // if move is safe for king, then it's possible |
866 | return (true); // this move is possible |
- | |
867 | - | ||
868 | return (false); // else this bishop can't move in the claimed way (his king would be in check) |
- | |
869 | } |
- | |
870 | else if (move->slots[index_line][index_column].part != PART_NONE) |
- | |
871 | return (false); // bishop can take a part there BUT it's not the location we want |
- | |
872 | } |
874 | } |
873 | 875 | ||
874 | // else do we want to move the bishop SE ? |
876 | // else do we want to move the bishop SE ? |
875 | else if ((to_line < from_line) && (to_column > from_column)) |
877 | else if ((to_line < from_line) && (to_column > from_column)) |
876 | { |
878 | { |
877 | // see if bishop can move SE |
879 | // see if bishop can move SE |
878 | for (index_line = from_line - 1, index_column = from_column + 1; (index_line >= 0) && (index_column < 8); index_line--, index_column++) |
880 | for (index_line = from_line - 1, index_column = from_column + 1; (index_line >= 0) && (index_column < 8); index_line--, index_column++) |
879 | if (!CAN_PLAY (index_line, index_column)) |
881 | if (!CAN_PLAY (index_line, index_column)) |
880 | return (false); // if bishop can no longer move this way, stop searching |
882 | return (false); // if bishop can no longer move this way, stop searching |
881 | else if ((index_line == to_line) && (index_column == to_column)) |
883 | else if ((index_line == to_line) && (index_column == to_column)) |
882 | { |
- | |
883 |
|
884 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, index_line, index_column, boardslot->color)); // if move is safe for king, then it's possible |
884 | return (true); // this move is possible |
- | |
885 | - | ||
886 | return (false); // else this bishop can't move in the claimed way (his king would be in check) |
- | |
887 | } |
- | |
888 | else if (move->slots[index_line][index_column].part != PART_NONE) |
- | |
889 | return (false); // bishop can take a part there BUT it's not the location we want |
- | |
890 | } |
885 | } |
891 | 886 | ||
892 | // else do we want to move the bishop NW ? |
887 | // else do we want to move the bishop NW ? |
893 | else if ((to_line > from_line) && (to_column < from_column)) |
888 | else if ((to_line > from_line) && (to_column < from_column)) |
894 | { |
889 | { |
895 | // see if bishop can move NW |
890 | // see if bishop can move NW |
896 | for (index_line = from_line + 1, index_column = from_column - 1; (index_line < 8) && (index_column >= 0); index_line++, index_column--) |
891 | for (index_line = from_line + 1, index_column = from_column - 1; (index_line < 8) && (index_column >= 0); index_line++, index_column--) |
897 | if (!CAN_PLAY (index_line, index_column)) |
892 | if (!CAN_PLAY (index_line, index_column)) |
898 | return (false); // if bishop can no longer move this way, stop searching |
893 | return (false); // if bishop can no longer move this way, stop searching |
899 | else if ((index_line == to_line) && (index_column == to_column)) |
894 | else if ((index_line == to_line) && (index_column == to_column)) |
900 | { |
- | |
901 |
|
895 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, index_line, index_column, boardslot->color)); // if move is safe for king, then it's possible |
902 | return (true); // this move is possible |
- | |
903 | - | ||
904 | return (false); // else this bishop can't move in the claimed way (his king would be in check) |
- | |
905 | } |
- | |
906 | else if (move->slots[index_line][index_column].part != PART_NONE) |
- | |
907 | return (false); // bishop can take a part there BUT it's not the location we want |
- | |
908 | } |
896 | } |
909 | 897 | ||
910 | // else do we want to move the bishop SW ? |
898 | // else do we want to move the bishop SW ? |
911 | else if ((to_line < from_line) && (to_column < from_column)) |
899 | else if ((to_line < from_line) && (to_column < from_column)) |
912 | { |
900 | { |
913 | // see if bishop can move SW |
901 | // see if bishop can move SW |
914 | for (index_line = from_line - 1, index_column = from_column - 1; (index_line >= 0) && (index_column >= 0); index_line--, index_column--) |
902 | for (index_line = from_line - 1, index_column = from_column - 1; (index_line >= 0) && (index_column >= 0); index_line--, index_column--) |
915 | if (!CAN_PLAY (index_line, index_column)) |
903 | if (!CAN_PLAY (index_line, index_column)) |
916 | return (false); // if bishop can no longer move this way, stop searching |
904 | return (false); // if bishop can no longer move this way, stop searching |
917 | else if ((index_line == to_line) && (index_column == to_column)) |
905 | else if ((index_line == to_line) && (index_column == to_column)) |
918 | { |
- | |
919 |
|
906 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, index_line, index_column, boardslot->color)); // if move is safe for king, then it's possible |
920 | return (true); // this move is possible |
- | |
921 | - | ||
922 | return (false); // else this bishop can't move in the claimed way (his king would be in check) |
- | |
923 | } |
- | |
924 | else if (move->slots[index_line][index_column].part != PART_NONE) |
- | |
925 | return (false); // bishop can take a part there BUT it's not the location we want |
- | |
926 | } |
907 | } |
927 | 908 | ||
928 | return (false); // this bishop can't move in the claimed way |
909 | return (false); // this bishop can't move in the claimed way |
929 | } |
910 | } |
930 | 911 | ||
Line 936... | Line 917... | ||
936 | { |
917 | { |
937 | // quick checks |
918 | // quick checks |
938 | if ((to_column != from_column) && (to_line != from_line) |
919 | if ((to_column != from_column) && (to_line != from_line) |
939 | && (abs (to_column - from_column) != abs (to_line - from_line))) |
920 | && (abs (to_column - from_column) != abs (to_line - from_line))) |
940 | return (false); // queens can only move horizontally, vertically or diagonally |
921 | return (false); // queens can only move horizontally, vertically or diagonally |
- | 922 | else if (!Move_IsWayClearBetween (move, from_line, from_column, to_line, to_column)) |
|
- | 923 | return (false); // way must be clear between source and target |
|
941 | 924 | ||
942 | // do we want to move that queen vertically ? |
925 | // do we want to move that queen vertically ? |
943 | if (from_column == to_column) |
926 | if (from_column == to_column) |
944 | { |
927 | { |
945 | // do we want to move her upwards ? |
928 | // do we want to move her upwards ? |
Line 948... | Line 931... | ||
948 | // see if queen can move upwards |
931 | // see if queen can move upwards |
949 | for (index_line = from_line + 1; index_line < 8; index_line++) |
932 | for (index_line = from_line + 1; index_line < 8; index_line++) |
950 | if (!CAN_PLAY (index_line, to_column)) |
933 | if (!CAN_PLAY (index_line, to_column)) |
951 | return (false); // if queen can no longer move this way, stop searching |
934 | return (false); // if queen can no longer move this way, stop searching |
952 | else if (index_line == to_line) |
935 | else if (index_line == to_line) |
953 | { |
- | |
954 |
|
936 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, to_line, to_column, boardslot->color)); // if move is safe for king, then it's possible |
955 | return (true); // this move is possible |
- | |
956 | - | ||
957 | return (false); // else this queen can't move in the claimed way (her king would be in check) |
- | |
958 | } |
- | |
959 | else if (move->slots[index_line][to_column].part != PART_NONE) |
- | |
960 | return (false); // queen can take a part there BUT it's not the location we want |
- | |
961 | } |
937 | } |
962 | 938 | ||
963 | // else do we want to move her downwards ? |
939 | // else do we want to move her downwards ? |
964 | else if (to_line < from_line) |
940 | else if (to_line < from_line) |
965 | { |
941 | { |
966 | // see if queen can move downwards |
942 | // see if queen can move downwards |
967 | for (index_line = from_line - 1; index_line >= 0; index_line--) |
943 | for (index_line = from_line - 1; index_line >= 0; index_line--) |
968 | if (!CAN_PLAY (index_line, to_column)) |
944 | if (!CAN_PLAY (index_line, to_column)) |
969 | return (false); // if queen can no longer move this way, stop searching |
945 | return (false); // if queen can no longer move this way, stop searching |
970 | else if (index_line == to_line) |
946 | else if (index_line == to_line) |
971 | { |
- | |
972 |
|
947 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, to_line, to_column, boardslot->color)); // if move is safe for king, then it's possible |
973 | return (true); // this move is possible |
- | |
974 | - | ||
975 | return (false); // else this queen can't move in the claimed way (her king would be in check) |
- | |
976 | } |
- | |
977 | else if (move->slots[index_line][to_column].part != PART_NONE) |
- | |
978 | return (false); // queen can take a part there BUT it's not the location we want |
- | |
979 | } |
948 | } |
980 | 949 | ||
981 | return (false); // this queen can't move in the claimed way |
950 | return (false); // this queen can't move in the claimed way |
982 | } |
951 | } |
983 | 952 | ||
Line 990... | Line 959... | ||
990 | // see if queen can move right |
959 | // see if queen can move right |
991 | for (index_column = from_column + 1; index_column < 8; index_column++) |
960 | for (index_column = from_column + 1; index_column < 8; index_column++) |
992 | if (!CAN_PLAY (to_line, index_column)) |
961 | if (!CAN_PLAY (to_line, index_column)) |
993 | return (false); // if queen can no longer move this way, stop searching |
962 | return (false); // if queen can no longer move this way, stop searching |
994 | else if (index_column == to_column) |
963 | else if (index_column == to_column) |
995 | { |
- | |
996 |
|
964 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, to_line, to_column, boardslot->color)); // if move is safe for king, then it's possible |
997 | return (true); // this move is possible |
- | |
998 | - | ||
999 | return (false); // else this queen can't move in the claimed way (her king would be in check) |
- | |
1000 | } |
- | |
1001 | else if (move->slots[to_line][index_column].part != PART_NONE) |
- | |
1002 | return (false); // queen can take a part there BUT it's not the location we want |
- | |
1003 | } |
965 | } |
1004 | 966 | ||
1005 | // else do we want this queen to move left ? |
967 | // else do we want this queen to move left ? |
1006 | else if (to_column < from_column) |
968 | else if (to_column < from_column) |
1007 | { |
969 | { |
1008 | // see if queen can move left |
970 | // see if queen can move left |
1009 | for (index_column = from_column - 1; index_column >= 0; index_column--) |
971 | for (index_column = from_column - 1; index_column >= 0; index_column--) |
1010 | if (!CAN_PLAY (to_line, index_column)) |
972 | if (!CAN_PLAY (to_line, index_column)) |
1011 | return (false); // if queen can no longer move this way, stop searching |
973 | return (false); // if queen can no longer move this way, stop searching |
1012 | else if (index_column == to_column) |
974 | else if (index_column == to_column) |
1013 | { |
- | |
1014 |
|
975 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, to_line, to_column, boardslot->color)); // if move is safe for king, then it's possible |
1015 | return (true); // this move is possible |
- | |
1016 | - | ||
1017 | return (false); // else this queen can't move in the claimed way (her king would be in check) |
- | |
1018 | } |
- | |
1019 | else if (move->slots[to_line][index_column].part != PART_NONE) |
- | |
1020 | return (false); // queen can take a part there BUT it's not the location we want |
- | |
1021 | } |
976 | } |
1022 | 977 | ||
1023 | return (false); // this queen can't move in the claimed way |
978 | return (false); // this queen can't move in the claimed way |
1024 | } |
979 | } |
1025 | 980 | ||
Line 1029... | Line 984... | ||
1029 | // see if queen can move NE |
984 | // see if queen can move NE |
1030 | for (index_line = from_line + 1, index_column = from_column + 1; (index_line < 8) && (index_column < 8); index_line++, index_column++) |
985 | for (index_line = from_line + 1, index_column = from_column + 1; (index_line < 8) && (index_column < 8); index_line++, index_column++) |
1031 | if (!CAN_PLAY (index_line, index_column)) |
986 | if (!CAN_PLAY (index_line, index_column)) |
1032 | return (false); // if queen can no longer move this way, stop searching |
987 | return (false); // if queen can no longer move this way, stop searching |
1033 | else if ((index_line == to_line) && (index_column == to_column)) |
988 | else if ((index_line == to_line) && (index_column == to_column)) |
1034 | { |
- | |
1035 |
|
989 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, index_line, index_column, boardslot->color)); // if move is safe for king, then it's possible |
1036 | return (true); // this move is possible |
- | |
1037 | - | ||
1038 | return (false); // else this queen can't move in the claimed way (her king would be in check) |
- | |
1039 | } |
- | |
1040 | else if (move->slots[index_line][index_column].part != PART_NONE) |
- | |
1041 | return (false); // queen can take a part there BUT it's not the location we want |
- | |
1042 | } |
990 | } |
1043 | 991 | ||
1044 | // else do we want to move the queen SE ? |
992 | // else do we want to move the queen SE ? |
1045 | else if ((to_line < from_line) && (to_column > from_column)) |
993 | else if ((to_line < from_line) && (to_column > from_column)) |
1046 | { |
994 | { |
1047 | // see if queen can move SE |
995 | // see if queen can move SE |
1048 | for (index_line = from_line - 1, index_column = from_column + 1; (index_line >= 0) && (index_column < 8); index_line--, index_column++) |
996 | for (index_line = from_line - 1, index_column = from_column + 1; (index_line >= 0) && (index_column < 8); index_line--, index_column++) |
1049 | if (!CAN_PLAY (index_line, index_column)) |
997 | if (!CAN_PLAY (index_line, index_column)) |
1050 | return (false); // if queen can no longer move this way, stop searching |
998 | return (false); // if queen can no longer move this way, stop searching |
1051 | else if ((index_line == to_line) && (index_column == to_column)) |
999 | else if ((index_line == to_line) && (index_column == to_column)) |
1052 | { |
- | |
1053 |
|
1000 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, index_line, index_column, boardslot->color)); // if move is safe for king, then it's possible |
1054 | return (true); // this move is possible |
- | |
1055 | - | ||
1056 | return (false); // else this queen can't move in the claimed way (her king would be in check) |
- | |
1057 | } |
- | |
1058 | else if (move->slots[index_line][index_column].part != PART_NONE) |
- | |
1059 | return (false); // queen can take a part there BUT it's not the location we want |
- | |
1060 | } |
1001 | } |
1061 | 1002 | ||
1062 | // else do we want to move the queen NW ? |
1003 | // else do we want to move the queen NW ? |
1063 | else if ((to_line > from_line) && (to_column < from_column)) |
1004 | else if ((to_line > from_line) && (to_column < from_column)) |
1064 | { |
1005 | { |
1065 | // see if queen can move NW |
1006 | // see if queen can move NW |
1066 | for (index_line = from_line + 1, index_column = from_column - 1; (index_line < 8) && (index_column >= 0); index_line++, index_column--) |
1007 | for (index_line = from_line + 1, index_column = from_column - 1; (index_line < 8) && (index_column >= 0); index_line++, index_column--) |
1067 | if (!CAN_PLAY (index_line, index_column)) |
1008 | if (!CAN_PLAY (index_line, index_column)) |
1068 | return (false); // if queen can no longer move this way, stop searching |
1009 | return (false); // if queen can no longer move this way, stop searching |
1069 | else if ((index_line == to_line) && (index_column == to_column)) |
1010 | else if ((index_line == to_line) && (index_column == to_column)) |
1070 | { |
- | |
1071 |
|
1011 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, index_line, index_column, boardslot->color)); // if move is safe for king, then it's possible |
1072 | return (true); // this move is possible |
- | |
1073 | - | ||
1074 | return (false); // else this queen can't move in the claimed way (her king would be in check) |
- | |
1075 | } |
- | |
1076 | else if (move->slots[index_line][index_column].part != PART_NONE) |
- | |
1077 | return (false); // queen can take a part there BUT it's not the location we want |
- | |
1078 | } |
1012 | } |
1079 | 1013 | ||
1080 | // else do we want to move the queen SW ? |
1014 | // else do we want to move the queen SW ? |
1081 | else if ((to_line < from_line) && (to_column < from_column)) |
1015 | else if ((to_line < from_line) && (to_column < from_column)) |
1082 | { |
1016 | { |
1083 | // see if queen can move SW |
1017 | // see if queen can move SW |
1084 | for (index_line = from_line - 1, index_column = from_column - 1; (index_line >= 0) && (index_column >= 0); index_line--, index_column--) |
1018 | for (index_line = from_line - 1, index_column = from_column - 1; (index_line >= 0) && (index_column >= 0); index_line--, index_column--) |
1085 | if (!CAN_PLAY (index_line, index_column)) |
1019 | if (!CAN_PLAY (index_line, index_column)) |
1086 | return (false); // if queen can no longer move this way, stop searching |
1020 | return (false); // if queen can no longer move this way, stop searching |
1087 | else if ((index_line == to_line) && (index_column == to_column)) |
1021 | else if ((index_line == to_line) && (index_column == to_column)) |
1088 | { |
- | |
1089 |
|
1022 | return (!Move_IsColorInCheckAfterTestMove (move, from_line, from_column, index_line, index_column, boardslot->color)); // if move is safe for king, then it's possible |
1090 | return (true); // this move is possible |
- | |
1091 | - | ||
1092 | return (false); // else this queen can't move in the claimed way (her king would be in check) |
- | |
1093 | } |
- | |
1094 | else if (move->slots[index_line][index_column].part != PART_NONE) |
- | |
1095 | return (false); // queen can take a part there BUT it's not the location we want |
- | |
1096 | } |
1023 | } |
1097 | 1024 | ||
1098 | return (false); // this queen can't move in the claimed way |
1025 | return (false); // this queen can't move in the claimed way |
1099 | } |
1026 | } |
1100 | 1027 | ||
Line 1982... | Line 1909... | ||
1982 | } |
1909 | } |
1983 | 1910 | ||
1984 | // finally, save the FEN string with which we initialized this board |
1911 | // finally, save the FEN string with which we initialized this board |
1985 | Move_DescribeInFEN (move); |
1912 | Move_DescribeInFEN (move); |
1986 | return (true); // finished, no error encountered |
1913 | return (true); // finished, no error encountered |
- | 1914 | } |
|
- | 1915 | ||
- | 1916 | ||
- | 1917 | static bool Move_IsWayClearBetween (boardmove_t *move, int source_line, int source_column, int target_line, int target_column) |
|
- | 1918 | { |
|
- | 1919 | // helper function that checks and returns whether the way is clear between source and target. |
|
- | 1920 | ||
- | 1921 | int column_delta_step; |
|
- | 1922 | int line_delta_step; |
|
- | 1923 | int column_delta; |
|
- | 1924 | int line_delta; |
|
- | 1925 | int column; |
|
- | 1926 | int line; |
|
- | 1927 | ||
- | 1928 | line_delta = target_line - source_line; |
|
- | 1929 | line_delta_step = (line_delta != 0 ? line_delta / abs (line_delta) : 0); |
|
- | 1930 | column_delta = target_column - source_column; |
|
- | 1931 | column_delta_step = (column_delta != 0 ? column_delta / abs (column_delta) : 0); |
|
- | 1932 | ||
- | 1933 | // for each square that's between source and target... |
|
- | 1934 | for (line = source_line + line_delta_step, column = source_column + column_delta_step; |
|
- | 1935 | IS_VALID (line, column) && (line != target_line || column != target_column); |
|
- | 1936 | line += line_delta_step, column += column_delta_step) |
|
- | 1937 | if ((line == target_line) && (column == target_column)) |
|
- | 1938 | break; // don't verify the target position's square |
|
- | 1939 | else if (move->slots[line][column].part != PART_NONE) |
|
- | 1940 | return (false); // there's something in the way... |
|
- | 1941 | ||
- | 1942 | if (!IS_VALID (line, column)) |
|
- | 1943 | return (false); // we've gotten off board... |
|
- | 1944 | ||
- | 1945 | return (true); // the way looks clear between source and target |
|
1987 | } |
1946 | } |
1988 | 1947 | ||
1989 | 1948 | ||
1990 | static void AddPossibleMove (boardmove_t **possiblemoves, int *possiblemove_count, int color, int part, int source_line, int source_column, int target_line, int target_column, int promotion_type, bool has_captured, bool is_enpassant) |
1949 | static void AddPossibleMove (boardmove_t **possiblemoves, int *possiblemove_count, int color, int part, int source_line, int source_column, int target_line, int target_column, int promotion_type, bool has_captured, bool is_enpassant) |
1991 | { |
1950 | { |