コード例 #1
0
void cEval::ScoreKing(POS *p, int sd) {

  const int startSq[2] = { E1, E8 };
  const int qCastle[2] = { B1, B8 };
  const int kCastle[2] = { G1, G8 };

  U64 bbKingFile, bbNextFile;
  int result = 0;
  int sq = KingSq(p, sd);

  // Normalize king square for pawn shield evaluation,
  // to discourage shuffling the king between g1 and h1.

  if (SqBb(sq) & bbKSCastle[sd]) sq = kCastle[sd];
  if (SqBb(sq) & bbQSCastle[sd]) sq = qCastle[sd];

  // Evaluate shielding and storming pawns on each file.

  bbKingFile = BB.FillNorthSq(sq) | BB.FillSouthSq(sq);
  result += ScoreKingFile(p, sd, bbKingFile);

  bbNextFile = ShiftEast(bbKingFile);
  if (bbNextFile) result += ScoreKingFile(p, sd, bbNextFile);

  bbNextFile = ShiftWest(bbKingFile);
  if (bbNextFile) result += ScoreKingFile(p, sd, bbNextFile);

  mg[sd][F_PAWNS] += result;
  mg[sd][F_PAWNS] += ScoreChains(p, sd);
}
コード例 #2
0
ファイル: eval_pawns.c プロジェクト: zhu-jz/rodent_code
void sEvaluator::SinglePawnScore(sPosition *p, int side)
{
  int sq, flagIsOpen, flagIsWeak;
  int oppo = Opp(side);
  U64 flagIsPhalanx, flagPhalanx2, flagIsDoubled, bbFrontSpan;
  U64 bbPieces = bbPc(p, side, P);
  U64 bbOwnPawns = bbPieces;
 
  while (bbPieces) {
    sq = PopFirstBit(&bbPieces);

    // gather information about a pawn that is evaluated
	bbFrontSpan   = GetFrontSpan(SqBb(sq), side );
	flagIsDoubled = bbFrontSpan & bbOwnPawns;
    flagIsOpen    = !( bbFrontSpan & bbPc(p, oppo, P) );
	flagIsPhalanx = ShiftEast(SqBb(sq) ) & bbOwnPawns;
	flagPhalanx2  = ShiftWest(SqBb(sq) ) & bbOwnPawns;
	flagIsWeak    = !( bbPawnSupport[side][sq] & bbOwnPawns );
	
	if (flagIsDoubled) {
	    pawnScoreMg[side] += doubledPawn[MG][File(sq)];
	    pawnScoreEg[side] += doubledPawn[EG][File(sq)];
    }

	if (flagIsPhalanx) {
		pawnScoreMg[side] += Data.pawnProperty[PHALANX][MG][side][sq];
		//pawnScoreEg[side] += Data.phalanxEg[side][sq];
	}

	if (flagIsOpen) {
		U64 bbObstacles = bbPassedMask[side][sq] & bbPc(p, oppo, P);
		
	    // passed pawn (some more eval will be done in ScoreP() in eval_pieces.c)
		if (!bbObstacles) {
			if (flagIsDoubled) AddPasserScore(CANDIDATE,side,sq); // back doubled passer is scored like candidate,
			else               AddPasserScore(PASSED,side,sq);    // only frontmost passer gets full credit
		}
		
	    // candidate passer
		if (flagIsPhalanx || flagPhalanx2) { // test lower bonus when !flagIsWeak
		    if (PopCntSparse(bbObstacles) == 1) AddPasserScore(CANDIDATE,side,sq);
	    }
	}
    
	if (flagIsWeak) {
		if (!(bbAdjacentMask[File(sq)] & bbOwnPawns)) { // isolated 
		   AddPawnProperty(ISOLATED,side,sq);
		   if (flagIsOpen) pawnScoreMg[side] += pawnIsolatedOnOpen;
		} else {                                        // backward
		   AddPawnProperty(BACKWARD,side,sq);
		   if (flagIsOpen) pawnScoreMg[side] += pawnBackwardOnOpen;
		}
	}
  }
}
コード例 #3
0
ファイル: eval.cpp プロジェクト: nescitus/Rodent_II
void cEval::ScorePieces(POS *p, eData *e, int sd) {

  U64 bbPieces, bbMob, bbAtt, bbFile, bbContact;
  int op, sq, cnt, tmp, ksq, att = 0, wood = 0;
  int own_pawn_cnt, opp_pawn_cnt;
  int r_on_7th = 0;
  int fwd_weight = 0;
  int fwd_cnt = 0;

  // Is color OK?

  assert(sd == WC || sd == BC);

  // Init variables

  op = Opp(sd);
  ksq = KingSq(p, op);
  U64 bbExcluded = p->Pawns(sd) /*| p->Kings(sd)*/;

  // Init enemy king zone for attack evaluation. We mark squares where the king
  // can move plus two or three more squares facing enemy position.

  U64 bbZone = Mask.king_zone[sd][ksq];

  // Init bitboards to detect check threats
  
  U64 bbKnightChk = BB.KnightAttacks(ksq);
  U64 bbStr8Chk = BB.RookAttacks(OccBb(p), ksq);
  U64 bbDiagChk = BB.BishAttacks(OccBb(p), ksq);
  U64 bbQueenChk = bbStr8Chk | bbDiagChk;
  
  // Knight

  bbPieces = p->Knights(sd);
  while (bbPieces) {
    sq = BB.PopFirstBit(&bbPieces);

    // Knight tropism to enemy king

    Add(e, sd, F_TROPISM, tropism_mg[N] * Param.dist[sq][ksq], tropism_eg[N] * Param.dist[sq][ksq]);

	// Knight forwardness

    if (SqBb(sq) & bbAwayZone[sd]) {
      fwd_weight += 1;
      fwd_cnt += 1;
	}
    
    // Knight mobility

    bbMob = BB.KnightAttacks(sq) & ~p->cl_bb[sd];  // knight is tricky, 
    cnt = BB.PopCnt(bbMob &~e->bbPawnTakes[op]);   // better to have it mobile than defending stuff
    
    Add(e, sd, F_MOB, Param.n_mob_mg[cnt], Param.n_mob_eg[cnt]);  // mobility bonus

    if ((bbMob &~e->bbPawnTakes[op]) & bbKnightChk) 
      att += chk_threat[N]; // check threat bonus

	e->bbAllAttacks[sd] |= BB.KnightAttacks(sq);
    e->bbEvAttacks[sd]  |= bbMob;

    // Knight attacks on enemy king zone

    bbAtt = BB.KnightAttacks(sq);
    if (bbAtt & bbZone) {
      wood++;
      att += king_att[N] * BB.PopCnt(bbAtt & bbZone);
    }

    // Knight outpost

    ScoreOutpost(p, e, sd, N, sq);

  } // end of knight eval

  // Bishop

  bbPieces = p->Bishops(sd);
  while (bbPieces) {
    sq = BB.PopFirstBit(&bbPieces);

    // Bishop tropism to enemy king

    Add(e, sd, F_TROPISM, tropism_mg[B] * Param.dist[sq][ksq], tropism_eg[B] * Param.dist[sq][ksq]);

    // Bishop forwardness

    if (SqBb(sq) & bbAwayZone[sd]) {
      fwd_weight += 1;
      fwd_cnt += 1;
    }

    // Bishop mobility

    bbMob = BB.BishAttacks(OccBb(p), sq);

    if (!(bbMob & bbAwayZone[sd]))               // penalty for bishops unable to reach enemy half of the board
       Add(e, sd, F_MOB, Param.bishConfined);    // (idea from Andscacs)

    cnt = BB.PopCnt(bbMob &~e->bbPawnTakes[op] &~bbExcluded);
    
    Add(e, sd, F_MOB, Param.b_mob_mg[cnt], Param.b_mob_eg[cnt]);   // mobility bonus

    if ((bbMob &~e->bbPawnTakes[op]) & ~p->cl_bb[sd] & bbDiagChk)
      att += chk_threat[B]; // check threat bonus

    e->bbAllAttacks[sd] |= bbMob;
    e->bbEvAttacks[sd]  |= bbMob;

    // Bishop attacks on enemy king zone (including attacks through a queen)

    bbAtt = BB.BishAttacks(OccBb(p) ^ p->Queens(sd) , sq);
    if (bbAtt & bbZone) {
      wood++;
      att += king_att[B] * BB.PopCnt(bbAtt & bbZone);
    }

    // Bishop outpost

    ScoreOutpost(p, e, sd, B, sq);

    // Bishops side by side

    if (ShiftNorth(SqBb(sq)) & p->Bishops(sd) )
      Add(e, sd, F_OTHERS, 4);
    if (ShiftEast(SqBb(sq)) & p->Bishops(sd))
      Add(e, sd, F_OTHERS, 4);

    // Pawns on the same square color as our bishop
  
    if (bbWhiteSq & SqBb(sq)) {
      own_pawn_cnt = BB.PopCnt(bbWhiteSq & p->Pawns(sd)) - 4;
      opp_pawn_cnt = BB.PopCnt(bbWhiteSq & p->Pawns(op)) - 4;
    } else {
      own_pawn_cnt = BB.PopCnt(bbBlackSq & p->Pawns(sd)) - 4;
      opp_pawn_cnt = BB.PopCnt(bbBlackSq & p->Pawns(op)) - 4;
    }

    Add(e, sd, F_OTHERS, -3 * own_pawn_cnt - opp_pawn_cnt);

  } // end of bishop eval

  // Rook

  bbPieces = p->Rooks(sd);
  while (bbPieces) {
    sq = BB.PopFirstBit(&bbPieces);

    // Rook tropism to enemy king

    Add(e, sd, F_TROPISM, tropism_mg[R] * Param.dist[sq][ksq], tropism_eg[R] * Param.dist[sq][ksq]);

	// Rook forwardness

	if (SqBb(sq) & bbAwayZone[sd]) {
      fwd_weight += 2;
	  fwd_cnt += 1;
	}
  
    // Rook mobility

    bbMob = BB.RookAttacks(OccBb(p), sq);
    cnt = BB.PopCnt(bbMob &~bbExcluded);
    Add(e, sd, F_MOB, Param.r_mob_mg[cnt], Param.r_mob_eg[cnt]);    // mobility bonus
    if (((bbMob &~e->bbPawnTakes[op]) & ~p->cl_bb[sd] & bbStr8Chk)  // check threat bonus
    && p->cnt[sd][Q]) {
      att += chk_threat[R]; 

      bbContact = (bbMob & BB.KingAttacks(ksq)) & bbStr8Chk;

      while (bbContact) {
        int contactSq = BB.PopFirstBit(&bbContact);

        // rook exchanges are accepted as contact checks

        if (Swap(p, sq, contactSq) >= 0) {
          att += r_contact_check;
          break;
        }
      }
    }

    e->bbAllAttacks[sd] |= bbMob;
    e->bbEvAttacks[sd]  |= bbMob;

    // Rook attacks on enemy king zone (also through a rook or through a queen)

    bbAtt = BB.RookAttacks(OccBb(p) ^ p->StraightMovers(sd), sq);
    if (bbAtt & bbZone) {
      wood++;
      att += king_att[R] * BB.PopCnt(bbAtt & bbZone);
    }

    // Get rook file

    bbFile = BB.FillNorthSq(sq) | BB.FillSouthSq(sq); // better this way than using front span

    // Queen on rook's file (which might be closed)

    if (bbFile & p->Queens(op)) Add(e, sd, F_LINES, Param.rookOnQueen);

    // Rook on (half) open file

    if (!(bbFile & p->Pawns(sd))) {
      if (!(bbFile & p->Pawns(op))) {
        Add(e, sd, F_LINES, Param.rookOnOpenMg, Param.rookOnOpenEg);
        //if (BB.GetFrontSpan(SqBb(sq), sd) & p->Rooks(sd)) Add(e, sd, F_LINES, 4, 2); // equal
      }
      else {
        // score differs depending on whether half-open file is blocked by defended enemy pawn
        if ((bbFile & p->Pawns(op)) & e->bbPawnTakes[op])
          Add(e, sd, F_LINES, Param.rookOnBadHalfOpenMg, Param.rookOnBadHalfOpenEg);
        else {
          Add(e, sd, F_LINES, Param.rookOnGoodHalfOpenMg, Param.rookOnGoodHalfOpenEg);
        }
      }
    }

    // Rook on the 7th rank attacking pawns or cutting off enemy king

    if (SqBb(sq) & bbRelRank[sd][RANK_7]) {
      if (p->Pawns(op) & bbRelRank[sd][RANK_7]
      ||  p->Kings(op) & bbRelRank[sd][RANK_8]) {
        Add(e, sd, F_LINES, Param.rookOn7thMg, Param.rookOn7thEg);
        r_on_7th++;
      }
    }

  } // end of rook eval

  // Queen

  bbPieces = p->Queens(sd);
  while (bbPieces) {
    sq = BB.PopFirstBit(&bbPieces);

    // Queen tropism to enemy king

    Add(e, sd, F_TROPISM, tropism_mg[Q] * Param.dist[sq][ksq], tropism_eg[Q] * Param.dist[sq][ksq]);

	// Queen forwardness

	if (SqBb(sq) & bbAwayZone[sd]) {
       fwd_weight += 4;
	   fwd_cnt += 1;
	}

    // Queen mobility

    bbMob = BB.QueenAttacks(OccBb(p), sq);
    cnt = BB.PopCnt(bbMob &~bbExcluded);
    Add(e, sd, F_MOB, Param.q_mob_mg[cnt], Param.q_mob_eg[cnt]);  // mobility bonus

    if ((bbMob &~e->bbPawnTakes[op]) & ~p->cl_bb[sd] & bbQueenChk) {  // check threat bonus
      att += chk_threat[Q];

    // Queen contact checks

    bbContact = bbMob & BB.KingAttacks(ksq);
    while (bbContact) {
      int contactSq = BB.PopFirstBit(&bbContact);

        // queen exchanges are accepted as contact checks

        if (Swap(p, sq, contactSq) >= 0) {
          att += q_contact_check;
          break;
        }
      }
    }

    e->bbAllAttacks[sd] |= bbMob;

    // Queen attacks on enemy king zone
   
    bbAtt  = BB.BishAttacks(OccBb(p) ^ p->DiagMovers(sd), sq);
    bbAtt |= BB.RookAttacks(OccBb(p) ^ p->StraightMovers(sd), sq);
    if (bbAtt & bbZone) {
      wood++;
      att += king_att[Q] * BB.PopCnt(bbAtt & bbZone);
    }

    // Queen on 7th rank

    if (SqBb(sq) & bbRelRank[sd][RANK_7]) {
      if (p->Pawns(op) & bbRelRank[sd][RANK_7]
      || p->Kings(op) & bbRelRank[sd][RANK_8]) {
        Add(e, sd, F_LINES, Param.queenOn7thMg, Param.queenOn7thEg);
      }
    }

  } // end of queen eval

  // Score terms using information gathered during piece eval

  if (r_on_7th > 1)                 // two rooks on 7th rank
    Add(e, sd, F_LINES, Param.twoRooksOn7thMg, Param.twoRooksOn7thEg);

  // forwardness (from Toga II 3.0)
  Add(e, sd, (fwd_bonus[fwd_cnt] * fwd_weight * Param.forwardness) / 100, 0); 

  // Score king attacks if own queen is present and there are at least 2 attackers

  if (wood > 1 && p->cnt[sd][Q]) {
    if (att > 399) att = 399;
    Add(e, sd, F_ATT, Param.danger[att]);
  }

}