void init(OptionsMap& o) { o["Write Debug Log"] = Option(false, on_logger); o["Write Search Log"] = Option(false); o["Search Log Filename"] = Option("SearchLog.txt"); o["Book File"] = Option("book.bin"); o["Best Book Move"] = Option(false); o["Contempt Factor"] = Option(0, -50, 50); o["Mobility (Midgame)"] = Option(100, 0, 200, on_eval); o["Mobility (Endgame)"] = Option(100, 0, 200, on_eval); o["Pawn Structure (Midgame)"] = Option(100, 0, 200, on_eval); o["Pawn Structure (Endgame)"] = Option(100, 0, 200, on_eval); o["Passed Pawns (Midgame)"] = Option(100, 0, 200, on_eval); o["Passed Pawns (Endgame)"] = Option(100, 0, 200, on_eval); o["Space"] = Option(100, 0, 200, on_eval); o["Aggressiveness"] = Option(100, 0, 200, on_eval); o["Cowardice"] = Option(100, 0, 200, on_eval); o["Min Split Depth"] = Option(0, 0, 12, on_threads); o["Max Threads per Split Point"] = Option(5, 4, 8, on_threads); o["Threads"] = Option(1, 1, MAX_THREADS, on_threads); o["Idle Threads Sleep"] = Option(true); o["Hash"] = Option(128, 1, 8192, on_hash_size); o["Clear Hash"] = Option(on_clear_hash); o["Ponder"] = Option(true); o["OwnBook"] = Option(false); o["MultiPV"] = Option(1, 1, 500); o["Skill Level"] = Option(20, 0, 20); o["Emergency Move Horizon"] = Option(40, 0, 50); o["Emergency Base Time"] = Option(50, 0, 30000); o["Emergency Move Time"] = Option(20, 0, 5000); o["Minimum Thinking Time"] = Option(20, 0, 5000); o["Slow Mover"] = Option(50, 10, 1000); o["UCI_Chess960"] = Option(false); o["UCI_AnalyseMode"] = Option(false, on_eval); o["Piece Structure"] = Option(100, 0, 200, on_eval); typedef Value V; #define S(mg, eg) make_score(mg, eg) //用于产生tuner文件 //Log log; //log<<"name, init, max, min, c_end, r_end, elod"<<std::endl; //PAWN, BISHOP, ADVISOR, KNIGHT, CANNON, ROOK, KING const Score MobilityBonus[][32] = { {}, {},//Pawn { S( 0, 0), S( 0, 0 ), S( 0, 0), S(0, 0), S(0, 0)},// Bishops { S( 0, 0), S( 0, 0 ), S( 0, 0), S(0, 0), S(0, 0)},// Advisor { S(-35,-30), S(-20,-20), S(-20,-20), S( 0, 0), S(0, 0), S(15, 10),S( 15, 10), S( 25, 12), S(25, 12) },//knight { S( -10, -10), S( 2, 4), S( 4, 4), S(6, 6), S(8, 8),S(10, 10),S(12, 12),S(12, 12),S(12, 12),S(12, 12),S(12, 12),S(12, 12),S(12, 12),S(12, 12),S(12, 12),S(12, 12),S(12, 12),S(12, 12)},// Cannon { S(-20,-20), S(-18,-18), S(-16,-16), S( -10,-10), S( -8,-8), S(-4,-4),S( 0, 0), S( 4, 2), S(8, 4), S(12,6), S(16,8), S(20,10),S( 24,12), S( 24,12), S(24,12), S(24,12), S(24,12), S(24,12)}, // Rooks }; for (int pt1 = KNIGHT; pt1 <= ROOK; ++pt1) { for (int c = 0; c <= 17; ++c) { int min = -40; int max = 40; if (pt1 == KNIGHT) { min = -50; max = 50; } if (pt1 == CANNON) { min = 0; max = 20; } if (pt1 == ROOK) { min = -30; max = 30; } int m = (int)mg_value(MobilityBonus[pt1][c]); int e = (int)eg_value(MobilityBonus[pt1][c]); char buf[256] = {0}; char text[1024]={0}; sprintf(buf, "MobilityBonusM[%d][%d]",pt1,c); o[buf] = Option(m, min, max, on_eval_variables); //sprintf(text, "%s,%d,%d,%d,%d,%d,%d",buf, m, max,min,8, 1, 0); //log<<text<<std::endl; //------ sprintf(buf, "MobilityBonusE[%d][%d]",pt1,c); o[buf] = Option(e, min, max, on_eval_variables); //sprintf(text, "%s,%d,%d,%d,%d,%d,%d",buf, e, max,min,8, 1, 0); //log<<text<<std::endl; } } const Score RookPin = make_score(26, 31); const Score CannonPin = make_score(16, 11); const Score RookOnPawn = make_score(10, 28); const Score RookOpenFile = make_score(53, 21); const Score RookPinRook = make_score(20, 20); const Score CannonPinRook = make_score(10, 10); const Score CannonPinKnight = make_score(10, 10); const Score CannonPinBishop = make_score(5, 3); const Score KnightLegPawn = make_score(16, 0); { char buf[256] = {0}; char text[1024]={0}; int min = -50; int max = 50; int m = 0; int e = 0; #define GEN_CODE(namem,namee, v, minv, maxv) {\ m = (int)mg_value((v));\ e = (int)eg_value((v));\ min = minv;\ max = maxv;\ o[namem]= Option(m, min, max, on_eval_variables);\ o[namee]= Option(e, min, max, on_eval_variables);\ } //sprintf(text, "%s,%d,%d,%d,%d,%d,%d",(namem), m, max,min,8, 1, 0);\ //log<<text<<std::endl;\ //sprintf(text, "%s,%d,%d,%d,%d,%d,%d",(namee), e, max,min,8, 1, 0);\ //log<<text<<std::endl;\ } GEN_CODE("RookPinM","RookPinE", RookPin, 0, 50); GEN_CODE("CannonPinM","CannonPinE", CannonPin, 0, 50); GEN_CODE("RookOnPawnM","RookOnPawnE", RookOnPawn, 0, 50); GEN_CODE("RookOpenFileM","RookOpenFileE", RookOpenFile, 0, 50); GEN_CODE("RookPinRookM","RookPinRookE", RookPinRook, 0, 50); GEN_CODE("CannonPinRookM","CannonPinRookE", CannonPinRook, 0, 50); GEN_CODE("CannonPinKnightM","CannonPinKnightE", CannonPinKnight, 0, 50); GEN_CODE("CannonPinBishopM","CannonPinBishopE", CannonPinBishop, 0, 50); GEN_CODE("KnightLegPawnM","KnightLegPawnE", KnightLegPawn, 0, 50); }
std::ostream& operator<<(std::ostream& os, Score s) { os << std::setw(5) << to_cp(mg_value(s)) << " " << std::setw(5) << to_cp(eg_value(s)); return os; }
Value Eval::evaluate(const Position& pos) { assert(!pos.checkers()); EvalInfo ei; Score score, mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO }; // Initialize score by reading the incrementally updated scores included in // the position object (material + piece square tables). Score is computed // internally from the white point of view. score = pos.psq_score(); // Probe the material hash table ei.me = Material::probe(pos); score += ei.me->imbalance(); // If we have a specialized evaluation function for the current material // configuration, call it and return. if (ei.me->specialized_eval_exists()) return ei.me->evaluate(pos); // Probe the pawn hash table ei.pi = Pawns::probe(pos); score += ei.pi->pawns_score(); // Initialize attack and king safety bitboards ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[BLACK][ALL_PIECES] = 0; eval_init<WHITE>(pos, ei); eval_init<BLACK>(pos, ei); // Pawns blocked or on ranks 2 and 3 will be excluded from the mobility area Bitboard blockedPawns[] = { pos.pieces(WHITE, PAWN) & (shift_bb<DELTA_S>(pos.pieces()) | Rank2BB | Rank3BB), pos.pieces(BLACK, PAWN) & (shift_bb<DELTA_N>(pos.pieces()) | Rank7BB | Rank6BB) }; // Do not include in mobility area squares protected by enemy pawns, or occupied // by our blocked pawns or king. Bitboard mobilityArea[] = { ~(ei.attackedBy[BLACK][PAWN] | blockedPawns[WHITE] | pos.square<KING>(WHITE)), ~(ei.attackedBy[WHITE][PAWN] | blockedPawns[BLACK] | pos.square<KING>(BLACK)) }; // Evaluate all pieces but king and pawns score += evaluate_pieces<DoTrace>(pos, ei, mobility, mobilityArea); score += mobility[WHITE] - mobility[BLACK]; // Evaluate kings after all other pieces because we need full attack // information when computing the king safety evaluation. score += evaluate_king<WHITE, DoTrace>(pos, ei) - evaluate_king<BLACK, DoTrace>(pos, ei); // Evaluate tactical threats, we need full attack information including king score += evaluate_threats<WHITE, DoTrace>(pos, ei) - evaluate_threats<BLACK, DoTrace>(pos, ei); // Evaluate passed pawns, we need full attack information including king score += evaluate_passed_pawns<WHITE, DoTrace>(pos, ei) - evaluate_passed_pawns<BLACK, DoTrace>(pos, ei); // If both sides have only pawns, score for potential unstoppable pawns if (!pos.non_pawn_material(WHITE) && !pos.non_pawn_material(BLACK)) { Bitboard b; if ((b = ei.pi->passed_pawns(WHITE)) != 0) score += Unstoppable * int(relative_rank(WHITE, frontmost_sq(WHITE, b))); if ((b = ei.pi->passed_pawns(BLACK)) != 0) score -= Unstoppable * int(relative_rank(BLACK, frontmost_sq(BLACK, b))); } // Evaluate space for both sides, only during opening if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222) score += evaluate_space<WHITE>(pos, ei) - evaluate_space<BLACK>(pos, ei); // Evaluate position potential for the winning side score += evaluate_initiative(pos, ei.pi->pawn_asymmetry(), eg_value(score)); // Evaluate scale factor for the winning side ScaleFactor sf = evaluate_scale_factor(pos, ei, eg_value(score)); // Interpolate between a middlegame and a (scaled by 'sf') endgame score Value v = mg_value(score) * int(ei.me->game_phase()) + eg_value(score) * int(PHASE_MIDGAME - ei.me->game_phase()) * sf / SCALE_FACTOR_NORMAL; v /= int(PHASE_MIDGAME); // In case of tracing add all remaining individual evaluation terms if (DoTrace) { Trace::add(MATERIAL, pos.psq_score()); Trace::add(IMBALANCE, ei.me->imbalance()); Trace::add(PAWN, ei.pi->pawns_score()); Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]); Trace::add(SPACE, evaluate_space<WHITE>(pos, ei) , evaluate_space<BLACK>(pos, ei)); Trace::add(TOTAL, score); } return (pos.side_to_move() == WHITE ? v : -v) + Eval::Tempo; // Side to move point of view }