void sEvaluator::EvalPawnCenter(sPosition *p, int side) { int oppo = Opp(side); if (bbPc(p, side, P) & RelSqBb(D4,side) ) { // defend central pawns (pawns side by side evaluated as "phalanx") if (bbPc(p, side, P) & RelSqBb(E3,side) ) pawnScoreMg[side] += centDefense; if (bbPc(p, side, P) & RelSqBb(C3,side) ) pawnScoreMg[side] += centDefense; } if (bbPc(p, side, P) & RelSqBb(E4,side) ) { if ( bbPc(p, side, P) & RelSqBb(D3,side) ) pawnScoreMg[side] += centDefense; } }
int GetDrawFactor(POS *p, int sd) { int op = Opp(sd); // Case 1: KPK with edge pawn (else KBPK recognizer would break) if (PcMatNone(p, sd) && PcMatNone(p, op) && p->cnt[sd][P] == 1 // TODO: all pawns of a stronger side on a rim && p->cnt[op][P] == 0) { // TODO: accept pawns for a weaker side if (p->Pawns(sd) & FILE_H_BB && p->Kings(op) & bbKingBlockH[sd]) return 0; if (p->Pawns(sd) & FILE_A_BB && p->Kings(op) & bbKingBlockA[sd]) return 0; } // Case 2: KBPK(P) draws with edge pawn and wrong bishop if (PcMatB(p, sd) && PcMatNone(p, op) && p->cnt[sd][P] == 1) { // TODO: all pawns of a stronger side on a rim if (p->Pawns(sd) & FILE_H_BB && NotOnBishColor(p, sd, REL_SQ(H8, sd)) && p->Kings(op) & bbKingBlockH[sd]) return 0; if (p->Pawns(sd) & FILE_A_BB && NotOnBishColor(p, sd, REL_SQ(A8, sd)) && p->Kings(op) & bbKingBlockA[sd]) return 0; } // Case 3: KBP vs Km // drawn when defending king stands on pawn's path and can't be driven out // by a bishop (must be dealt with before opposite bishops ending) if (PcMatB(p, sd) && PcMat1Minor(p, op) && p->cnt[sd][P] == 1 && p->cnt[op][P] == 0 && (SqBb(p->king_sq[op]) & BB.GetFrontSpan(p->Pawns(sd), sd)) && NotOnBishColor(p, sd, p->king_sq[op]) ) return 0; // Case 4: Bishops of opposite color if (PcMatB(p, sd) && PcMatB(p, op) && DifferentBishops(p)) { // 4a: single bishop cannot win without pawns if (p->cnt[sd][P] == 0) return 0; // 4b: different bishops with a single pawn on the own half of the board if (p->cnt[sd][P] == 1 && p->cnt[op][P] == 0) { if (bbHomeZone[sd] & p->Pawns(sd)) return 0; // TODO: 4c: distant bishop controls a square on pawn's path } // 4d: halve the score for pure BOC endings return 32; } if (p->cnt[sd][P] == 0) { // Case 5: low and almost equal material with no pawns if (p->cnt[op][P] == 0) { if (PcMatRm(p, sd) && PcMatRm(p, op)) return 8; if (PcMatR (p, sd) && PcMatR (p, op)) return 8; if (PcMatQ (p, sd) && PcMatQ (p, op)) return 8; if (PcMat2Minors(p, sd) && PcMatR(p, op)) return 8; } // Case 6: two knights if (PcMatNN(p, sd)) { if (p->cnt[op][P] == 0) return 0; else return 4; } // Case 7: K(m) vs K(m) or Km vs Kp(p) if (p->cnt[sd][Q] + p->cnt[sd][R] == 0 && p->cnt[sd][B] + p->cnt[sd][N] < 2 ) return 0; // Case 8: KR vs Km(p) if (PcMatR(p, sd) && PcMat1Minor(p, op) ) return 16; // Case 9: KRm vs KR(p) if (p->cnt[sd][R] == 1 && p->cnt[sd][Q] == 0 && p->cnt[sd][B] + p->cnt[sd][N] == 1 && PcMatR(p, op) ) return 16; // Case 10: KQm vs KQ(p) if (p->cnt[sd][Q] == 1 && p->cnt[sd][R] == 0 && p->cnt[sd][B] + p->cnt[sd][N] == 1 && PcMatQ(p, op) ) return 32; // Case 11: Kmm vs KB(p) if (PcMat2Minors(p,sd) && PcMatB(p, op) ) return 16; // Case 12: KBN vs Km(p) if (PcMatBN(p, sd) && PcMat1Minor(p, op) ) return 16; // Case 13: KRR vs KRm(p) if (PcMatRR(p, sd) && PcMatRm(p, op)) return 16; // Case 14: KRRm vs KRR(p) if (p->cnt[sd][R] == 2 && p->cnt[sd][Q] == 0 && p->cnt[sd][B] + p->cnt[sd][N] == 1 && PcMatRR(p, op)) return 16; } // Case 15: KRP vs KR if (PcMatR(p, sd) && PcMatR(p, op) && p->cnt[sd][P] == 1 && p->cnt[op][P] == 0) { // 15a: good defensive position with a king on pawn's path increases drawing chances if ((SqBb(p->king_sq[op]) & BB.GetFrontSpan(p->Pawns(sd), sd))) return 32; // 1/2 // 15b: draw code for rook endgame with edge pawn if ((RelSqBb(A7, sd) & p->Pawns(sd)) && ( RelSqBb(A8, sd) & p->Rooks(sd)) && ( FILE_A_BB & p->Rooks(op)) && ((RelSqBb(H7, sd) & p->Kings(op)) || (RelSqBb(G7, sd) & p->Kings(op))) ) return 0; // dead draw if ((RelSqBb(H7, sd) & p->Pawns(sd)) && ( RelSqBb(H8, sd) & p->Rooks(sd)) && ( FILE_H_BB & p->Rooks(op)) && ((RelSqBb(A7, sd) & p->Kings(op)) || (RelSqBb(B7, sd) & p->Kings(op))) ) return 0; // dead draw } return 64; }