X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=be3c64977be4b001e70f8a3e57dc324d88da04a0;hp=1c27b29d8075728fe77dc56a2f1c805e728836f8;hb=8b0fee9998e2ae530fa57e55f6cf145779aef3d0;hpb=25b492ab586bcb3795a4bbb7521a8e5ee20d6708 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 1c27b29d..be3c6497 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -1,7 +1,7 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) - Copyright (C) 2008-2014 Marco Costalba, Joona Kiiski, Tord Romstad + Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #include #include +#include // For std::memset #include #include @@ -26,7 +27,6 @@ #include "evaluate.h" #include "material.h" #include "pawns.h" -#include "thread.h" namespace { @@ -91,7 +91,7 @@ namespace { // Evaluation weights, indexed by evaluation term enum { Mobility, PawnStructure, PassedPawns, Space, KingSafety }; const struct Weight { int mg, eg; } Weights[] = { - {289, 344}, {233, 201}, {221, 273}, {46, 0}, {321, 0} + {289, 344}, {233, 201}, {221, 273}, {46, 0}, {322, 0} }; #define V(v) Value(v) @@ -162,6 +162,7 @@ namespace { const Score TrappedRook = S(92, 0); const Score Unstoppable = S( 0, 20); const Score Hanging = S(31, 26); + const Score PawnAttackThreat = S(20, 20); // Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by // a friendly pawn on b2/g2 (b7/g7 for black). This can obviously only @@ -186,19 +187,19 @@ namespace { // index to KingDanger[]. // // KingAttackWeights[PieceType] contains king attack weights by piece type - const int KingAttackWeights[] = { 0, 0, 6, 2, 5, 5 }; + const int KingAttackWeights[] = { 0, 0, 7, 5, 4, 1 }; // Bonuses for enemy's safe checks - const int QueenContactCheck = 92; - const int RookContactCheck = 68; + const int QueenContactCheck = 89; + const int RookContactCheck = 71; const int QueenCheck = 50; - const int RookCheck = 36; - const int BishopCheck = 7; + const int RookCheck = 37; + const int BishopCheck = 6; const int KnightCheck = 14; // KingDanger[attackUnits] contains the actual king danger weighted // scores, indexed by a calculated integer number. - Score KingDanger[128]; + Score KingDanger[512]; // apply_weight() weighs score 's' by weight 'w' trying to prevent overflow Score apply_weight(Score s, const Weight& w) { @@ -411,11 +412,11 @@ namespace { // number and types of the enemy's attacking pieces, the number of // attacked and undefended squares around our king and the quality of // the pawn shelter (current 'score' value). - attackUnits = std::min(77, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) - + 10 * ei.kingAdjacentZoneAttacksCount[Them] - + 19 * popcount(undefended) - + 9 * (ei.pinnedPieces[Us] != 0) - - mg_value(score) * 63 / 512 + attackUnits = std::min(74, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) + + 8 * ei.kingAdjacentZoneAttacksCount[Them] + + 25 * popcount(undefended) + + 11 * (ei.pinnedPieces[Us] != 0) + - mg_value(score) * 31 / 256 - !pos.count(Them) * 60; // Analyse the enemy's safe queen contact checks. Firstly, find the @@ -476,7 +477,7 @@ namespace { // Finally, extract the king danger score from the KingDanger[] // array and subtract the score from evaluation. - score -= KingDanger[std::max(std::min(attackUnits / 4, 99), 0)]; + score -= KingDanger[std::max(std::min(attackUnits, 399), 0)]; } if (Trace) @@ -492,7 +493,12 @@ namespace { template Score evaluate_threats(const Position& pos, const EvalInfo& ei) { - const Color Them = (Us == WHITE ? BLACK : WHITE); + const Color Them = (Us == WHITE ? BLACK : WHITE); + const Square Up = (Us == WHITE ? DELTA_N : DELTA_S); + const Square Left = (Us == WHITE ? DELTA_NW : DELTA_SE); + const Square Right = (Us == WHITE ? DELTA_NE : DELTA_SW); + const Bitboard TRank2BB = (Us == WHITE ? Rank2BB : Rank7BB); + const Bitboard TRank7BB = (Us == WHITE ? Rank7BB : Rank2BB); enum { Defended, Weak }; enum { Minor, Major }; @@ -534,13 +540,28 @@ namespace { b = weak & ~ei.attackedBy[Them][ALL_PIECES]; if (b) - score += more_than_one(b) ? Hanging * popcount(b) : Hanging; + score += Hanging * popcount(b); b = weak & ei.attackedBy[Us][KING]; if (b) score += more_than_one(b) ? KingOnMany : KingOnOne; } + // Add bonus for safe pawn pushes which attacks an enemy piece + b = pos.pieces(Us, PAWN) & ~TRank7BB; + b = shift_bb(b | (shift_bb(b & TRank2BB) & ~pos.pieces())); + + b &= ~pos.pieces() + & ~ei.attackedBy[Them][PAWN] + & (ei.attackedBy[Us][PAWN] | ~ei.attackedBy[Them][ALL_PIECES]); + + b = (shift_bb(b) | shift_bb(b)) + & pos.pieces(Them) + & ~ei.attackedBy[Us][PAWN]; + + if (b) + score += popcount(b) * PawnAttackThreat; + if (Trace) Tracing::write(Tracing::THREAT, Us, score); @@ -677,7 +698,6 @@ namespace { EvalInfo ei; Score score, mobility[2] = { SCORE_ZERO, SCORE_ZERO }; - Thread* thisThread = pos.this_thread(); // Initialize score by reading the incrementally updated scores included // in the position object (material + piece square tables). @@ -685,7 +705,7 @@ namespace { score = pos.psq_score(); // Probe the material hash table - ei.mi = Material::probe(pos, thisThread->materialTable, thisThread->endgames); + ei.mi = Material::probe(pos); score += ei.mi->imbalance(); // If we have a specialized evaluation function for the current material @@ -694,7 +714,7 @@ namespace { return ei.mi->evaluate(pos); // Probe the pawn hash table - ei.pi = Pawns::probe(pos, thisThread->pawnsTable); + ei.pi = Pawns::probe(pos); score += apply_weight(ei.pi->pawns_score(), Weights[PawnStructure]); // Initialize attack and king safety bitboards @@ -892,13 +912,14 @@ namespace Eval { void init() { - const double MaxSlope = 30; + const double MaxSlope = 8.7; const double Peak = 1280; + double t = 0.0; - for (int t = 0, i = 1; i < 100; ++i) + for (int i = 1; i < 400; ++i) { - t = int(std::min(Peak, std::min(0.4 * i * i, t + MaxSlope))); - KingDanger[i] = apply_weight(make_score(t, 0), Weights[KingSafety]); + t = std::min(Peak, std::min(0.027 * i * i, t + MaxSlope)); + KingDanger[i] = apply_weight(make_score(int(t), 0), Weights[KingSafety]); } }