diff options
| author | Scott Gasch <[email protected]> | 2026-09-16 08:02:21 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-09-16 08:02:21 -0700 |
| commit | 966a0ef4da9cf3911eb3da0533179199808717b4 (patch) | |
| tree | e09363b574215ef0d8996155a5ab24314db2dd69 /src/recogn.c | |
| parent | b91c8453f3fe21c8ccd3568923d8e39141c9c945 (diff) | |
Retire cPawns/cNonPawns piece-location lists in favor of bbPawns/bbPieces/cKingSq, and hoist two redundant TotalNonPawnCount POPCNT calls out of per-node hot loops.
POSITION no longer stores cPawns[2][8], cNonPawns[2][16], uPawnCount[2],
uNonPawnCount[2][8], or uWhiteSqBishopCount[2] -- every reader now goes
through PawnMaterial/TotalNonPawnCount/WhiteSqBishopCount/KingPosition
(chess.h), computed from the already-incrementally-maintained bbPawns/
bbPieces/cKingSq bitboards via a single -mpopcnt POPCNT instead of a
stored counter. move.c's make/unmake loses the list-swap-on-removal
bookkeeping entirely. GNUmakefile now passes -mpopcnt so the popcount
builtins actually compile to one instruction instead of clang's ~15-op
SWAR fallback.
Measured a small but real nps regression from the naive swap (search.c's
QSearch move-filter and eval.c's _EvalKing were each recomputing the same
TotalNonPawnCount sum on every candidate move / twice per node); hoisted
both to a single call per node instead. Net result across a same-code
self-play match: ~1541.5 knps candidate vs ~1505.7 knps head_reference.
A third hoist (FindEnprisePiece out of SelectBestWithHistory) was tried
and reverted -- its cache isn't actually loop-invariant within a node
(populated from inside Eval(), which doesn't run before every selection
call), caught by a DEBUG-build ASSERT before it landed.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/recogn.c')
| -rw-r--r-- | src/recogn.c | 256 |
1 files changed, 133 insertions, 123 deletions
diff --git a/src/recogn.c b/src/recogn.c index 32a618d..deb2285 100644 --- a/src/recogn.c +++ b/src/recogn.c @@ -23,6 +23,15 @@ Revision History: #include "chess.h" +// See eval.c's identical comment: routes this file's KBNK/KBKB +// adjacency-check bitboard-scan loops (called every node via +// RecognLookup in search.c) to the inlined +// FastCoorFromBitBoardRank8ToRank1 (chess.h) instead of the real +// out-of-line extern call. +#ifndef CROUTINES +#define CoorFromBitBoardRank8ToRank1 FastCoorFromBitBoardRank8ToRank1 +#endif + extern ULONG g_uIterateDepth; static COOR QUEENING_SQUARE_BY_COLOR_FILE[2][8] = { @@ -211,14 +220,14 @@ static FLAG if (!(p & PAWN)) { - if (pos->uPawnCount[uColor] > 0) return(FALSE); + if (FastCountBits(pos->bbPawns[uColor]) > 0) return(FALSE); } for (u = 0; u < ARRAY_LENGTH(q); u++) { if (!(p & q[u])) { - if (pos->uNonPawnCount[uColor][q[u]] > 0) return(FALSE); + if (FastCountBits(pos->bbPieces[uColor][q[u]]) > 0) return(FALSE); } } return(TRUE); @@ -276,8 +285,8 @@ Return value: ULONG uAdjacent; POSITION *pos = &ctx->sPosition; - ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && - (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT((TotalNonPawnCount(pos, WHITE) <= 3) && + (TotalNonPawnCount(pos, BLACK) <= 3)); ASSERT(_NothingBut(pos, BISHOP, WHITE)); ASSERT(_NothingBut(pos, BISHOP, BLACK)); @@ -285,11 +294,11 @@ Return value: // Recognize KBKB as a draw unless there's a cornered king (in // which case it may be a mate-in-1) // - if ((pos->uNonPawnCount[WHITE][0] == 2) && - (pos->uNonPawnCount[BLACK][0] == 2)) + if ((TotalNonPawnCount(pos, WHITE) == 2) && + (TotalNonPawnCount(pos, BLACK) == 2)) { - if ((CORNER_DISTANCE(pos->cNonPawns[WHITE][0]) != 0) && - (CORNER_DISTANCE(pos->cNonPawns[BLACK][0]) != 0)) + if ((CORNER_DISTANCE(KingPosition(pos, WHITE)) != 0) && + (CORNER_DISTANCE(KingPosition(pos, BLACK)) != 0)) { *piScore = 0; return(RECOGN_EXACT); @@ -300,8 +309,8 @@ Return value: // Otherwise we want to deal with KB+ vs lone K. KBKBB etc are // too hard to recognize. // - if ((pos->uNonPawnCount[WHITE][0] != 1) && - (pos->uNonPawnCount[BLACK][0] != 1)) + if ((TotalNonPawnCount(pos, WHITE) != 1) && + (TotalNonPawnCount(pos, BLACK) != 1)) { return(UNRECOGNIZED); } @@ -310,21 +319,21 @@ Return value: // If we get here then one side has no pieces (except the king). // uStrong = BLACK; - if (pos->uNonPawnCount[WHITE][0] > 1) + if (TotalNonPawnCount(pos, WHITE) > 1) { uStrong = WHITE; } - ASSERT(pos->uNonPawnCount[uStrong][0] > 1); - ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + ASSERT(TotalNonPawnCount(pos, uStrong) > 1); + ASSERT(TotalNonPawnCount(pos, FLIP(uStrong)) == 1); // // KB vs K is a draw, KB+ vs K is still a draw if all bishops are the // same color. // - uBishops = pos->uNonPawnCount[uStrong][BISHOP]; + uBishops = FastCountBits(pos->bbPieces[uStrong][BISHOP]); if ((uBishops == 1) || - (pos->uWhiteSqBishopCount[uStrong] == 0) || - (pos->uWhiteSqBishopCount[uStrong] == uBishops)) + (WhiteSqBishopCount(pos, uStrong) == 0) || + (WhiteSqBishopCount(pos, uStrong) == uBishops)) { *piScore = 0; return(RECOGN_EXACT); @@ -341,12 +350,16 @@ Return value: // move. Note: we allow the weak king to be adjacent to up to one // enemy bishop as long as it's the strong side's turn to move. // - cWeakKing = pos->cNonPawns[FLIP(uStrong)][0]; - ASSERT(DISTANCE(cWeakKing, pos->cNonPawns[uStrong][0]) > 1); + cWeakKing = KingPosition(pos, FLIP(uStrong)); + ASSERT(DISTANCE(cWeakKing, KingPosition(pos, uStrong)) > 1); uAdjacent = 0; - for (u = 1; u < pos->uNonPawnCount[uStrong][0]; u++) { - uAdjacent += (DISTANCE(cWeakKing, pos->cNonPawns[uStrong][u]) == 1); + BITBOARD bbPieces = NON_KING_PIECES_BB(pos, uStrong); + COOR c; + while (IS_ON_BOARD(c = CoorFromBitBoardRank8ToRank1(&bbPieces))) + { + uAdjacent += (DISTANCE(cWeakKing, c) == 1); + } } if (uAdjacent > 1) { @@ -357,9 +370,9 @@ Return value: // If it's the weak side's turn and the strong king is close // enough that the weak side may be stalemated, fail to recognize. // - ASSERT(IS_ON_BOARD(pos->cNonPawns[uStrong][0])); - ASSERT(IS_KING(pos->rgSquare[pos->cNonPawns[uStrong][0]].pPiece)); - u = DISTANCE(cWeakKing, pos->cNonPawns[uStrong][0]); + ASSERT(IS_ON_BOARD(KingPosition(pos, uStrong))); + ASSERT(IS_KING(pos->rgSquare[KingPosition(pos, uStrong)].pPiece)); + u = DISTANCE(cWeakKing, KingPosition(pos, uStrong)); ASSERT(u != 1); if (pos->uToMove != uStrong) { @@ -413,8 +426,8 @@ Return value: POSITION *pos = &ctx->sPosition; ULONG uStrong; - ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && - (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT((TotalNonPawnCount(pos, WHITE) <= 3) && + (TotalNonPawnCount(pos, BLACK) <= 3)); ASSERT(_NothingBut(pos, KNIGHT, WHITE)); ASSERT(_NothingBut(pos, KNIGHT, BLACK)); @@ -422,11 +435,11 @@ Return value: // KNKN is a draw unless someone has a K in the corner (in which case, // with the friend knight in the way, there's a possible mate) // - if ((pos->uNonPawnCount[WHITE][0] == 2) && - (pos->uNonPawnCount[BLACK][0] == 2)) + if ((TotalNonPawnCount(pos, WHITE) == 2) && + (TotalNonPawnCount(pos, BLACK) == 2)) { - if ((CORNER_DISTANCE(pos->cNonPawns[WHITE][0]) != 0) && - (CORNER_DISTANCE(pos->cNonPawns[BLACK][0]) != 0)) + if ((CORNER_DISTANCE(KingPosition(pos, WHITE)) != 0) && + (CORNER_DISTANCE(KingPosition(pos, BLACK)) != 0)) { *piScore = 0; return(RECOGN_EXACT); @@ -438,8 +451,8 @@ Return value: // KNNKN etc... unrecognized. Heinz says "exceptional wins possible for // any side by mates in seven or less moves." TODO: add this knowledge. // - if ((pos->uNonPawnCount[WHITE][0] != 1) || - (pos->uNonPawnCount[BLACK][0] != 1)) + if ((TotalNonPawnCount(pos, WHITE) != 1) || + (TotalNonPawnCount(pos, BLACK) != 1)) { return(UNRECOGNIZED); } @@ -448,20 +461,20 @@ Return value: // If we get here somebody has no pieces (except a lone king). // uStrong = WHITE; - if (pos->uNonPawnCount[BLACK][0] > 1) + if (TotalNonPawnCount(pos, BLACK) > 1) { uStrong = BLACK; } - ASSERT(pos->uNonPawnCount[uStrong][0] > 1); - ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + ASSERT(TotalNonPawnCount(pos, uStrong) > 1); + ASSERT(TotalNonPawnCount(pos, FLIP(uStrong)) == 1); // // Call KNNK a draw unless the weak K is on the edge of the board // where a checkmate is possible (e.g. 8/8/8/8/8/N2N4/4K3/2k5 b - -) // Everything else in here is a draw. // - ASSERT(pos->uNonPawnCount[uStrong][0] < 4); - if (ON_EDGE(pos->cNonPawns[FLIP(uStrong)][0])) + ASSERT(TotalNonPawnCount(pos, uStrong) < 4); + if (ON_EDGE(KingPosition(pos, FLIP(uStrong)))) { return(UNRECOGNIZED); } @@ -506,18 +519,18 @@ Return value: ULONG uAdjacent; POSITION *pos = &ctx->sPosition; - ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && - (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT((TotalNonPawnCount(pos, WHITE) <= 3) && + (TotalNonPawnCount(pos, BLACK) <= 3)); ASSERT(_NothingBut(pos, BISHOP | KNIGHT, WHITE)); ASSERT(_NothingBut(pos, BISHOP | KNIGHT, BLACK)); - if ((pos->uNonPawnCount[WHITE][0] > 1) && - (pos->uNonPawnCount[BLACK][0] > 1)) + if ((TotalNonPawnCount(pos, WHITE) > 1) && + (TotalNonPawnCount(pos, BLACK) > 1)) { // // Do not recognize stuff like KNNKB or KNKBB etc... // - if (pos->uNonPawnCount[WHITE][0] + pos->uNonPawnCount[BLACK][0] > 4) + if (TotalNonPawnCount(pos, WHITE) + TotalNonPawnCount(pos, BLACK) > 4) { return(UNRECOGNIZED); } @@ -526,10 +539,10 @@ Return value: // This is KNKB; unless someone's king is on the edge, // recognize a draw. // - ASSERT((pos->uNonPawnCount[WHITE][0] == 2) && - (pos->uNonPawnCount[BLACK][0] == 2)); - if (ON_EDGE(pos->cNonPawns[WHITE][0]) || - ON_EDGE(pos->cNonPawns[BLACK][0])) + ASSERT((TotalNonPawnCount(pos, WHITE) == 2) && + (TotalNonPawnCount(pos, BLACK) == 2)); + if (ON_EDGE(KingPosition(pos, WHITE)) || + ON_EDGE(KingPosition(pos, BLACK))) { return(UNRECOGNIZED); } @@ -541,13 +554,13 @@ Return value: // If we get here we are in a KBNK endgame. // uStrong = WHITE; - if (pos->uNonPawnCount[BLACK][0] > 1) + if (TotalNonPawnCount(pos, BLACK) > 1) { uStrong = BLACK; } - ASSERT(pos->uNonPawnCount[uStrong][0] > 1); - ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); - cWeakKing = pos->cNonPawns[FLIP(uStrong)][0]; + ASSERT(TotalNonPawnCount(pos, uStrong) > 1); + ASSERT(TotalNonPawnCount(pos, FLIP(uStrong)) == 1); + cWeakKing = KingPosition(pos, FLIP(uStrong)); ASSERT(IS_ON_BOARD(cWeakKing)); ASSERT(IS_KING(pos->rgSquare[cWeakKing].pPiece)); @@ -556,7 +569,7 @@ Return value: // lone king. It's possible for the lone king to trap it there // thus drawing the game. // - cKnight = pos->cNonPawns[uStrong][KNIGHT]; + cKnight = CoorOfSingleBit(pos->bbPieces[uStrong][KNIGHT]); if ((CORNER_DISTANCE(cKnight) == 0) && (DISTANCE(cWeakKing, cKnight) == 1)) { @@ -568,9 +581,13 @@ Return value: // piece. // uAdjacent = 0; - for (u = 1; u < pos->uNonPawnCount[uStrong][0]; u++) { - uAdjacent += (DISTANCE(pos->cNonPawns[uStrong][u], cWeakKing) == 1); + BITBOARD bbPieces = NON_KING_PIECES_BB(pos, uStrong); + COOR c; + while (IS_ON_BOARD(c = CoorFromBitBoardRank8ToRank1(&bbPieces))) + { + uAdjacent += (DISTANCE(c, cWeakKing) == 1); + } } if (uAdjacent) { @@ -582,9 +599,9 @@ Return value: // that there might be a stalemate if the weak side is on move and // on the edge. // - ASSERT(IS_ON_BOARD(pos->cNonPawns[uStrong][0])); - ASSERT(IS_KING(pos->rgSquare[pos->cNonPawns[uStrong][0]].pPiece)); - u = DISTANCE(cWeakKing, pos->cNonPawns[uStrong][0]); + ASSERT(IS_ON_BOARD(KingPosition(pos, uStrong))); + ASSERT(IS_KING(pos->rgSquare[KingPosition(pos, uStrong)].pPiece)); + u = DISTANCE(cWeakKing, KingPosition(pos, uStrong)); ASSERT(u != 1); if (pos->uToMove != uStrong) { @@ -600,7 +617,7 @@ Return value: // progress towards driving the weak king to the correct corner to // mate him. // - if (pos->uWhiteSqBishopCount[uStrong] > 0) + if (WhiteSqBishopCount(pos, uStrong) > 0) { uDist = WHITE_CORNER_DISTANCE(cWeakKing); } @@ -666,8 +683,8 @@ Return value: ULONG uStrong; POSITION *pos = &ctx->sPosition; - ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && - (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT((TotalNonPawnCount(pos, WHITE) <= 3) && + (TotalNonPawnCount(pos, BLACK) <= 3)); ASSERT(_NothingBut(pos, PAWN | KNIGHT, WHITE)); ASSERT(_NothingBut(pos, PAWN | KNIGHT, BLACK)); @@ -675,21 +692,21 @@ Return value: // Call the side with the knight "strong" // uStrong = WHITE; - if (pos->uNonPawnCount[BLACK][0] > 1) + if (TotalNonPawnCount(pos, BLACK) > 1) { uStrong = BLACK; } - ASSERT(pos->uNonPawnCount[uStrong][0] > 1); - ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + ASSERT(TotalNonPawnCount(pos, uStrong) > 1); + ASSERT(TotalNonPawnCount(pos, FLIP(uStrong)) == 1); // // Exhaustively proven correct only for exactly one knight and // exactly one pawn (see the comment above) -- also still exclude // K on the edge, per the original ON_EDGE reasoning. // - if ((pos->uNonPawnCount[uStrong][KNIGHT] != 1) || - (pos->uPawnCount[FLIP(uStrong)] != 1) || - (ON_EDGE(pos->cNonPawns[FLIP(uStrong)][0]))) + if ((FastCountBits(pos->bbPieces[uStrong][KNIGHT]) != 1) || + (FastCountBits(pos->bbPawns[FLIP(uStrong)]) != 1) || + (ON_EDGE(KingPosition(pos, FLIP(uStrong))))) { return(UNRECOGNIZED); } @@ -730,13 +747,11 @@ Return value: { ULONG uStrong; BITBOARD bb; - ULONG u; - COOR c; COOR cWeakKing; POSITION *pos = &ctx->sPosition; - ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && - (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT((TotalNonPawnCount(pos, WHITE) <= 3) && + (TotalNonPawnCount(pos, BLACK) <= 3)); ASSERT(_NothingBut(pos, PAWN | BISHOP, WHITE)); ASSERT(_NothingBut(pos, PAWN | BISHOP, BLACK)); @@ -744,36 +759,30 @@ Return value: // Call the side with bishop(s) "strong" // uStrong = WHITE; - if (pos->uNonPawnCount[BLACK][BISHOP] > 0) + if (FastCountBits(pos->bbPieces[BLACK][BISHOP]) > 0) { uStrong = BLACK; } - ASSERT(pos->uNonPawnCount[uStrong][0] > 1); - ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + ASSERT(TotalNonPawnCount(pos, uStrong) > 1); + ASSERT(TotalNonPawnCount(pos, FLIP(uStrong)) == 1); - cWeakKing = pos->cNonPawns[FLIP(uStrong)][0]; + cWeakKing = KingPosition(pos, FLIP(uStrong)); ASSERT(IS_ON_BOARD(cWeakKing)); ASSERT(IS_KING(pos->rgSquare[cWeakKing].pPiece)); // - // Construct a strong side bitboard of pawn locations + // Strong side's pawn locations // - bb = 0ULL; - for (u = 0; u < pos->uPawnCount[uStrong]; u++) - { - c = pos->cPawns[uStrong][u]; - ASSERT(IS_ON_BOARD(c)); - bb |= COOR_TO_BB(c); - } + bb = pos->bbPawns[uStrong]; - if ((pos->uNonPawnCount[BLACK][0] + pos->uPawnCount[BLACK] > 1) && - (pos->uNonPawnCount[WHITE][0] + pos->uPawnCount[WHITE] > 1)) + if ((TotalNonPawnCount(pos, BLACK) + FastCountBits(pos->bbPawns[BLACK]) > 1) && + (TotalNonPawnCount(pos, WHITE) + FastCountBits(pos->bbPawns[WHITE]) > 1)) { // // Neither side has a lone king. This is either KBKP+ or // KBP+KP+. // - if (pos->uPawnCount[uStrong] > 0) + if (FastCountBits(pos->bbPawns[uStrong]) > 0) { // // Strong side can maybe take an adjacent pawn and survive the @@ -791,15 +800,15 @@ Return value: if (uStrong == WHITE) { if (!(bb & ~BBFILE[A]) && - (pos->uWhiteSqBishopCount[WHITE] == 0) && + (WhiteSqBishopCount(pos, WHITE) == 0) && (DISTANCE(cWeakKing, A8) <= 1)) { goto at_best_draw_for_strong; } if (!(bb & ~BBFILE[H]) && - (pos->uWhiteSqBishopCount[WHITE] == - pos->uNonPawnCount[WHITE][BISHOP]) && + (WhiteSqBishopCount(pos, WHITE) == + FastCountBits(pos->bbPieces[WHITE][BISHOP])) && (DISTANCE(cWeakKing, H8) <= 1)) { goto at_best_draw_for_strong; @@ -808,15 +817,15 @@ Return value: else { if (!(bb & ~BBFILE[A]) && - (pos->uWhiteSqBishopCount[BLACK] == - pos->uNonPawnCount[BLACK][BISHOP]) && + (WhiteSqBishopCount(pos, BLACK) == + FastCountBits(pos->bbPieces[BLACK][BISHOP])) && (DISTANCE(cWeakKing, A1) <= 1)) { goto at_best_draw_for_strong; } if (!(bb & ~BBFILE[H]) && - (pos->uWhiteSqBishopCount[BLACK] == 0) && + (WhiteSqBishopCount(pos, BLACK) == 0) && (DISTANCE(cWeakKing, H1) <= 1)) { goto at_best_draw_for_strong; @@ -830,7 +839,7 @@ Return value: // Strong side has no pawns... there's a mate-in-1 here if // the weak king is stuck in the corner. // - if ((pos->uNonPawnCount[uStrong][BISHOP] > 1) || + if ((FastCountBits(pos->bbPieces[uStrong][BISHOP]) > 1) || (CORNER_DISTANCE(cWeakKing) == 0)) { return(UNRECOGNIZED); @@ -844,20 +853,20 @@ Return value: // KBPK: make sure the bishop is the right color. This time // there is no need to check for on-move. // - ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); - ASSERT(pos->uNonPawnCount[uStrong][0] > 1); + ASSERT(TotalNonPawnCount(pos, FLIP(uStrong)) == 1); + ASSERT(TotalNonPawnCount(pos, uStrong) > 1); if (uStrong == WHITE) { if (!(bb & ~BBFILE[A]) && - (pos->uWhiteSqBishopCount[WHITE] == 0) && + (WhiteSqBishopCount(pos, WHITE) == 0) && (DISTANCE(cWeakKing, A8) <= 1)) { goto draw; } if (!(bb & ~BBFILE[H]) && - (pos->uWhiteSqBishopCount[WHITE] == - pos->uNonPawnCount[WHITE][BISHOP]) && + (WhiteSqBishopCount(pos, WHITE) == + FastCountBits(pos->bbPieces[WHITE][BISHOP])) && (DISTANCE(cWeakKing, H8) <= 1)) { goto draw; @@ -866,14 +875,14 @@ Return value: else { if (!(bb & ~BBFILE[A]) && - (pos->uWhiteSqBishopCount[BLACK] == - pos->uNonPawnCount[BLACK][BISHOP]) && + (WhiteSqBishopCount(pos, BLACK) == + FastCountBits(pos->bbPieces[BLACK][BISHOP])) && (DISTANCE(cWeakKing, A1) <= 1)) { goto draw; } if (!(bb & ~BBFILE[H]) && - (pos->uWhiteSqBishopCount[BLACK] == 0) && + (WhiteSqBishopCount(pos, BLACK) == 0) && (DISTANCE(cWeakKing, H1) <= 1)) { goto draw; @@ -983,6 +992,7 @@ Return value: } +// BUG: 7k/8/5KP1/8/8/8/8/8 w - - static ULONG _RecognizeKPK(IN SEARCHER_THREAD_CONTEXT *ctx, IN OUT SCORE *piScore) @@ -1012,8 +1022,8 @@ Return value: PAWN_HASH_ENTRY *pHash; POSITION *pos = &ctx->sPosition; - ASSERT(pos->uNonPawnCount[WHITE][0] == 1); - ASSERT(pos->uNonPawnCount[BLACK][0] == 1); + ASSERT(TotalNonPawnCount(pos, WHITE) == 1); + ASSERT(TotalNonPawnCount(pos, BLACK) == 1); ASSERT(_NothingBut(pos, PAWN, WHITE)); ASSERT(_NothingBut(pos, PAWN, BLACK)); @@ -1064,7 +1074,7 @@ Return value: // // No one has a winning passer or we did not find the hash entry. // - if ((pos->uPawnCount[WHITE] > 0) && (pos->uPawnCount[BLACK] > 0)) + if ((FastCountBits(pos->bbPawns[WHITE]) > 0) && (FastCountBits(pos->bbPawns[BLACK]) > 0)) { return(UNRECOGNIZED); } @@ -1076,15 +1086,15 @@ Return value: // draw for the weak side. // uStrong = WHITE; - if (pos->uPawnCount[WHITE] == 0) + if (FastCountBits(pos->bbPawns[WHITE]) == 0) { uStrong = BLACK; } - ASSERT(pos->uPawnCount[uStrong] > 0); + ASSERT(FastCountBits(pos->bbPawns[uStrong]) > 0); uWeak = FLIP(uStrong); - ASSERT(pos->uPawnCount[uWeak] == 0); + ASSERT(FastCountBits(pos->bbPawns[uWeak]) == 0); - if (pos->uPawnCount[uStrong] > 1) + if (FastCountBits(pos->bbPawns[uStrong]) > 1) { *piScore = 0; if (pos->uToMove == uStrong) @@ -1099,8 +1109,8 @@ Return value: // sophisticated analysis here to spot winning KPK // configurations earlier by using "critical squares" // - ASSERT(pos->uPawnCount[uStrong] == 1); - cPawn = pos->cPawns[uStrong][0]; + ASSERT(FastCountBits(pos->bbPawns[uStrong]) == 1); + cPawn = CoorOfSingleBit(pos->bbPawns[uStrong]); ASSERT(IS_ON_BOARD(cPawn)); ASSERT(IS_PAWN(pos->rgSquare[cPawn].pPiece)); @@ -1108,9 +1118,9 @@ Return value: // Step 1: the strong king must be closer to the pawn than // the weak king. // - uDist[uStrong] = DISTANCE(pos->cNonPawns[uStrong][0], cPawn); + uDist[uStrong] = DISTANCE(KingPosition(pos, uStrong), cPawn); ASSERT((1 <= uDist[uStrong]) && (uDist[uStrong] <= 7)); - uDist[uWeak] = DISTANCE(pos->cNonPawns[uWeak][0], cPawn); + uDist[uWeak] = DISTANCE(KingPosition(pos, uWeak), cPawn); ASSERT((1 <= uDist[uWeak]) && (uDist[uWeak] <= 7)); if (uDist[uStrong] <= uDist[uWeak]) { @@ -1121,10 +1131,10 @@ Return value: _GetPassersCriticalSquares(uStrong, cPawn, cCritical); for (u = 0; u < 3; u++) { - uDist[uStrong] = DISTANCE(pos->cNonPawns[uStrong][0], + uDist[uStrong] = DISTANCE(KingPosition(pos, uStrong), cCritical[u]); ASSERT((0 <= uDist[uStrong]) && (uDist[uStrong] <= 7)); - uDist[uWeak] = DISTANCE(pos->cNonPawns[uWeak][0], + uDist[uWeak] = DISTANCE(KingPosition(pos, uWeak), cCritical[u]); // @@ -1333,19 +1343,19 @@ Return value: // // Try interior node recognizers // - if ((pos->uNonPawnCount[WHITE][0] <= 3) && - (pos->uNonPawnCount[BLACK][0] <= 3)) + if ((TotalNonPawnCount(pos, WHITE) <= 3) && + (TotalNonPawnCount(pos, BLACK) <= 3)) { - uSig[BLACK] = _MakeMaterialSig((pos->uPawnCount[BLACK] > 0), - (pos->uNonPawnCount[BLACK][KNIGHT] > 0), - (pos->uNonPawnCount[BLACK][BISHOP] > 0), - (pos->uNonPawnCount[BLACK][ROOK] > 0), - (pos->uNonPawnCount[BLACK][QUEEN] > 0)); - uSig[WHITE] = _MakeMaterialSig((pos->uPawnCount[WHITE] > 0), - (pos->uNonPawnCount[WHITE][KNIGHT] > 0), - (pos->uNonPawnCount[WHITE][BISHOP] > 0), - (pos->uNonPawnCount[WHITE][ROOK] > 0), - (pos->uNonPawnCount[WHITE][QUEEN] > 0)); + uSig[BLACK] = _MakeMaterialSig((FastCountBits(pos->bbPawns[BLACK]) > 0), + (FastCountBits(pos->bbPieces[BLACK][KNIGHT]) > 0), + (FastCountBits(pos->bbPieces[BLACK][BISHOP]) > 0), + (FastCountBits(pos->bbPieces[BLACK][ROOK]) > 0), + (FastCountBits(pos->bbPieces[BLACK][QUEEN]) > 0)); + uSig[WHITE] = _MakeMaterialSig((FastCountBits(pos->bbPawns[WHITE]) > 0), + (FastCountBits(pos->bbPieces[WHITE][KNIGHT]) > 0), + (FastCountBits(pos->bbPieces[WHITE][BISHOP]) > 0), + (FastCountBits(pos->bbPieces[WHITE][ROOK]) > 0), + (FastCountBits(pos->bbPieces[WHITE][QUEEN]) > 0)); pRec = g_pRecognizers[RECOGN_INDEX(uSig[WHITE], uSig[BLACK])]; if (NULL != pRec) { |
