Beruflich Dokumente
Kultur Dokumente
of
See
"bitboard.h"
"bitcount.h"
"pawns.h"
"position.h"
namespace {
#define V Value
#define S(mg, eg) make_score(mg, eg)
// Doubled pawn penalty by file
const Score Doubled[FILE_NB] = {
S(13, 43), S(20, 48), S(23, 48), S(23, 48),
S(23, 48), S(23, 48), S(20, 48), S(13, 43) };
// Isolated pawn penalty by opposed flag and file
{
S(60,
S(37,
S(40,
S(25,
52),
45) },
35),
30) } };
and file
46),
42) },
31),
28) } };
#undef V
template<Color Us>
Score evaluate(const Position& pos, Pawns::Entry* e) {
const
const
const
const
Color
Square
Square
Square
Them
Up
Right
Left
=
=
=
=
(Us
(Us
(Us
(Us
==
==
==
==
WHITE
WHITE
WHITE
WHITE
?
?
?
?
BLACK
DELTA_N
DELTA_NE
DELTA_NW
:
:
:
:
WHITE);
DELTA_S);
DELTA_SW);
DELTA_SE);
Bitboard b, p, doubled;
Square s;
File f;
bool passed, isolated, opposed, connected, backward,
candidate, unsupported;
Score value = SCORE_ZERO;
const Square* pl = pos.list<PAWN>(Us);
Bitboard ourPawns = pos.pieces(Us, PAWN);
Bitboard theirPawns = pos.pieces(Them, PAWN);
e->passedPawns[Us] = e->candidatePawns[Us] = 0;
e->kingSquares[Us] = SQ_NONE;
e->semiopenFiles[Us] = 0xFF;
e->pawnAttacks[Us] = shift_bb<Right>(ourPawns) |
shift_bb<Left>(ourPawns);
e->pawnsOnSquares[Us][BLACK] = popcount<Max15>(ourPawns &
DarkSquares);
e->pawnsOnSquares[Us][WHITE] = pos.count<PAWN>(Us) - e>pawnsOnSquares[Us][BLACK];
// Loop through all pawns of the current color and score
each pawn
while ((s = *pl++) != SQ_NONE)
{
assert(pos.piece_on(s) == make_piece(Us, PAWN));
f = file_of(s);
// This file cannot be semi-open
e->semiopenFiles[Us] &= ~(1 << f);
// Previous rank
p = rank_bb(s - pawn_push(Us));
// Our rank plus previous one
b = rank_bb(s) | p;
one).
p);
isolated
doubled
opposed
passed
&
&
&
&
= !(ourPawns
=
ourPawns
=
theirPawns
= !(theirPawns
adjacent_files_bb(f));
forward_bb(Us, s);
forward_bb(Us, s);
passed_pawn_mask(Us, s));
if (!doubled)
e->candidatePawns[Us] |= s;
}
//
give a
//
pawns.
if
{
}
}
return value;
} // namespace
namespace Pawns {
/// init() initializes some tables by formula instead of hardcoding their values
void init() {
const int bonusesByFile[8] = { 1, 3, 3, 4, 4, 3, 3, 1 };
int bonus;
for (Rank r = RANK_1; r <
for (File f = FILE_A;
{
bonus = r * (r-1)
+ 1);
Connected[f][r] =
}
}
RANK_8; ++r)
f <= FILE_H; ++f)
* (r-2) + bonusesByFile[f] * (r/2
make_score(bonus, bonus);
Entry* e = entries[key];
if (e->key == key)
return e;
e->key = key;
e->value = evaluate<WHITE>(pos, e) - evaluate<BLACK>(pos,
e);
return e;
}
/// Entry::shelter_storm() calculates shelter and storm
penalties for the file
/// the king is on, as well as the two adjacent files.
template<Color Us>
Value Entry::shelter_storm(const Position& pos, Square ksq) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
static const Bitboard MiddleEdges = (FileABB | FileHBB) &
(Rank2BB | Rank3BB);
Value safety = MaxSafetyBonus;
Bitboard b = pos.pieces(PAWN) & (in_front_bb(Us,
rank_of(ksq)) | rank_bb(ksq));
Bitboard ourPawns = b & pos.pieces(Us);
Bitboard theirPawns = b & pos.pieces(Them);
Rank rkUs, rkThem;
File kf = std::max(FILE_B, std::min(FILE_G, file_of(ksq)));
for (File f = kf - File(1); f <= kf + File(1); ++f)
{
b = ourPawns & file_bb(f);
rkUs = b ? relative_rank(Us, backmost_sq(Us, b)) :
RANK_1;
b = theirPawns & file_bb(f);
rkThem = b ? relative_rank(Us, frontmost_sq(Them, b)) :
RANK_1;
if (
else
return safety;