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]); }
/* 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]; }