src/chess/rules.c

changeset 168
663676cfef6e
parent 167
fd1d3f0a7a73
equal deleted inserted replaced
167:fd1d3f0a7a73 168:663676cfef6e
136 } 136 }
137 } else if (piece_type(move->piece) != KING) { 137 } else if (piece_type(move->piece) != KING) {
138 /* resolve ambiguities, if any */ 138 /* resolve ambiguities, if any */
139 Move candidates[16]; 139 Move candidates[16];
140 size_t ccount; 140 size_t ccount;
141 if (get_candidates(gamestate, move->torow, move->tofile, 141 if (get_real_candidates(gamestate, move->torow, move->tofile,
142 piece_color(move->piece), candidates, &ccount)) { 142 piece_color(move->piece), candidates, &ccount)) {
143 unsigned int ambrows = 0, ambfiles = 0, ambpiece = 0; 143 unsigned int ambrows = 0, ambfiles = 0, ambpiece = 0;
144 for (size_t i = 0 ; i < ccount ; i++) { 144 for (size_t i = 0 ; i < ccount ; i++) {
145 // TODO: check if we need to discard pinned pieces here
146 if (candidates[i].piece == move->piece) { 145 if (candidates[i].piece == move->piece) {
147 ambpiece++; 146 ambpiece++;
148 if (candidates[i].fromrow == move->fromrow) { 147 if (candidates[i].fromrow == move->fromrow) {
149 ambrows++; 148 ambrows++;
150 } 149 }
666 665
667 bool get_threats(const GameState *gamestate, Row row, File file, 666 bool get_threats(const GameState *gamestate, Row row, File file,
668 Color color, Move *threats, size_t *threatcount) { 667 Color color, Move *threats, size_t *threatcount) {
669 668
670 /* simulate a capturing move on the target position */ 669 /* simulate a capturing move on the target position */
671 // TODO: this does NOT disregard the pin, as stated in the spec!
672 Color opcolor = opponent_color(color); 670 Color opcolor = opponent_color(color);
673 GameState simulation = gamestate_copy_sim(gamestate); 671 GameState simulation = gamestate_copy_sim(gamestate);
674 if (piece_color(piece_at(&simulation, row, file)) != opcolor) { 672 if (piece_color(piece_at(&simulation, row, file)) != opcolor) {
675 /* set a fake pawn if the field is not occupied by the opponent */ 673 /* set a fake pawn if the field is not occupied by the opponent */
676 piece_set(&simulation, row, file, mkpiece(PAWN, opcolor)); 674 piece_set(&simulation, row, file, mkpiece(PAWN, opcolor));
728 726
729 File kingfile = 0; 727 File kingfile = 0;
730 Row kingrow = 0; 728 Row kingrow = 0;
731 for (Row row = 0 ; row < 8 ; row++) { 729 for (Row row = 0 ; row < 8 ; row++) {
732 for (File file = 0 ; file < 8 ; file++) { 730 for (File file = 0 ; file < 8 ; file++) {
733 if (simulation.board[row][file] == (color|KING)) { 731 if (piece_at(&simulation, row, file) == mkpiece(KING, color)) {
734 kingfile = file; 732 kingfile = file;
735 kingrow = row; 733 kingrow = row;
736 } 734 }
737 } 735 }
738 } 736 }
742 gamestate_cleanup(&simulation); 740 gamestate_cleanup(&simulation);
743 741
744 return covered; 742 return covered;
745 } 743 }
746 744
745 bool get_real_candidates(const GameState *gamestate, Row row, File file,
746 Color color, Move *moves, size_t *movecount) {
747
748 if (movecount) {
749 *movecount = 0;
750 }
751
752 Move candidates[16];
753 size_t ccount;
754 if (get_candidates(gamestate, row, file, color, candidates, &ccount)) {
755 bool result = false;
756 for (size_t i = 0 ; i < ccount ; i++) {
757 if (!is_pinned(gamestate, &candidates[i])) {
758 result = true;
759 if (moves && movecount) {
760 moves[(*movecount)++] = candidates[i];
761 }
762 }
763 }
764 return result;
765 } else {
766 return false;
767 }
768 }
769
747 bool get_real_threats(const GameState *gamestate, Row row, File file, 770 bool get_real_threats(const GameState *gamestate, Row row, File file,
748 Color color, Move *threats, size_t *threatcount) { 771 Color color, Move *threats, size_t *threatcount) {
749 772
750 if (threatcount) { 773 if (threatcount) {
751 *threatcount = 0; 774 *threatcount = 0;
752 } 775 }
753 776
754 Move candidates[16]; 777 Move candidates[16];
755 size_t candidatecount; 778 size_t ccount;
756 if (get_threats(gamestate, row, file, color, candidates, &candidatecount)) { 779 if (get_threats(gamestate, row, file, color, candidates, &ccount)) {
757
758 bool result = false; 780 bool result = false;
759 File kingfile = 0; 781 for (size_t i = 0 ; i < ccount ; i++) {
760 Row kingrow = 0; 782 if (!is_pinned(gamestate, &candidates[i])) {
761 for (Row r = 0 ; r < 8 ; r++) {
762 for (File f = 0 ; f < 8 ; f++) {
763 if (gamestate->board[r][f] == (color|KING)) {
764 kingfile = f;
765 kingrow = r;
766 }
767 }
768 }
769
770 for (size_t i = 0 ; i < candidatecount ; i++) {
771 // TODO: check if we really need full-blown simulations here
772 GameState simulation = gamestate_copy_sim(gamestate);
773 Move simmove = candidates[i];
774 apply_move(&simulation, &simmove);
775 if (!is_covered(&simulation, kingrow, kingfile,
776 opponent_color(color))) {
777 result = true; 783 result = true;
778 if (threats && threatcount) { 784 if (threats && threatcount) {
779 threats[(*threatcount)++] = candidates[i]; 785 threats[(*threatcount)++] = candidates[i];
780 } 786 }
781 } 787 }
782 gamestate_cleanup(&simulation); 788 }
783 }
784
785 return result; 789 return result;
786 } else { 790 } else {
787 return false; 791 return false;
788 } 792 }
789 } 793 }

mercurial