Ejemplo n.º 1
0
static int evaluate()
{
  int sq;
  int score[2];
  sq_t king_square[2];
  state_t *state = &board->state;
  
  //clearing data:
  score[W] = 0; score[B] = 0;

  ///pawn evaluation:
  eval_pawn_struct(&score[0]);
  
  ///piece evaluation
  //kings
  king_square[W] = King_Square(W);
  king_square[B] = King_Square(B);
  score[W] += psq_table[WK][king_square[W]];
  score[W] += eval_white_king(king_square[W]);
  score[B] += psq_table[BK][king_square[B]];
  score[B] += eval_black_king(king_square[B]);
  
  //queens:
  for(sq = PLS(WQ); sq <= H8; sq = PLN(sq))
  { score[W] += psq_table[WQ][sq];
    if(calc_rank(sq) == RANK_7
    && calc_rank(king_square[BLACK]) == RANK_8)
      score[W] += QUEEN_ON_7TH_REWARD;
    score[W] += eval_q_mobility(sq,W);
  }
  for(sq = PLS(BQ); sq <= H8; sq = PLN(sq))
  { score[B] += psq_table[BQ][sq];
    if(calc_rank(sq) == RANK_2
    && calc_rank(king_square[WHITE]) == RANK_1)
      score[B] += QUEEN_ON_7TH_REWARD;
    score[B] += eval_q_mobility(sq,B);
  }
  
  //rooks:
  for(sq = PLS(WR); sq <= H8; sq = PLN(sq))
  { score[W] += psq_table[WR][sq];
    score[W] += eval_white_rook(sq);
    score[W] += eval_r_mobility(sq,W);
  }
  for(sq = PLS(BR); sq <= H8; sq = PLN(sq))
  { score[B] += psq_table[BR][sq];
    score[B] += eval_black_rook(sq);
    score[B] += eval_r_mobility(sq,B);
  }
  
  //bishops:
  for(sq = PLS(WB); sq <= H8; sq = PLN(sq))
  { score[W] += psq_table[WB][sq];
    score[W] += eval_white_bishop(sq);
    score[W] += eval_b_mobility(sq,W);
    
    //outposts - twice as low than a knight outpost:
    if(!((1ULL << rsz[sq]) & pawn_attacks[B]))
    { if(psq_outposts[W][sq])
      { //if not attacked by an opponent's pawn,
        //this could be a weak square that matters,
        //in accordance with the outposts table:
        score[W] += (psq_outposts[W][sq]) / 2;
        
        //additional bonus if it's reinforced by own pawns:
        if((1ULL << rsz[sq]) & pawn_attacks[W])
          score[W] += (psq_outposts[W][sq]) / 2;				
      }
    }
  }
  for(sq = PLS(BB); sq <= H8; sq = PLN(sq))
  { score[B] += psq_table[BB][sq];
    score[B] += eval_black_bishop(sq);
    score[B] += eval_b_mobility(sq,B);
    
    //outposts:
    if(!((1ULL << rsz[sq]) & pawn_attacks[W]))
    { if(psq_outposts[B][sq])
      { score[B] += (psq_outposts[B][sq]) / 2;
        if((1ULL << rsz[sq]) & pawn_attacks[B])
          score[B] += (psq_outposts[B][sq]) / 2;
      }
    }
  }
  
  //knights:
  for(sq = PLS(WN); sq <= H8; sq = PLN(sq))
  { score[W] += psq_table[WN][sq];
    score[W] += eval_n_mobility(sq,W);
    
    //outposts:
    if(!((1ULL << rsz[sq]) & pawn_attacks[B]))
    { if(psq_outposts[W][sq])
      { score[W] += psq_outposts[W][sq];
        if((1ULL << rsz[sq]) & pawn_attacks[W])
          score[W] += psq_outposts[W][sq];				
      }
    }
  }
  for(sq = PLS(BN); sq <= H8; sq = PLN(sq))
  { score[B] += psq_table[BN][sq];
    score[B] += eval_n_mobility(sq,B);
    
    //outposts:
    if(!((1ULL << rsz[sq]) & pawn_attacks[W]))
    { if(psq_outposts[B][sq])
      { score[B] += psq_outposts[B][sq];
        if((1ULL << rsz[sq]) & pawn_attacks[B])
          score[B] += psq_outposts[B][sq];
      }
    }
  }
  
  //bishop pair bonus depending on pawns on board:
  if(Bishops(W) >= 2) score[W] += BISHOP_PAIR_REWARD - state->pawns;
  if(Bishops(B) >= 2) score[B] += BISHOP_PAIR_REWARD - state->pawns;
  
  //calculate basic knight and rook material imbalances:
  /**********************************************************
      quote from GM L.Kaufman:
   "A further refinement would be to raise the knight's value 
   by 1/16 and lower the rook's value by 1/8 for each pawn 
   above five of the side being valued, with the opposite 
   adjustment for each pawn short of five".
  ***********************************************************/	
  score[W] += Rooks(W)   * rook_imbalance[Pawns(W)];
  score[W] += Knights(W) * knight_imbalance[Pawns(W)];
  score[B] += Rooks(B)   * rook_imbalance[Pawns(B)];
  score[B] += Knights(B) * knight_imbalance[Pawns(B)];
    
  if(opening)
  { score[W] += eval_white_opening();
    score[B] += eval_black_opening();
  }

  ///final results:
  score[W] += state->material_value[WHITE] + \
    state->pawn_value[WHITE];
  score[B] += state->material_value[BLACK] + \
    state->pawn_value[BLACK];
  
  if(board->side == W) return (score[W]-score[B]);
  else return -(score[W]-score[B]);
}
Ejemplo n.º 2
0
/* Used to evaluate the future state of the board,
 returns a relative score used to assess move strength. */
