Wed, 29 Aug 2018 15:12:24 +0200
fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
src/chess/rules.c | file | annotate | diff | comparison | revisions | |
src/terminal-chess.h | file | annotate | diff | comparison | revisions |
--- a/src/chess/rules.c Wed Aug 29 14:01:41 2018 +0200 +++ b/src/chess/rules.c Wed Aug 29 15:12:24 2018 +0200 @@ -35,6 +35,7 @@ static GameState gamestate_copy_sim(GameState *gamestate) { GameState simulation = *gamestate; + simulation.movecount = 0; /* simulations do not count moves */ if (simulation.lastmove) { MoveList *lastmovecopy = malloc(sizeof(MoveList)); *lastmovecopy = *(simulation.lastmove); @@ -70,9 +71,9 @@ }; } -/* MUST be called IMMEDIATLY after applying a move to work correctly */ +/* MUST be called BEFORE applying a move to work correctly */ static void format_move(GameState *gamestate, Move *move) { - char *string = move->string; + char *string = &(move->string[0]); /* at least 8 characters should be available, wipe them out */ memset(string, 0, 8); @@ -103,25 +104,34 @@ /* resolve ambiguities, if any */ Move threats[16]; uint8_t threatcount; - get_real_threats(gamestate, move->torow, move->tofile, - move->piece&COLOR_MASK, threats, &threatcount); - if (threatcount > 1) { - int ambrows = 0, ambfiles = 0; + if (get_threats(gamestate, move->torow, move->tofile, + move->piece&COLOR_MASK, threats, &threatcount)) { + unsigned int ambrows = 0, ambfiles = 0, ambpiece = 0; for (uint8_t i = 0 ; i < threatcount ; i++) { - if (threats[i].fromrow == move->fromrow) { - ambrows++; - } - if (threats[i].fromfile == move->fromfile) { - ambfiles++; + if (threats[i].piece == move->piece) { + ambpiece++; + if (threats[i].fromrow == move->fromrow) { + ambrows++; + } + if (threats[i].fromfile == move->fromfile) { + ambfiles++; + } } } - /* ambiguous row, name file */ - if (ambrows > 1) { + /* neither file, nor row are ambiguous, name file */ + if (ambpiece > 1 && ambrows == 1 && ambfiles == 1) { + /* this is most likely the case with Knights + * in diagonal opposition */ string[idx++] = filechr(move->fromfile); - } - /* ambiguous file, name row */ - if (ambfiles > 1) { - string[idx++] = filechr(move->fromrow); + } else { + /* ambiguous row, name file */ + if (ambrows > 1) { + string[idx++] = filechr(move->fromfile); + } + /* ambiguous file, name row */ + if (ambfiles > 1) { + string[idx++] = filechr(move->fromrow); + } } } } @@ -144,7 +154,7 @@ /* check? */ if (move->check) { - /* works only, if this function is called when applying the move */ + // TODO: does not work, because checkmate is not set when format_move is called string[idx++] = gamestate->checkmate?'#':'+'; } } @@ -207,6 +217,13 @@ } static void apply_move_impl(GameState *gamestate, Move *move, _Bool simulate) { + /* format move before moving (s.t. ambiguities can be resolved) */ + if (!simulate) { + if (!move->string[0]) { + format_move(gamestate, move); + } + } + uint8_t piece = move->piece & PIECE_MASK; uint8_t color = move->piece & COLOR_MASK; @@ -239,7 +256,6 @@ /* castling */ if (piece == KING && move->fromfile == fileidx('e')) { - if (move->tofile == fileidx('g')) { gamestate->board[move->torow][fileidx('h')] = 0; gamestate->board[move->torow][fileidx('f')] = color|ROOK; @@ -248,12 +264,7 @@ gamestate->board[move->torow][fileidx('d')] = color|ROOK; } } - - if (!simulate) { - if (!move->string[0]) { - format_move(gamestate, move); - } - } + /* add move, even in simulation (checkmate test needs it) */ addmove(gamestate, move); }