src/chess/rules.c

changeset 80
b980a7192b5a
parent 78
ceb9197b3c6d
equal deleted inserted replaced
79:ffd452cf05ff 80:b980a7192b5a
205 case 'K': return KING; 205 case 'K': return KING;
206 default: return 0; 206 default: return 0;
207 } 207 }
208 } 208 }
209 209
210 static void apply_move_impl(GameState *gamestate, Move *move, _Bool simulate) { 210 static void apply_move_impl(GameState *gamestate, Move *move, bool simulate) {
211 /* format move before moving (s.t. ambiguities can be resolved) */ 211 /* format move before moving (s.t. ambiguities can be resolved) */
212 if (!simulate) { 212 if (!simulate) {
213 if (!move->string[0]) { 213 if (!move->string[0]) {
214 format_move(gamestate, move); 214 format_move(gamestate, move);
215 } 215 }
292 (mdst(gamestate->board, move) != 0 && !move->capture)) { 292 (mdst(gamestate->board, move) != 0 && !move->capture)) {
293 return INVALID_MOVE_SYNTAX; 293 return INVALID_MOVE_SYNTAX;
294 } 294 }
295 295
296 /* validate individual rules */ 296 /* validate individual rules */
297 _Bool chkrules; 297 bool chkrules;
298 switch (move->piece & PIECE_MASK) { 298 switch (move->piece & PIECE_MASK) {
299 case PAWN: 299 case PAWN:
300 chkrules = pawn_chkrules(gamestate, move) && 300 chkrules = pawn_chkrules(gamestate, move) &&
301 !pawn_isblocked(gamestate, move); 301 !pawn_isblocked(gamestate, move);
302 break; 302 break;
378 move->check = get_threats(&simulation, opkingrow, opkingfile, 378 move->check = get_threats(&simulation, opkingrow, opkingfile,
379 piececolor, threats, &threatcount); 379 piececolor, threats, &threatcount);
380 380
381 if (move->check) { 381 if (move->check) {
382 /* determine possible escape fields */ 382 /* determine possible escape fields */
383 _Bool canescape = 0; 383 bool canescape = false;
384 for (int dr = -1 ; dr <= 1 && !canescape ; dr++) { 384 for (int dr = -1 ; dr <= 1 && !canescape ; dr++) {
385 for (int df = -1 ; df <= 1 && !canescape ; df++) { 385 for (int df = -1 ; df <= 1 && !canescape ; df++) {
386 if (!(dr == 0 && df == 0) && 386 if (!(dr == 0 && df == 0) &&
387 isidx(opkingrow + dr) && isidx(opkingfile + df)) { 387 isidx(opkingrow + dr) && isidx(opkingfile + df)) {
388 388
453 gamestate_cleanup(&simulation); 453 gamestate_cleanup(&simulation);
454 454
455 return VALID_MOVE_SEMANTICS; 455 return VALID_MOVE_SEMANTICS;
456 } 456 }
457 457
458 _Bool get_threats(GameState *gamestate, uint8_t row, uint8_t file, 458 bool get_threats(GameState *gamestate, uint8_t row, uint8_t file,
459 uint8_t color, Move *threats, uint8_t *threatcount) { 459 uint8_t color, Move *threats, uint8_t *threatcount) {
460 Move candidates[32]; 460 Move candidates[32];
461 int candidatecount = 0; 461 int candidatecount = 0;
462 for (uint8_t r = 0 ; r < 8 ; r++) { 462 for (uint8_t r = 0 ; r < 8 ; r++) {
463 for (uint8_t f = 0 ; f < 8 ; f++) { 463 for (uint8_t f = 0 ; f < 8 ; f++) {
483 if (threatcount) { 483 if (threatcount) {
484 *threatcount = 0; 484 *threatcount = 0;
485 } 485 }
486 486
487 487
488 _Bool result = 0; 488 bool result = false;
489 489
490 for (int i = 0 ; i < candidatecount ; i++) { 490 for (int i = 0 ; i < candidatecount ; i++) {
491 if (validate_move_rules(gamestate, &(candidates[i])) 491 if (validate_move_rules(gamestate, &(candidates[i]))
492 == VALID_MOVE_SEMANTICS) { 492 == VALID_MOVE_SEMANTICS) {
493 result = 1; 493 result = true;
494 if (threats && threatcount) { 494 if (threats && threatcount) {
495 threats[(*threatcount)++] = candidates[i]; 495 threats[(*threatcount)++] = candidates[i];
496 } 496 }
497 } 497 }
498 } 498 }
499 499
500 return result; 500 return result;
501 } 501 }
502 502
503 _Bool is_pinned(GameState *gamestate, Move *move) { 503 bool is_pinned(GameState *gamestate, Move *move) {
504 uint8_t color = move->piece & COLOR_MASK; 504 uint8_t color = move->piece & COLOR_MASK;
505 505
506 GameState simulation = gamestate_copy_sim(gamestate); 506 GameState simulation = gamestate_copy_sim(gamestate);
507 Move simmove = *move; 507 Move simmove = *move;
508 apply_move(&simulation, &simmove); 508 apply_move(&simulation, &simmove);
515 kingrow = row; 515 kingrow = row;
516 } 516 }
517 } 517 }
518 } 518 }
519 519
520 _Bool covered = is_covered(&simulation, 520 bool covered = is_covered(&simulation,
521 kingrow, kingfile, opponent_color(color)); 521 kingrow, kingfile, opponent_color(color));
522 gamestate_cleanup(&simulation); 522 gamestate_cleanup(&simulation);
523 523
524 return covered; 524 return covered;
525 } 525 }
526 526
527 _Bool get_real_threats(GameState *gamestate, uint8_t row, uint8_t file, 527 bool get_real_threats(GameState *gamestate, uint8_t row, uint8_t file,
528 uint8_t color, Move *threats, uint8_t *threatcount) { 528 uint8_t color, Move *threats, uint8_t *threatcount) {
529 529
530 if (threatcount) { 530 if (threatcount) {
531 *threatcount = 0; 531 *threatcount = 0;
532 } 532 }
533 533
534 Move candidates[16]; 534 Move candidates[16];
535 uint8_t candidatecount; 535 uint8_t candidatecount;
536 if (get_threats(gamestate, row, file, color, candidates, &candidatecount)) { 536 if (get_threats(gamestate, row, file, color, candidates, &candidatecount)) {
537 537
538 _Bool result = 0; 538 bool result = false;
539 uint8_t kingfile = 0, kingrow = 0; 539 uint8_t kingfile = 0, kingrow = 0;
540 for (uint8_t row = 0 ; row < 8 ; row++) { 540 for (uint8_t row = 0 ; row < 8 ; row++) {
541 for (uint8_t file = 0 ; file < 8 ; file++) { 541 for (uint8_t file = 0 ; file < 8 ; file++) {
542 if (gamestate->board[row][file] == (color|KING)) { 542 if (gamestate->board[row][file] == (color|KING)) {
543 kingfile = file; 543 kingfile = file;
550 GameState simulation = gamestate_copy_sim(gamestate); 550 GameState simulation = gamestate_copy_sim(gamestate);
551 Move simmove = candidates[i]; 551 Move simmove = candidates[i];
552 apply_move(&simulation, &simmove); 552 apply_move(&simulation, &simmove);
553 if (!is_covered(&simulation, kingrow, kingfile, 553 if (!is_covered(&simulation, kingrow, kingfile,
554 opponent_color(color))) { 554 opponent_color(color))) {
555 result = 1; 555 result = true;
556 if (threats && threatcount) { 556 if (threats && threatcount) {
557 threats[(*threatcount)++] = candidates[i]; 557 threats[(*threatcount)++] = candidates[i];
558 } 558 }
559 } 559 }
560 } 560 }
561 561
562 return result; 562 return result;
563 } else { 563 } else {
564 return 0; 564 return false;
565 } 565 }
566 } 566 }
567 567
568 static int getlocation(GameState *gamestate, Move *move) { 568 static int getlocation(GameState *gamestate, Move *move) {
569 569
570 uint8_t color = move->piece & COLOR_MASK; 570 uint8_t color = move->piece & COLOR_MASK;
571 uint8_t piece = move->piece & PIECE_MASK; 571 uint8_t piece = move->piece & PIECE_MASK;
572 _Bool incheck = gamestate->lastmove?gamestate->lastmove->move.check:0; 572 bool incheck = gamestate->lastmove?gamestate->lastmove->move.check:false;
573 573
574 Move threats[16], *threat = NULL; 574 Move threats[16], *threat = NULL;
575 uint8_t threatcount; 575 uint8_t threatcount;
576 576
577 if (get_threats(gamestate, move->torow, move->tofile, color, 577 if (get_threats(gamestate, move->torow, move->tofile, color,
743 } else { 743 } else {
744 return INVALID_MOVE_SYNTAX; 744 return INVALID_MOVE_SYNTAX;
745 } 745 }
746 } 746 }
747 747
748 _Bool is_protected(GameState *gamestate, uint8_t row, uint8_t file, 748 bool is_protected(GameState *gamestate, uint8_t row, uint8_t file,
749 uint8_t color) { 749 uint8_t color) {
750 750
751 Move threats[16]; 751 Move threats[16];
752 uint8_t threatcount; 752 uint8_t threatcount;
753 if (get_real_threats(gamestate, row, file, color, threats, &threatcount)) { 753 if (get_real_threats(gamestate, row, file, color, threats, &threatcount)) {
754 for (int i = 0 ; i < threatcount ; i++) { 754 for (int i = 0 ; i < threatcount ; i++) {
755 if (threats[i].piece != (color|KING)) { 755 if (threats[i].piece != (color|KING)) {
756 return 1; 756 return true;
757 } 757 }
758 } 758 }
759 return 0; 759 return false;
760 } else { 760 } else {
761 return 0; 761 return false;
762 } 762 }
763 } 763 }
764 764
765 uint16_t remaining_movetime(GameInfo *gameinfo, GameState *gamestate, 765 uint16_t remaining_movetime(GameInfo *gameinfo, GameState *gamestate,
766 uint8_t color) { 766 uint8_t color) {

mercurial