mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-12-17 11:12:17 +01:00
DroidFish: Updated stockfish engine to version 8.
This commit is contained in:
@@ -425,23 +425,28 @@ Phase Position::game_phase() const {
|
||||
/// slider if removing that piece from the board would result in a position where
|
||||
/// square 's' is attacked. For example, a king-attack blocking piece can be either
|
||||
/// a pinned or a discovered check piece, according if its color is the opposite
|
||||
/// or the same of the color of the slider. The pinners bitboard get filled with
|
||||
/// real and potential pinners.
|
||||
/// or the same of the color of the slider.
|
||||
|
||||
Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
|
||||
|
||||
Bitboard b, p, result = 0;
|
||||
Bitboard result = 0;
|
||||
pinners = 0;
|
||||
|
||||
// Pinners are sliders that attack 's' when a pinned piece is removed
|
||||
pinners = p = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK))
|
||||
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
|
||||
// Snipers are sliders that attack 's' when a piece is removed
|
||||
Bitboard snipers = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK))
|
||||
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
|
||||
|
||||
while (p)
|
||||
while (snipers)
|
||||
{
|
||||
b = between_bb(s, pop_lsb(&p)) & pieces();
|
||||
Square sniperSq = pop_lsb(&snipers);
|
||||
Bitboard b = between_bb(s, sniperSq) & pieces();
|
||||
|
||||
if (!more_than_one(b))
|
||||
result |= b;
|
||||
if (!more_than_one(b))
|
||||
{
|
||||
result |= b;
|
||||
if (b & pieces(color_of(piece_on(s))))
|
||||
pinners |= sniperSq;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -950,102 +955,83 @@ Key Position::key_after(Move m) const {
|
||||
}
|
||||
|
||||
|
||||
/// Position::see() is a static exchange evaluator: It tries to estimate the
|
||||
/// material gain or loss resulting from a move.
|
||||
/// Position::see_ge (Static Exchange Evaluation Greater or Equal) tests if the
|
||||
/// SEE value of move is greater or equal to the given value. We'll use an
|
||||
/// algorithm similar to alpha-beta pruning with a null window.
|
||||
|
||||
Value Position::see_sign(Move m) const {
|
||||
bool Position::see_ge(Move m, Value v) const {
|
||||
|
||||
assert(is_ok(m));
|
||||
|
||||
// Early return if SEE cannot be negative because captured piece value
|
||||
// is not less then capturing one. Note that king moves always return
|
||||
// here because king midgame value is set to 0.
|
||||
if (PieceValue[MG][moved_piece(m)] <= PieceValue[MG][piece_on(to_sq(m))])
|
||||
return VALUE_KNOWN_WIN;
|
||||
|
||||
return see(m);
|
||||
}
|
||||
|
||||
Value Position::see(Move m) const {
|
||||
|
||||
Square from, to;
|
||||
Bitboard occupied, attackers, stmAttackers;
|
||||
Value swapList[32];
|
||||
int slIndex = 1;
|
||||
PieceType captured;
|
||||
Color stm;
|
||||
|
||||
assert(is_ok(m));
|
||||
|
||||
from = from_sq(m);
|
||||
to = to_sq(m);
|
||||
swapList[0] = PieceValue[MG][piece_on(to)];
|
||||
stm = color_of(piece_on(from));
|
||||
occupied = pieces() ^ from;
|
||||
|
||||
// Castling moves are implemented as king capturing the rook so cannot
|
||||
// be handled correctly. Simply return VALUE_ZERO that is always correct
|
||||
// unless in the rare case the rook ends up under attack.
|
||||
// Castling moves are implemented as king capturing the rook so cannot be
|
||||
// handled correctly. Simply assume the SEE value is VALUE_ZERO that is always
|
||||
// correct unless in the rare case the rook ends up under attack.
|
||||
if (type_of(m) == CASTLING)
|
||||
return VALUE_ZERO;
|
||||
return VALUE_ZERO >= v;
|
||||
|
||||
Square from = from_sq(m), to = to_sq(m);
|
||||
PieceType nextVictim = type_of(piece_on(from));
|
||||
Color stm = ~color_of(piece_on(from)); // First consider opponent's move
|
||||
Value balance; // Values of the pieces taken by us minus opponent's ones
|
||||
Bitboard occupied, stmAttackers;
|
||||
|
||||
if (type_of(m) == ENPASSANT)
|
||||
{
|
||||
occupied ^= to - pawn_push(stm); // Remove the captured pawn
|
||||
swapList[0] = PieceValue[MG][PAWN];
|
||||
occupied = SquareBB[to - pawn_push(~stm)]; // Remove the captured pawn
|
||||
balance = PieceValue[MG][PAWN];
|
||||
}
|
||||
else
|
||||
{
|
||||
balance = PieceValue[MG][piece_on(to)];
|
||||
occupied = 0;
|
||||
}
|
||||
|
||||
// Find all attackers to the destination square, with the moving piece
|
||||
// removed, but possibly an X-ray attacker added behind it.
|
||||
attackers = attackers_to(to, occupied) & occupied;
|
||||
if (balance < v)
|
||||
return false;
|
||||
|
||||
// If the opponent has no attackers we are finished
|
||||
stm = ~stm;
|
||||
stmAttackers = attackers & pieces(stm);
|
||||
occupied ^= to; // For the case when captured piece is a pinner
|
||||
if (nextVictim == KING)
|
||||
return true;
|
||||
|
||||
// Don't allow pinned pieces to attack as long all pinners (this includes also
|
||||
// potential ones) are on their original square. When a pinner moves to the
|
||||
// exchange-square or get captured on it, we fall back to standard SEE behaviour.
|
||||
if ( (stmAttackers & pinned_pieces(stm))
|
||||
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
|
||||
stmAttackers &= ~pinned_pieces(stm);
|
||||
balance -= PieceValue[MG][nextVictim];
|
||||
|
||||
if (!stmAttackers)
|
||||
return swapList[0];
|
||||
if (balance >= v)
|
||||
return true;
|
||||
|
||||
// The destination square is defended, which makes things rather more
|
||||
// difficult to compute. We proceed by building up a "swap list" containing
|
||||
// the material gain or loss at each stop in a sequence of captures to the
|
||||
// destination square, where the sides alternately capture, and always
|
||||
// capture with the least valuable piece. After each capture, we look for
|
||||
// new X-ray attacks from behind the capturing piece.
|
||||
captured = type_of(piece_on(from));
|
||||
bool relativeStm = true; // True if the opponent is to move
|
||||
occupied ^= pieces() ^ from ^ to;
|
||||
|
||||
do {
|
||||
assert(slIndex < 32);
|
||||
// Find all attackers to the destination square, with the moving piece removed,
|
||||
// but possibly an X-ray attacker added behind it.
|
||||
Bitboard attackers = attackers_to(to, occupied) & occupied;
|
||||
|
||||
// Add the new entry to the swap list
|
||||
swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][captured];
|
||||
while (true)
|
||||
{
|
||||
stmAttackers = attackers & pieces(stm);
|
||||
|
||||
// Don't allow pinned pieces to attack pieces except the king as long all
|
||||
// pinners are on their original square.
|
||||
if (!(st->pinnersForKing[stm] & ~occupied))
|
||||
stmAttackers &= ~st->blockersForKing[stm];
|
||||
|
||||
if (!stmAttackers)
|
||||
return relativeStm;
|
||||
|
||||
// Locate and remove the next least valuable attacker
|
||||
captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
|
||||
nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
|
||||
|
||||
if (nextVictim == KING)
|
||||
return relativeStm == bool(attackers & pieces(~stm));
|
||||
|
||||
balance += relativeStm ? PieceValue[MG][nextVictim]
|
||||
: -PieceValue[MG][nextVictim];
|
||||
|
||||
relativeStm = !relativeStm;
|
||||
|
||||
if (relativeStm == (balance >= v))
|
||||
return relativeStm;
|
||||
|
||||
stm = ~stm;
|
||||
stmAttackers = attackers & pieces(stm);
|
||||
if ( (stmAttackers & pinned_pieces(stm))
|
||||
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
|
||||
stmAttackers &= ~pinned_pieces(stm);
|
||||
|
||||
++slIndex;
|
||||
|
||||
} while (stmAttackers && (captured != KING || (--slIndex, false))); // Stop before a king capture
|
||||
|
||||
// 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.
|
||||
while (--slIndex)
|
||||
swapList[slIndex - 1] = std::min(-swapList[slIndex], swapList[slIndex - 1]);
|
||||
|
||||
return swapList[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user