src/chess/rules.c

changeset 167
fd1d3f0a7a73
parent 166
1a9b662bc201
child 168
663676cfef6e
equal deleted inserted replaced
166:1a9b662bc201 167:fd1d3f0a7a73
140 size_t ccount; 140 size_t ccount;
141 if (get_candidates(gamestate, move->torow, move->tofile, 141 if (get_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
145 if (candidates[i].piece == move->piece) { 146 if (candidates[i].piece == move->piece) {
146 ambpiece++; 147 ambpiece++;
147 if (candidates[i].fromrow == move->fromrow) { 148 if (candidates[i].fromrow == move->fromrow) {
148 ambrows++; 149 ambrows++;
149 } 150 }
546 break; 547 break;
547 default: 548 default:
548 return INVALID_MOVE_SYNTAX; 549 return INVALID_MOVE_SYNTAX;
549 } 550 }
550 551
551 /* cancel processing to save resources */ 552 return chkrules ? VALID_MOVE_SEMANTICS : RULES_VIOLATED;
552 if (!chkrules) { 553 }
553 return RULES_VIOLATED; 554
554 } 555 int validate_move(const GameState *gamestate, const Move *move) {
555 556 int result = validate_move_rules(gamestate, move);
557 if (result != VALID_MOVE_SEMANTICS) {
558 return result;
559 }
560
556 /* test if the move would expose our own king */ 561 /* test if the move would expose our own king */
557 GameState simulation = gamestate_copy_sim(gamestate); 562 GameState simulation = gamestate_copy_sim(gamestate);
558 Move simmove = *move; 563 Move simmove = *move;
559 apply_move(&simulation, &simmove); 564 apply_move(&simulation, &simmove);
560 Color piececolor = piece_color(move->piece); 565 Color piececolor = piece_color(move->piece);
568 kingfile = file; 573 kingfile = file;
569 kingrow = row; 574 kingrow = row;
570 } 575 }
571 } 576 }
572 } 577 }
573 int result = VALID_MOVE_SEMANTICS;
574 if (is_covered(&simulation, kingrow, kingfile, oppcolor)) { 578 if (is_covered(&simulation, kingrow, kingfile, oppcolor)) {
575 gamestate_cleanup(&simulation);
576 if (piece_type(move->piece) == KING) { 579 if (piece_type(move->piece) == KING) {
577 result = KING_MOVES_INTO_CHECK; 580 result = KING_MOVES_INTO_CHECK;
578 } else { 581 } else {
579 if (is_check_position(gamestate)) { 582 if (is_check_position(gamestate)) {
580 result = KING_IN_CHECK; 583 result = KING_IN_CHECK;
583 } 586 }
584 } 587 }
585 } 588 }
586 gamestate_cleanup(&simulation); 589 gamestate_cleanup(&simulation);
587 590
588 return result;
589 }
590
591 int validate_move(const GameState *gamestate, const Move *move) {
592 int result = validate_move_rules(gamestate, move);
593 if (result != VALID_MOVE_SEMANTICS) {
594 return result;
595 }
596
597 /* validate check and checkmate flags */ 591 /* validate check and checkmate flags */
598 int cocm = determine_check_or_checkmate(gamestate, move); 592 int cocm = determine_check_or_checkmate(gamestate, move);
599 if (cocm == 2) { 593 if (cocm == 2) {
600 if (!move->checkmate) { 594 if (!move->checkmate) {
601 return MISSING_CHECKMATE; 595 return MISSING_CHECKMATE;
607 } else if (move->checkmate) { 601 } else if (move->checkmate) {
608 return INVALID_CHECKMATE; 602 return INVALID_CHECKMATE;
609 } else if (move->check) { 603 } else if (move->check) {
610 return INVALID_CHECK; 604 return INVALID_CHECK;
611 } 605 }
612
613 606
614 return VALID_MOVE_SEMANTICS; 607 return VALID_MOVE_SEMANTICS;
615 } 608 }
616 609
617 Piece piece_at(const GameState *gamestate, Row row, File file) { 610 Piece piece_at(const GameState *gamestate, Row row, File file) {
673 666
674 bool get_threats(const GameState *gamestate, Row row, File file, 667 bool get_threats(const GameState *gamestate, Row row, File file,
675 Color color, Move *threats, size_t *threatcount) { 668 Color color, Move *threats, size_t *threatcount) {
676 669
677 /* simulate a capturing move on the target position */ 670 /* simulate a capturing move on the target position */
671 // TODO: this does NOT disregard the pin, as stated in the spec!
678 Color opcolor = opponent_color(color); 672 Color opcolor = opponent_color(color);
679 GameState simulation = gamestate_copy_sim(gamestate); 673 GameState simulation = gamestate_copy_sim(gamestate);
680 if (piece_color(piece_at(&simulation, row, file)) != opcolor) { 674 if (piece_color(piece_at(&simulation, row, file)) != opcolor) {
681 /* set a fake pawn if the field is not occupied by the opponent */ 675 /* set a fake pawn if the field is not occupied by the opponent */
682 piece_set(&simulation, row, file, mkpiece(PAWN, opcolor)); 676 piece_set(&simulation, row, file, mkpiece(PAWN, opcolor));

mercurial