Beispiel #1
0
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;
}