int sSearcher::RecognizeDraw(sPosition *p) { if ( p->pcCount[WHITE][P] == 0 && p->pcCount[BLACK][P] == 0 ) { if ( p->pieceMat[WHITE] + p->pieceMat[BLACK] < 400 ) { if ( !IllegalPosition(p) ) return 1; } // bare kings or Km vs K if (p->pieceMat[WHITE] < 400 && p->pieceMat[BLACK] < 400 && (bbPc(p, WHITE, K) & bbRim) == 0 && (bbPc(p, BLACK, K) & bbRim) == 0 ) { if ( !IllegalPosition(p) ) return 1; } // Km vs Km; just in case we ensure that neither king is on the rim } // no pawns if (p->pieceMat[WHITE] == 0 && p->pieceMat[BLACK] == 0) { if (p->pcCount[WHITE][P] == 1 && p->pcCount[BLACK][P] == 0) return KPKdraw(p, WHITE); // exactly one white pawn if (p->pcCount[BLACK][P] == 1 && p->pcCount[WHITE][P] == 0) return KPKdraw(p, BLACK); // exactly one black pawn } // pawns only return 0; }
int IsDraw(POS *p) { static const U64 bbRim = { FILE_A_BB | FILE_H_BB | RANK_1_BB | RANK_8_BB }; // Draw by 50 move rule if (p->rev_moves > 100) return 1; // Draw by repetition for (int i = 4; i <= p->rev_moves; i += 2) if (p->hash_key == p->rep_list[p->head - i]) return 1; // With no major pieces on the board, we have some heuristic draws to consider if (p->cnt[WC][Q] + p->cnt[BC][Q] + p->cnt[WC][R] + p->cnt[BC][R] == 0) { // Draw by insufficient material (bare kings or Km vs K) if (!Illegal(p)) { if (p->cnt[WC][P] + p->cnt[BC][P] == 0) { if (p->cnt[WC][N] + p->cnt[BC][N] + p->cnt[WC][B] + p->cnt[BC][B] <= 1) return 0; // KmK } } // Trivially drawn KPK endgames if (p->cnt[WC][N] + p->cnt[BC][N] + p->cnt[WC][B] + p->cnt[BC][B] == 0) { if (p->cnt[WC][P] + p->cnt[BC][P] == 1) { if (p->cnt[WC][P] == 1 && p->cnt[BC][P] == 0) return KPKdraw(p, WC); // exactly one white pawn if (p->cnt[BC][P] == 1 && p->cnt[WC][P] == 0) return KPKdraw(p, BC); // exactly one black pawn } } // pawns only } return 0; // default: no draw }