src/chess/rules.c

changeset 64
4eda5df55f86
parent 63
611332453da0
child 66
f5cc75565f7c
equal deleted inserted replaced
63:611332453da0 64:4eda5df55f86
75 char *string = move->string; 75 char *string = move->string;
76 76
77 /* at least 8 characters should be available, wipe them out */ 77 /* at least 8 characters should be available, wipe them out */
78 memset(string, 0, 8); 78 memset(string, 0, 8);
79 79
80 /* special formats for castling */ 80 unsigned int idx;
81 if ((move->piece&PIECE_MASK) == KING && 81 if ((move->piece&PIECE_MASK) == KING &&
82 abs(move->tofile-move->fromfile) == 2) { 82 abs(move->tofile-move->fromfile) == 2) {
83 /* special formats for castling */
83 if (move->tofile==fileidx('c')) { 84 if (move->tofile==fileidx('c')) {
84 memcpy(string, "O-O-O", 5); 85 memcpy(string, "O-O-O", 5);
86 idx = 5;
85 } else { 87 } else {
86 memcpy(string, "O-O", 3); 88 memcpy(string, "O-O", 3);
87 } 89 idx = 3;
88 } 90 }
89 91 } else {
90 /* start by notating the piece character */ 92 /* start by notating the piece character */
91 string[0] = getpiecechr(move->piece); 93 string[0] = getpiecechr(move->piece);
92 int idx = string[0] ? 1 : 0; 94 idx = string[0] ? 1 : 0;
93 95
94 /* find out how many source information we do need */ 96 /* find out how many source information we do need */
95 uint8_t piece = move->piece & PIECE_MASK; 97 uint8_t piece = move->piece & PIECE_MASK;
96 if (piece == PAWN) { 98 if (piece == PAWN) {
99 if (move->capture) {
100 string[idx++] = filechr(move->fromfile);
101 }
102 } else if (piece != KING) {
103 /* resolve ambiguities, if any */
104 Move threats[16];
105 uint8_t threatcount;
106 get_real_threats(gamestate, move->torow, move->tofile,
107 move->piece&COLOR_MASK, threats, &threatcount);
108 if (threatcount > 1) {
109 int ambrows = 0, ambfiles = 0;
110 for (uint8_t i = 0 ; i < threatcount ; i++) {
111 if (threats[i].fromrow == move->fromrow) {
112 ambrows++;
113 }
114 if (threats[i].fromfile == move->fromfile) {
115 ambfiles++;
116 }
117 }
118 /* ambiguous row, name file */
119 if (ambrows > 1) {
120 string[idx++] = filechr(move->fromfile);
121 }
122 /* ambiguous file, name row */
123 if (ambfiles > 1) {
124 string[idx++] = filechr(move->fromrow);
125 }
126 }
127 }
128
129 /* capturing? */
97 if (move->capture) { 130 if (move->capture) {
98 string[idx++] = filechr(move->fromfile); 131 string[idx++] = 'x';
99 } 132 }
100 } else if (piece != KING) { 133
101 Move threats[16]; 134 /* destination */
102 uint8_t threatcount; 135 string[idx++] = filechr(move->tofile);
103 get_real_threats(gamestate, move->torow, move->tofile, 136 string[idx++] = rowchr(move->torow);
104 move->piece&COLOR_MASK, threats, &threatcount); 137
105 if (threatcount > 1) { 138 /* promotion? */
106 int ambrows = 0, ambfiles = 0; 139 if (move->promotion) {
107 for (uint8_t i = 0 ; i < threatcount ; i++) { 140 string[idx++] = '=';
108 if (threats[i].fromrow == move->fromrow) { 141 string[idx++] = getpiecechr(move->promotion);
109 ambrows++; 142 }
110 }
111 if (threats[i].fromfile == move->fromfile) {
112 ambfiles++;
113 }
114 }
115 /* ambiguous row, name file */
116 if (ambrows > 1) {
117 string[idx++] = filechr(move->fromfile);
118 }
119 /* ambiguous file, name row */
120 if (ambfiles > 1) {
121 string[idx++] = filechr(move->fromrow);
122 }
123 }
124 }
125
126 /* capturing? */
127 if (move->capture) {
128 string[idx++] = 'x';
129 }
130
131 /* destination */
132 string[idx++] = filechr(move->tofile);
133 string[idx++] = rowchr(move->torow);
134
135 /* promotion? */
136 if (move->promotion) {
137 string[idx++] = '=';
138 string[idx++] = getpiecechr(move->promotion);
139 } 143 }
140 144
141 /* check? */ 145 /* check? */
142 if (move->check) { 146 if (move->check) {
143 /* works only, if this function is called when applying the move */ 147 /* works only, if this function is called when applying the move */
454 Move candidates[32]; 458 Move candidates[32];
455 int candidatecount = 0; 459 int candidatecount = 0;
456 for (uint8_t r = 0 ; r < 8 ; r++) { 460 for (uint8_t r = 0 ; r < 8 ; r++) {
457 for (uint8_t f = 0 ; f < 8 ; f++) { 461 for (uint8_t f = 0 ; f < 8 ; f++) {
458 if ((gamestate->board[r][f] & COLOR_MASK) == color) { 462 if ((gamestate->board[r][f] & COLOR_MASK) == color) {
459 // non-capturing move 463 /* non-capturing move */
460 memset(&(candidates[candidatecount]), 0, sizeof(Move)); 464 memset(&(candidates[candidatecount]), 0, sizeof(Move));
461 candidates[candidatecount].piece = gamestate->board[r][f]; 465 candidates[candidatecount].piece = gamestate->board[r][f];
462 candidates[candidatecount].fromrow = r; 466 candidates[candidatecount].fromrow = r;
463 candidates[candidatecount].fromfile = f; 467 candidates[candidatecount].fromfile = f;
464 candidates[candidatecount].torow = row; 468 candidates[candidatecount].torow = row;
465 candidates[candidatecount].tofile = file; 469 candidates[candidatecount].tofile = file;
466 candidatecount++; 470 candidatecount++;
467 471
468 // capturing move 472 /* capturing move */
469 memcpy(&(candidates[candidatecount]), 473 memcpy(&(candidates[candidatecount]),
470 &(candidates[candidatecount-1]), sizeof(Move)); 474 &(candidates[candidatecount-1]), sizeof(Move));
471 candidates[candidatecount].capture = 1; 475 candidates[candidatecount].capture = 1;
472 candidatecount++; 476 candidatecount++;
473 } 477 }
570 if (get_threats(gamestate, move->torow, move->tofile, color, 574 if (get_threats(gamestate, move->torow, move->tofile, color,
571 threats, &threatcount)) { 575 threats, &threatcount)) {
572 576
573 int reason = INVALID_POSITION; 577 int reason = INVALID_POSITION;
574 578
575 // find threats for the specified position 579 /* find threats for the specified position */
576 for (uint8_t i = 0 ; i < threatcount ; i++) { 580 for (uint8_t i = 0 ; i < threatcount ; i++) {
577 if ((threats[i].piece & (PIECE_MASK | COLOR_MASK)) 581 if ((threats[i].piece & (PIECE_MASK | COLOR_MASK))
578 == move->piece && 582 == move->piece &&
579 (move->fromrow == POS_UNSPECIFIED || 583 (move->fromrow == POS_UNSPECIFIED ||
580 move->fromrow == threats[i].fromrow) && 584 move->fromrow == threats[i].fromrow) &&
582 move->fromfile == threats[i].fromfile)) { 586 move->fromfile == threats[i].fromfile)) {
583 587
584 if (threat) { 588 if (threat) {
585 return AMBIGUOUS_MOVE; 589 return AMBIGUOUS_MOVE;
586 } else { 590 } else {
587 // found threat is no real threat 591 /* found threat is no real threat */
588 if (is_pinned(gamestate, &(threats[i]))) { 592 if (is_pinned(gamestate, &(threats[i]))) {
589 reason = incheck?KING_IN_CHECK:PIECE_PINNED; 593 reason = incheck?KING_IN_CHECK:PIECE_PINNED;
590 } else { 594 } else {
591 threat = &(threats[i]); 595 threat = &(threats[i]);
592 } 596 }
593 } 597 }
594 } 598 }
595 } 599 }
596 600
597 // can't threaten specified position 601 /* can't threaten specified position */
598 if (!threat) { 602 if (!threat) {
599 return reason; 603 return reason;
600 } 604 }
601 605
602 memcpy(move, threat, sizeof(Move)); 606 memcpy(move, threat, sizeof(Move));

mercurial