pos_check(): add adjacent kings test

This commit is contained in:
2024-03-11 16:11:19 +01:00
parent 890cb05296
commit b7fdcca66d

View File

@@ -147,41 +147,41 @@ bitboard_t pos_pinners(const pos_t *pos, const color_t color)
} }
/** /**
* pos_check() - extensive position consistenci check. * pos_check() - extensive position consistency check.
* @pos: &position * @pos: &position
* @strict: if not zero, call bug_on() on any error. * @strict: if true, call bug_on() on any error.
* *
* Check (hopefully) if position is valid: * Perform some validity check on position @pos:
* - pawns on first or 8th rank * - pawns on 1st or 8th rank
* - number of pawns per color > 8 * - number of pawns > 8 (per color)
* - total number of pieces per color > 16 or zero * - total number of pieces > 16 or zero (per color)
* - number of kings per color != 1 * - number of kings != 1 (per color)
* - discrepancy between bitboards per piece and ALL_PIECES per color * - discrepancy between board and king (per color)
* - discrepancy between bitboards and board * - discrepancy between piece bitboards and ALL_PIECES bitboards (per color)
* - side-to-move already checking opponent king. * - discrepancy between bitboards and board (per color)
* - side to move in check more than twice * - side-to-move already checking opponent king
* - side-to-move in check more than twice
* - kings distance is 1
* *
* In case of errors, and @abort is true, @bug_on() is called, and program will * In case of errors, and @strict is true, @bug_on() is called, and program will
* be terminated. * be terminated.
* This function should be called with @abort == 0 during initialization phase * This function should be called with @strict == false during initialization phase
* (eg after fen parsing), and with @abort != 0 otherwise (as we have some data * (eg after fen parsing), and with @strict == true otherwise (as we have some data
* corruption). * corruption).
* *
* TODO: add more checks: * TODO: add more checks:
* - kings attacking each other * - kings attacking each other
* *
* @Return: 0 if no error detected * @Return: Number of detected error (only if @strict is false).
* the number of detected error if @abort == 0.
* this function does not return if @abort != 0 and errors are found.
*/ */
int pos_check(const pos_t *pos, const int fatal) int pos_check(const pos_t *pos, const bool strict)
{ {
int n, count = 0, bbcount = 0, error = 0; int n, count = 0, bbcount = 0, error = 0;
bitboard_t tmp;
/* pawns on 1st ot 8th rank */ /* pawns on 1st ot 8th rank */
n = popcount64((pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) & tmp = (pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) & (RANK_1bb | RANK_8bb);
(RANK_1bb | RANK_8bb)); error += warn_on(tmp);
error += warn_on(n != 0);
for (color_t color = WHITE; color <= BLACK; ++color) { for (color_t color = WHITE; color <= BLACK; ++color) {
/* pawn count */ /* pawn count */
@@ -190,6 +190,8 @@ int pos_check(const pos_t *pos, const int fatal)
/* king count */ /* king count */
n = popcount64(pos->bb[color][KING]); n = popcount64(pos->bb[color][KING]);
error += warn_on(n != 1); error += warn_on(n != 1);
/* king mismatch with board */
error += warn_on(PIECE(pos->board[pos->king[color]]) != KING);
/* pieces count */ /* pieces count */
n = popcount64(pos->bb[color][ALL_PIECES]); n = popcount64(pos->bb[color][ALL_PIECES]);
error += warn_on(n == 0 || n > 16); error += warn_on(n == 0 || n > 16);
@@ -212,8 +214,10 @@ int pos_check(const pos_t *pos, const int fatal)
error += warn_on(pos_checkers(pos, OPPONENT(pos->turn))); error += warn_on(pos_checkers(pos, OPPONENT(pos->turn)));
/* is color to play in check more than twice ? */ /* is color to play in check more than twice ? */
error += warn_on(popcount64(pos_checkers(pos, OPPONENT(pos->turn))) > 2); error += warn_on(popcount64(pos_checkers(pos, OPPONENT(pos->turn))) > 2);
/* kings distance is less than 2 */
error += warn_on(sq_dist(pos->king[WHITE], pos->king[BLACK]) < 2);
bug_on(fatal && error); bug_on(strict && error);
return error; return error;
} }