Skip to content

Commit

Permalink
Sync with master
Browse files Browse the repository at this point in the history
bench: 7038730
  • Loading branch information
mcostalba committed Aug 28, 2016
2 parents a64e06f + 2b57b61 commit f624582
Show file tree
Hide file tree
Showing 23 changed files with 457 additions and 416 deletions.
101 changes: 68 additions & 33 deletions src/evaluate.cpp
Expand Up @@ -77,6 +77,11 @@ namespace {
// attacked by a given color and piece type (can be also ALL_PIECES).
Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];

// attackedBy2[color] are the squares attacked by 2 pieces of a given color,
// possibly via x-ray or by one pawn and one piece. Diagonal x-ray through
// pawn or squares attacked by 2 pawns are not explicitly added.
Bitboard attackedBy2[COLOR_NB];

// kingRing[color] is the zone around the king which is considered
// by the king safety evaluation. This consists of the squares directly
// adjacent to the king, and the three (or two, for a king on an edge file)
Expand Down Expand Up @@ -183,6 +188,7 @@ namespace {
const Score BishopPawns = S( 8, 12);
const Score RookOnPawn = S( 8, 24);
const Score TrappedRook = S(92, 0);
const Score CloseEnemies = S( 7, 0);
const Score SafeCheck = S(20, 20);
const Score OtherCheck = S(10, 10);
const Score ThreatByHangingPawn = S(71, 61);
Expand Down Expand Up @@ -211,10 +217,10 @@ namespace {

// Penalties for enemy's safe checks
const int QueenContactCheck = 89;
const int QueenCheck = 52;
const int RookCheck = 45;
const int BishopCheck = 5;
const int KnightCheck = 17;
const int QueenCheck = 62;
const int RookCheck = 57;
const int BishopCheck = 48;
const int KnightCheck = 78;


// eval_init() initializes king and attack bitboards for a given color
Expand All @@ -227,9 +233,10 @@ namespace {
const Square Down = (Us == WHITE ? DELTA_S : DELTA_N);

ei.pinnedPieces[Us] = pos.pinned_pieces(Us);
Bitboard b = ei.attackedBy[Them][KING] = pos.attacks_from<KING>(pos.square<KING>(Them));
Bitboard b = ei.attackedBy[Them][KING];
ei.attackedBy[Them][ALL_PIECES] |= b;
ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us);
ei.attackedBy2[Us] = ei.attackedBy[Us][PAWN] & ei.attackedBy[Us][KING];

// Init king safety tables only if we are going to use them
if (pos.non_pawn_material(Us) >= QueenValueMg)
Expand Down Expand Up @@ -272,6 +279,7 @@ namespace {
if (ei.pinnedPieces[Us] & s)
b &= LineBB[pos.square<KING>(Us)][s];

ei.attackedBy2[Us] |= ei.attackedBy[Us][ALL_PIECES] & b;
ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][Pt] |= b;

if (b & ei.kingRing[Them])
Expand Down Expand Up @@ -348,6 +356,13 @@ namespace {
score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us));
}
}

if (Pt == QUEEN)
{
// Penalty if any relative pin or discovered attack against the queen
if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s))
score -= WeakQueen;
}
}

