-
- Result classify_btm(const KPKPosition &p) {
-
- // If one move leads to a position classified as RESULT_DRAW, the result
- // of the current position is RESULT_DRAW. If all moves lead to positions
- // classified as RESULT_WIN, the current position is classified as
- // RESULT_LOSS. Otherwise, the current position is classified as
- // RESULT_UNKNOWN.
-
- bool unknownFound = false;
- Bitboard b;
- Square s;
-
- // King moves
- b = p.bk_attacks();
- while(b) {
- s = pop_1st_bit(&b);
- switch(Bitbase[compute_index(p.whiteKingSquare, s, p.pawnSquare,
- WHITE)]) {
- case RESULT_DRAW:
- return RESULT_DRAW;
-
- case RESULT_UNKNOWN:
- unknownFound = true;
- break;
-
- case RESULT_WIN: case RESULT_INVALID:
- break;
-
- default:
- assert(false);
- }
+ template<Color Us>
+ Result KPKPosition::classify(const std::vector<KPKPosition>& db) {
+
+ // White to Move: If one move leads to a position classified as WIN, the result
+ // of the current position is WIN. If all moves lead to positions classified
+ // as DRAW, the current position is classified DRAW otherwise the current
+ // position is classified as UNKNOWN.
+ //
+ // Black to Move: If one move leads to a position classified as DRAW, the result
+ // of the current position is DRAW. If all moves lead to positions classified
+ // as WIN, the position is classified WIN otherwise the current position is
+ // classified UNKNOWN.
+
+ Result r = INVALID;
+ Bitboard b = StepAttacksBB[KING][Us == WHITE ? wksq : bksq];
+
+ while (b)
+ r |= Us == WHITE ? db[index(~Us, bksq, pop_lsb(&b), psq)]
+ : db[index(~Us, pop_lsb(&b), wksq, psq)];
+
+ if (Us == WHITE && rank_of(psq) < RANK_7)
+ {
+ Square s = psq + DELTA_N;
+ r |= db[index(BLACK, bksq, wksq, s)]; // Single push
+
+ if (rank_of(s) == RANK_3 && s != wksq && s != bksq)
+ r |= db[index(BLACK, bksq, wksq, s + DELTA_N)]; // Double push