int eval()
{
	int i;  // Counter
	int f;  // File
	int score[2]; // Each side's score
    
	// Initialize board scores by ranking pawns
	for (i = 0; i < 10; ++i) {
		pawn_rank[WHITE][i] = 0;
		pawn_rank[BLACK][i] = 7;
	}
	// Initialize score matricies to zero
	piece_mat[WHITE] = 0;
	piece_mat[BLACK] = 0;
	pawn_mat[WHITE] = 0;
	pawn_mat[BLACK] = 0;
	
	// Scan through board and initialize pawn score matrix
	for (i = 0; i < 64; ++i) {
		if (color[i] == EMPTY)
			continue;
		if (piece[i] == PAWN) {
			pawn_mat[color[i]] += piece_value[PAWN];
			f = COL(i) + 1;  // Add 1 to account for extra file
			if (color[i] == WHITE) {
				if (pawn_rank[WHITE][f] < ROW(i))
					pawn_rank[WHITE][f] = ROW(i);
			}
			else {
				if (pawn_rank[BLACK][f] > ROW(i))
					pawn_rank[BLACK][f] = ROW(i);
			}
		}
		else
			piece_mat[color[i]] += piece_value[piece[i]];
	}
    
	// Evaluate scores of each piece
	score[WHITE] = piece_mat[WHITE] + pawn_mat[WHITE];
	score[BLACK] = piece_mat[BLACK] + pawn_mat[BLACK];
	for (i = 0; i < 64; ++i) {
		if (color[i] == EMPTY)
			continue;
		if (color[i] == WHITE) {
			switch (piece[i]) {
				case PAWN:
					score[WHITE] += eval_white_pawn(i);
					break;
				case KNIGHT:
					score[WHITE] += knight_pcsq[i];
					break;
				case BISHOP:
					score[WHITE] += bishop_pcsq[i];
					break;
				case ROOK:
					if (pawn_rank[WHITE][COL(i) + 1] == 0) {
						if (pawn_rank[BLACK][COL(i) + 1] == 7)
							score[WHITE] += ROOK_OPEN_FILE_BONUS;
						else
							score[WHITE] += ROOK_SEMI_OPEN_FILE_BONUS;
					}
					if (ROW(i) == 1)
						score[WHITE] += ROOK_ON_SEVENTH_BONUS;
					break;
				case KING:
					if (piece_mat[BLACK] <= 1200) // Determines endgame score conditions
						score[WHITE] += king_endgame_pcsq[i];
					else
						score[WHITE] += eval_white_king(i);
					break;
			}
		}
		else {
			switch (piece[i]) {
				case PAWN:
					score[BLACK] += eval_black_pawn(i);
					break;
				case KNIGHT:
					score[BLACK] += knight_pcsq[flip[i]];
					break;
				case BISHOP:
					score[BLACK] += bishop_pcsq[flip[i]];
					break;
				case ROOK:
					if (pawn_rank[BLACK][COL(i) + 1] == 7) {
						if (pawn_rank[WHITE][COL(i) + 1] == 0)
							score[BLACK] += ROOK_OPEN_FILE_BONUS;
						else
							score[BLACK] += ROOK_SEMI_OPEN_FILE_BONUS;
					}
					if (ROW(i) == 6)
						score[BLACK] += ROOK_ON_SEVENTH_BONUS;
					break;
				case KING:
					if (piece_mat[WHITE] <= 1200) // Determines endgame score conditions
						score[BLACK] += king_endgame_pcsq[flip[i]];
					else
						score[BLACK] += eval_black_king(i);
					break;
			}
		}
	}
    
	// Returns score relative to side
	if (side == WHITE)
		return score[WHITE] - score[BLACK];
	return score[BLACK] - score[WHITE];
}