CACHE_LINE_ALIGNMENT
-Score pieceSquareTable[PIECE_NB][SQUARE_NB];
+Score pieceSquareTable[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
Value PieceValue[PHASE_NB][PIECE_NB] = {
{ VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg },
{ VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg } };
for (Square s = SQ_A1; s <= SQ_H8; s++)
{
- pieceSquareTable[make_piece(WHITE, pt)][ s] = (v + PSQT[pt][s]);
- pieceSquareTable[make_piece(BLACK, pt)][~s] = -(v + PSQT[pt][s]);
+ pieceSquareTable[WHITE][pt][ s] = (v + PSQT[pt][s]);
+ pieceSquareTable[BLACK][pt][~s] = -(v + PSQT[pt][s]);
}
}
}
namespace {
-/// next_attacker() is an helper function used by see() to locate the least
-/// valuable attacker for the side to move, remove the attacker we just found
-/// from the 'occupied' bitboard and scan for new X-ray attacks behind it.
+// next_attacker() is an helper function used by see() to locate the least
+// valuable attacker for the side to move, remove the attacker we just found
+// from the 'occupied' bitboard and scan for new X-ray attacks behind it.
template<int Pt> FORCE_INLINE
PieceType next_attacker(const Bitboard* bb, const Square& to, const Bitboard& stmAttackers,
ss << square_to_string(pop_lsb(&b)) << " ";
ss << "\nLegal moves: ";
- for (MoveList<LEGAL> ml(*this); !ml.end(); ++ml)
- ss << move_to_san(*const_cast<Position*>(this), ml.move()) << " ";
+ for (MoveList<LEGAL> it(*this); *it; ++it)
+ ss << move_to_san(*const_cast<Position*>(this), *it) << " ";
return ss.str();
}
Color them = ~us;
Square from = from_sq(m);
Square to = to_sq(m);
- Piece piece = piece_on(from);
- PieceType pt = type_of(piece);
+ Piece pc = piece_on(from);
+ PieceType pt = type_of(pc);
PieceType capture = type_of(m) == ENPASSANT ? PAWN : type_of(piece_on(to));
- assert(color_of(piece) == us);
+ assert(color_of(pc) == us);
assert(piece_on(to) == NO_PIECE || color_of(piece_on(to)) == them || type_of(m) == CASTLE);
assert(capture != KING);
if (type_of(m) == CASTLE)
{
- assert(piece == make_piece(us, KING));
+ assert(pc == make_piece(us, KING));
bool kingSide = to > from;
Square rfrom = to; // Castle is encoded as "king captures friendly rook"
do_castle(from, to, rfrom, rto);
- st->psqScore += psq_delta(make_piece(us, ROOK), rfrom, rto);
+ st->psqScore += pieceSquareTable[us][ROOK][rto] - pieceSquareTable[us][ROOK][rfrom];
k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
}
prefetch((char*)thisThread->materialTable[st->materialKey]);
// Update incremental scores
- st->psqScore -= pieceSquareTable[make_piece(them, capture)][capsq];
+ st->psqScore -= pieceSquareTable[them][capture][capsq];
// Reset rule 50 counter
st->rule50 = 0;
byColorBB[us] ^= from_to_bb;
board[from] = NO_PIECE;
- board[to] = piece;
+ board[to] = pc;
// Update piece lists, index[from] is not updated and becomes stale. This
// works as long as index[] is accessed just by known occupied squares.
^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]];
// Update incremental score
- st->psqScore += pieceSquareTable[make_piece(us, promotion)][to]
- - pieceSquareTable[make_piece(us, PAWN)][to];
+ st->psqScore += pieceSquareTable[us][promotion][to] - pieceSquareTable[us][PAWN][to];
// Update material
st->npMaterial[us] += PieceValue[MG][promotion];
}
// Update incremental scores
- st->psqScore += psq_delta(piece, from, to);
+ st->psqScore += pieceSquareTable[us][pt][to] - pieceSquareTable[us][pt][from];
// Set capture piece
st->capturedType = capture;
/// Position::see() is a static exchange evaluator: It tries to estimate the
-/// material gain or loss resulting from a move. There are three versions of
-/// this function: One which takes a destination square as input, one takes a
-/// move, and one which takes a 'from' and a 'to' square. The function does
-/// not yet understand promotions captures.
+/// material gain or loss resulting from a move. Parameter 'asymmThreshold' takes
+/// tempi into account. If the side who initiated the capturing sequence does the
+/// last capture, he loses a tempo and if the result is below 'asymmThreshold'
+/// the capturing sequence is considered bad.
int Position::see_sign(Move m) const {
return see(m);
}
-int Position::see(Move m) const {
- return do_see<false>(m, 0);
-}
-
-/// Position::see_asymm() takes tempi into account.
-/// If the side who initiated the capturing sequence does the last capture,
-/// he loses a tempo. In this case if the result is below asymmThreshold
-/// the capturing sequence is considered bad.
-
-int Position::see_asymm(Move m, int asymmThreshold) const
-{
- return do_see<true>(m, asymmThreshold);
-}
-
-template <bool Asymmetric>
-int Position::do_see(Move m, int asymmThreshold) const {
+int Position::see(Move m, int asymmThreshold) const {
Square from, to;
Bitboard occupied, attackers, stmAttackers;
} while (stmAttackers);
// If we are doing asymmetric SEE evaluation and the same side does the first
- // and the last capture, he loses a tempo and gain must be at least worth "asymmThreshold".
- // If not, we replace the score with a very low value, before negamaxing.
- if (Asymmetric)
- {
- for (int i = 0; i < slIndex ; i += 2)
- {
+ // and the last capture, he loses a tempo and gain must be at least worth
+ // 'asymmThreshold', otherwise we replace the score with a very low value,
+ // before negamaxing.
+ if (asymmThreshold)
+ for (int i = 0; i < slIndex; i += 2)
if (swapList[i] < asymmThreshold)
- swapList[i] = - QueenValueMg * 16;
- }
- }
+ swapList[i] = - QueenValueMg * 16;
// Having built the swap list, we negamax through it to find the best
// achievable score from the point of view of the side to move.
for (Bitboard b = pieces(); b; )
{
Square s = pop_lsb(&b);
- score += pieceSquareTable[piece_on(s)][s];
+ Piece pc = piece_on(s);
+ score += pieceSquareTable[color_of(pc)][type_of(pc)][s];
}
return score;
/// Position::is_draw() tests whether the position is drawn by material,
/// repetition, or the 50 moves rule. It does not detect stalemates, this
/// must be done by the search.
-template<bool SkipRepetition>
bool Position::is_draw() const {
// Draw by material?
return true;
// Draw by repetition?
- if (!SkipRepetition)
- {
- int i = 4, e = std::min(st->rule50, st->pliesFromNull);
+ int i = 4, e = std::min(st->rule50, st->pliesFromNull);
- if (i <= e)
- {
- StateInfo* stp = st->previous->previous;
+ if (i <= e)
+ {
+ StateInfo* stp = st->previous->previous;
- do {
- stp = stp->previous->previous;
+ do {
+ stp = stp->previous->previous;
- if (stp->key == st->key)
- return true;
+ if (stp->key == st->key)
+ return true;
- i += 2;
+ i += 2;
- } while (i <= e);
- }
+ } while (i <= e);
}
return false;
}
-// Explicit template instantiations
-template bool Position::is_draw<false>() const;
-template bool Position::is_draw<true>() const;
-
/// Position::flip() flips position with the white and black sides reversed. This
/// is only useful for debugging especially for finding evaluation symmetry bugs.