if (DoTrace)
Expand All @@ -365,6 +380,19 @@ namespace {

// evaluate_king() assigns bonuses and penalties to a king of a given color

const Bitboard WhiteCamp = Rank1BB | Rank2BB | Rank3BB | Rank4BB | Rank5BB;
const Bitboard BlackCamp = Rank8BB | Rank7BB | Rank6BB | Rank5BB | Rank4BB;
const Bitboard QueenSide = FileABB | FileBBB | FileCBB | FileDBB;
const Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
const Bitboard KingSide = FileEBB | FileFBB | FileGBB | FileHBB;

const Bitboard KingFlank[COLOR_NB][FILE_NB] = {
{ QueenSide & WhiteCamp, QueenSide & WhiteCamp, QueenSide & WhiteCamp, CenterFiles & WhiteCamp,
CenterFiles & WhiteCamp, KingSide & WhiteCamp, KingSide & WhiteCamp, KingSide & WhiteCamp },
{ QueenSide & BlackCamp, QueenSide & BlackCamp, QueenSide & BlackCamp, CenterFiles & BlackCamp,
CenterFiles & BlackCamp, KingSide & BlackCamp, KingSide & BlackCamp, KingSide & BlackCamp },
};

template<Color Us, bool DoTrace>
Score evaluate_king(const Position& pos, const EvalInfo& ei) {

Expand All @@ -382,11 +410,9 @@ namespace {
if (ei.kingAttackersCount[Them])
{
// Find the attacked squares which are defended only by the king...
undefended = ei.attackedBy[Them][ALL_PIECES]
& ei.attackedBy[Us][KING]
& ~( ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT]
| ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK]
| ei.attackedBy[Us][QUEEN]);
undefended = ei.attackedBy[Them][ALL_PIECES]
& ei.attackedBy[Us][KING]
& ~ei.attackedBy2[Us];

// ... and those which are not defended at all in the larger king ring
b = ei.attackedBy[Them][ALL_PIECES] & ~ei.attackedBy[Us][ALL_PIECES]
Expand All @@ -399,23 +425,17 @@ namespace {
// the pawn shelter (current 'score' value).
attackUnits = std::min(72, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them])
+ 9 * ei.kingAdjacentZoneAttacksCount[Them]
+ 27 * popcount(undefended)
+ 11 * (popcount(b) + !!ei.pinnedPieces[Us])
+ 21 * popcount(undefended)
+ 12 * (popcount(b) + !!ei.pinnedPieces[Us])
- 64 * !pos.count<QUEEN>(Them)
- mg_value(score) / 8;

// Analyse the enemy's safe queen contact checks. Firstly, find the
// undefended squares around the king reachable by the enemy queen...
b = undefended & ei.attackedBy[Them][QUEEN] & ~pos.pieces(Them);
if (b)
{
// ...and then remove squares not supported by another enemy piece
b &= ei.attackedBy[Them][PAWN] | ei.attackedBy[Them][KNIGHT]
| ei.attackedBy[Them][BISHOP] | ei.attackedBy[Them][ROOK]
| ei.attackedBy[Them][KING];

attackUnits += QueenContactCheck * popcount(b);
}
// ...and keep squares supported by another enemy piece
attackUnits += QueenContactCheck * popcount(b & ei.attackedBy2[Them]);

// Analyse the safe enemy's checks which are possible on next move...
safe = ~(ei.attackedBy[Us][ALL_PIECES] | pos.pieces(Them));
Expand All @@ -432,6 +452,12 @@ namespace {
if ((b1 | b2) & ei.attackedBy[Them][QUEEN] & safe)
attackUnits += QueenCheck, score -= SafeCheck;

// For other pieces, also consider the square safe if attacked twice,
// and only defended by a queen.
safe |= ei.attackedBy2[Them]
& ~(ei.attackedBy2[Us] | pos.pieces(Them))
& ei.attackedBy[Us][QUEEN];

// Enemy rooks safe and other checks
if (b1 & ei.attackedBy[Them][ROOK] & safe)
attackUnits += RookCheck, score -= SafeCheck;
Expand Down Expand Up @@ -459,6 +485,19 @@ namespace {
score -= KingDanger[std::max(std::min(attackUnits, 399), 0)];
}

// King tropism: firstly, find squares that opponent attacks in our king flank
b = ei.attackedBy[Them][ALL_PIECES] & KingFlank[Us][file_of(ksq)];

assert(((Us == WHITE ? b << 4 : b >> 4) & b) == 0);
assert(popcount(Us == WHITE ? b << 4 : b >> 4) == popcount(b));

// Secondly, add the squares which are attacked twice in that flank and
// which are not defended by our pawns.
b = (Us == WHITE ? b << 4 : b >> 4)
| (b & ei.attackedBy2[Them] & ~ei.attackedBy[Us][PAWN]);

score -= CloseEnemies * popcount(b);

if (DoTrace)
Trace::add(KING, Us, score);

Expand Down Expand Up @@ -489,13 +528,6 @@ namespace {
& ~(ei.attackedBy[Us][ALL_PIECES] | ei.attackedBy[Them][ALL_PIECES]))
score += LooseEnemies;

// Bonus for pin or discovered attack on the opponent queen
if ( pos.count<QUEEN>(Them) == 1
&& pos.slider_blockers(pos.pieces(),
pos.pieces(Us, ROOK, BISHOP),
pos.square<QUEEN>(Them)))
score += WeakQueen;

// Non-pawn enemies attacked by a pawn
weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & ei.attackedBy[Us][PAWN];

Expand Down Expand Up @@ -577,6 +609,7 @@ namespace {
Square s = pop_lsb(&b);

assert(pos.pawn_passed(Us, s));
assert(!(pos.pieces(PAWN) & forward_bb(Us, s)));

int r = relative_rank(Us, s) - RANK_2;
int rr = r * (r - 1);
Expand Down Expand Up @@ -672,10 +705,10 @@ namespace {

// ...count safe + (behind & safe) with a single popcount
int bonus = popcount((Us == WHITE ? safe << 32 : safe >> 32) | (behind & safe));
int weight = pos.count<KNIGHT>(Us) + pos.count<BISHOP>(Us)
+ pos.count<KNIGHT>(Them) + pos.count<BISHOP>(Them);
bonus = std::min(16, bonus);
int weight = pos.count<ALL_PIECES>(Us);

return make_score(bonus * weight * weight * 2 / 11, 0);
return make_score(bonus * weight * weight / 22, 0);
}


Expand Down Expand Up @@ -722,14 +755,14 @@ namespace {
// Endgame with opposite-colored bishops, but also other pieces. Still
// a bit drawish, but not as drawish as with only the two bishops.
else
sf = ScaleFactor(46 * sf / SCALE_FACTOR_NORMAL);
sf = ScaleFactor(46);
}
// Endings where weaker side can place his king in front of the opponent's
// pawns are drawish.
else if ( abs(eg) <= BishopValueEg
&& ei.pi->pawn_span(strongSide) <= 1
&& pos.count<PAWN>(strongSide) <= 2
&& !pos.pawn_passed(~strongSide, pos.square<KING>(~strongSide)))
sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(51) : ScaleFactor(37);
sf = ScaleFactor(37 + 7 * pos.count<PAWN>(strongSide));
}

return sf;
Expand Down Expand Up @@ -769,6 +802,8 @@ Value Eval::evaluate(const Position& pos) {

// Initialize attack and king safety bitboards
ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[BLACK][ALL_PIECES] = 0;
ei.attackedBy[WHITE][KING] = pos.attacks_from<KING>(pos.square<KING>(WHITE));
ei.attackedBy[BLACK][KING] = pos.attacks_from<KING>(pos.square<KING>(BLACK));
eval_init<WHITE>(pos, ei);
eval_init<BLACK>(pos, ei);

Expand Down
6 changes: 3 additions & 3 deletions src/material.h
Expand Up @@ -50,9 +50,9 @@ struct Entry {
// the position. For instance, in KBP vs K endgames, the scaling function looks
// for rook pawns and wrong-colored bishops.
ScaleFactor scale_factor(const Position& pos, Color c) const {
return !scalingFunction[c]
|| (*scalingFunction[c])(pos) == SCALE_FACTOR_NONE ? ScaleFactor(factor[c])
: (*scalingFunction[c])(pos);
ScaleFactor sf = scalingFunction[c] ? (*scalingFunction[c])(pos)
: SCALE_FACTOR_NONE;
return sf != SCALE_FACTOR_NONE ? sf : ScaleFactor(factor[c]);
}

Key key;
Expand Down
12 changes: 6 additions & 6 deletions src/misc.cpp
Expand Up @@ -65,23 +65,23 @@ struct Tie: public streambuf { // MSVC requires split streambuf for cin and cout
class Logger {

Logger() : in(cin.rdbuf(), file.rdbuf()), out(cout.rdbuf(), file.rdbuf()) {}
~Logger() { start(false); }
~Logger() { start(""); }

ofstream file;
Tie in, out;

public:
static void start(bool b) {
static void start(const std::string& fname) {

static Logger l;

if (b && !l.file.is_open())
if (!fname.empty() && !l.file.is_open())
{
l.file.open("io_log.txt", ifstream::out);
l.file.open(fname, ifstream::out);
cin.rdbuf(&l.in);
cout.rdbuf(&l.out);
}
else if (!b && l.file.is_open())
else if (fname.empty() && l.file.is_open())
{
cout.rdbuf(l.out.buf);
cin.rdbuf(l.in.buf);
Expand Down Expand Up @@ -157,7 +157,7 @@ std::ostream& operator<<(std::ostream& os, SyncCout sc) {


/// Trampoline helper to avoid moving Logger to misc.h
void start_logger(bool b) { Logger::start(b); }
void start_logger(const std::string& fname) { Logger::start(fname); }


/// prefetch() preloads the given address in L1/L2 cache. This is a non-blocking
Expand Down
2 changes: 1 addition & 1 deletion src/misc.h
Expand Up @@ -31,7 +31,7 @@

const std::string engine_info(bool to_uci = false);
void prefetch(void* addr);
void start_logger(bool b);
void start_logger(const std::string& fname);

void dbg_hit_on(bool b);
void dbg_hit_on(bool c, bool b);
Expand Down

0 comments on commit f624582

Please sign in to comment.