pos_check(): add adjacent kings test
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user