mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 00:33:09 +00:00
Sync with master
bench: 7031649
This commit is contained in:
commit
15dce36035
5 changed files with 46 additions and 37 deletions
|
@ -187,6 +187,7 @@ namespace {
|
||||||
const Score OtherCheck = S(10, 10);
|
const Score OtherCheck = S(10, 10);
|
||||||
const Score ThreatByHangingPawn = S(71, 61);
|
const Score ThreatByHangingPawn = S(71, 61);
|
||||||
const Score LooseEnemies = S( 0, 25);
|
const Score LooseEnemies = S( 0, 25);
|
||||||
|
const Score WeakQueen = S(35, 0);
|
||||||
const Score Hanging = S(48, 27);
|
const Score Hanging = S(48, 27);
|
||||||
const Score ThreatByPawnPush = S(38, 22);
|
const Score ThreatByPawnPush = S(38, 22);
|
||||||
const Score Unstoppable = S( 0, 20);
|
const Score Unstoppable = S( 0, 20);
|
||||||
|
@ -488,6 +489,13 @@ namespace {
|
||||||
& ~(ei.attackedBy[Us][ALL_PIECES] | ei.attackedBy[Them][ALL_PIECES]))
|
& ~(ei.attackedBy[Us][ALL_PIECES] | ei.attackedBy[Them][ALL_PIECES]))
|
||||||
score += LooseEnemies;
|
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
|
// Non-pawn enemies attacked by a pawn
|
||||||
weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & ei.attackedBy[Us][PAWN];
|
weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & ei.attackedBy[Us][PAWN];
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ namespace {
|
||||||
opposed = theirPawns & forward_bb(Us, s);
|
opposed = theirPawns & forward_bb(Us, s);
|
||||||
stoppers = theirPawns & passed_pawn_mask(Us, s);
|
stoppers = theirPawns & passed_pawn_mask(Us, s);
|
||||||
lever = theirPawns & pawnAttacksBB[s];
|
lever = theirPawns & pawnAttacksBB[s];
|
||||||
doubled = ourPawns & forward_bb(Us, s);
|
doubled = ourPawns & (s + Up);
|
||||||
neighbours = ourPawns & adjacent_files_bb(f);
|
neighbours = ourPawns & adjacent_files_bb(f);
|
||||||
phalanx = neighbours & rank_bb(s);
|
phalanx = neighbours & rank_bb(s);
|
||||||
supported = neighbours & rank_bb(s - Up);
|
supported = neighbours & rank_bb(s - Up);
|
||||||
|
@ -150,7 +150,7 @@ namespace {
|
||||||
// Passed pawns will be properly scored in evaluation because we need
|
// Passed pawns will be properly scored in evaluation because we need
|
||||||
// full attack info to evaluate them. Only the frontmost passed
|
// full attack info to evaluate them. Only the frontmost passed
|
||||||
// pawn on each file is considered a true passed pawn.
|
// pawn on each file is considered a true passed pawn.
|
||||||
if (!(stoppers | doubled))
|
if (!(stoppers | doubled)) // FIXME this is just doubled by adjacent pawn
|
||||||
e->passedPawns[Us] |= s;
|
e->passedPawns[Us] |= s;
|
||||||
|
|
||||||
// Score this pawn
|
// Score this pawn
|
||||||
|
@ -167,7 +167,7 @@ namespace {
|
||||||
score += Connected[opposed][!!phalanx][more_than_one(supported)][relative_rank(Us, s)];
|
score += Connected[opposed][!!phalanx][more_than_one(supported)][relative_rank(Us, s)];
|
||||||
|
|
||||||
if (doubled)
|
if (doubled)
|
||||||
score -= Doubled / distance<Rank>(s, frontmost_sq(Us, doubled));
|
score -= Doubled;
|
||||||
|
|
||||||
if (lever)
|
if (lever)
|
||||||
score += Lever[relative_rank(Us, s)];
|
score += Lever[relative_rank(Us, s)];
|
||||||
|
|
|
@ -454,28 +454,27 @@ Phase Position::game_phase() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Position::check_blockers() returns a bitboard of all the pieces with color
|
/// Position::slider_blockers() returns a bitboard of all the pieces in 'target' that
|
||||||
/// 'c' that are blocking check on the king with color 'kingColor'. A piece
|
/// are blocking attacks on the square 's' from 'sliders'. A piece blocks a slider
|
||||||
/// blocks a check if removing that piece from the board would result in a
|
/// if removing that piece from the board would result in a position where square 's'
|
||||||
/// position where the king is in check. A check blocking piece can be either a
|
/// is attacked. For example, a king-attack blocking piece can be either a pinned or
|
||||||
/// pinned or a discovered check piece, according if its color 'c' is the same
|
/// a discovered check piece, according if its color is the opposite or the same of
|
||||||
/// or the opposite of 'kingColor'.
|
/// the color of the slider.
|
||||||
|
|
||||||
Bitboard Position::check_blockers(Color c, Color kingColor) const {
|
Bitboard Position::slider_blockers(Bitboard target, Bitboard sliders, Square s) const {
|
||||||
|
|
||||||
Bitboard b, pinners, result = 0;
|
Bitboard b, pinners, result = 0;
|
||||||
Square ksq = square<KING>(kingColor);
|
|
||||||
|
|
||||||
// Pinners are sliders that give check when a pinned piece is removed
|
// Pinners are sliders that attack 's' when a pinned piece is removed
|
||||||
pinners = ( (pieces( ROOK, QUEEN) & PseudoAttacks[ROOK ][ksq])
|
pinners = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK))
|
||||||
| (pieces(BISHOP, QUEEN) & PseudoAttacks[BISHOP][ksq])) & pieces(~kingColor);
|
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
|
||||||
|
|
||||||
while (pinners)
|
while (pinners)
|
||||||
{
|
{
|
||||||
b = between_bb(ksq, pop_lsb(&pinners)) & pieces();
|
b = between_bb(s, pop_lsb(&pinners)) & pieces();
|
||||||
|
|
||||||
if (!more_than_one(b))
|
if (!more_than_one(b))
|
||||||
result |= b & pieces(c);
|
result |= b & target;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,7 @@ public:
|
||||||
Bitboard attacks_from(Piece pc, Square s) const;
|
Bitboard attacks_from(Piece pc, Square s) const;
|
||||||
template<PieceType> Bitboard attacks_from(Square s) const;
|
template<PieceType> Bitboard attacks_from(Square s) const;
|
||||||
template<PieceType> Bitboard attacks_from(Square s, Color c) const;
|
template<PieceType> Bitboard attacks_from(Square s, Color c) const;
|
||||||
|
Bitboard slider_blockers(Bitboard target, Bitboard sliders, Square s) const;
|
||||||
|
|
||||||
// Properties of moves
|
// Properties of moves
|
||||||
bool legal(Move m, Bitboard pinned) const;
|
bool legal(Move m, Bitboard pinned) const;
|
||||||
|
@ -187,7 +188,6 @@ private:
|
||||||
void set_state(StateInfo* si) const;
|
void set_state(StateInfo* si) const;
|
||||||
|
|
||||||
// Other helpers
|
// Other helpers
|
||||||
Bitboard check_blockers(Color c, Color kingColor) const;
|
|
||||||
void put_piece(Color c, PieceType pt, Square s);
|
void put_piece(Color c, PieceType pt, Square s);
|
||||||
void remove_piece(Color c, PieceType pt, Square s);
|
void remove_piece(Color c, PieceType pt, Square s);
|
||||||
void move_piece(Color c, PieceType pt, Square from, Square to);
|
void move_piece(Color c, PieceType pt, Square from, Square to);
|
||||||
|
@ -312,11 +312,11 @@ inline Bitboard Position::checkers() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Bitboard Position::discovered_check_candidates() const {
|
inline Bitboard Position::discovered_check_candidates() const {
|
||||||
return check_blockers(sideToMove, ~sideToMove);
|
return slider_blockers(pieces(sideToMove), pieces(sideToMove), square<KING>(~sideToMove));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Bitboard Position::pinned_pieces(Color c) const {
|
inline Bitboard Position::pinned_pieces(Color c) const {
|
||||||
return check_blockers(c, c);
|
return slider_blockers(pieces(c), pieces(~c), square<KING>(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Position::pawn_passed(Color c, Square s) const {
|
inline bool Position::pawn_passed(Color c, Square s) const {
|
||||||
|
|
|
@ -541,18 +541,18 @@ void Thread::search() {
|
||||||
// Stop the search if only one legal move is available, or if all
|
// Stop the search if only one legal move is available, or if all
|
||||||
// of the available time has been used, or if we matched an easyMove
|
// of the available time has been used, or if we matched an easyMove
|
||||||
// from the previous search and just did a fast verification.
|
// from the previous search and just did a fast verification.
|
||||||
const bool F[] = { !mainThread->failedLow,
|
const int F[] = { mainThread->failedLow,
|
||||||
bestValue >= mainThread->previousScore };
|
bestValue - mainThread->previousScore };
|
||||||
|
|
||||||
int improvingFactor = 640 - 160*F[0] - 126*F[1] - 124*F[0]*F[1];
|
int improvingFactor = std::max(229, std::min(715, 357 + 119 * F[0] - 6 * F[1]));
|
||||||
double unstablePvFactor = 1 + mainThread->bestMoveChanges;
|
double unstablePvFactor = 1 + mainThread->bestMoveChanges;
|
||||||
|
|
||||||
bool doEasyMove = rootMoves[0].pv[0] == easyMove
|
bool doEasyMove = rootMoves[0].pv[0] == easyMove
|
||||||
&& mainThread->bestMoveChanges < 0.03
|
&& mainThread->bestMoveChanges < 0.03
|
||||||
&& Time.elapsed() > Time.optimum() * 25 / 204;
|
&& Time.elapsed() > Time.optimum() * 5 / 42;
|
||||||
|
|
||||||
if ( rootMoves.size() == 1
|
if ( rootMoves.size() == 1
|
||||||
|| Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 634
|
|| Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 628
|
||||||
|| (mainThread->easyMovePlayed = doEasyMove))
|
|| (mainThread->easyMovePlayed = doEasyMove))
|
||||||
{
|
{
|
||||||
// If we are allowed to ponder do not stop the search now but
|
// If we are allowed to ponder do not stop the search now but
|
||||||
|
@ -609,6 +609,7 @@ namespace {
|
||||||
Value bestValue, value, ttValue, eval, nullValue, futilityValue;
|
Value bestValue, value, ttValue, eval, nullValue, futilityValue;
|
||||||
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
|
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
|
||||||
bool captureOrPromotion, doFullDepthSearch;
|
bool captureOrPromotion, doFullDepthSearch;
|
||||||
|
Piece moved_piece;
|
||||||
int moveCount, quietCount;
|
int moveCount, quietCount;
|
||||||
|
|
||||||
// Step 1. Initialize node
|
// Step 1. Initialize node
|
||||||
|
@ -865,7 +866,9 @@ namespace {
|
||||||
moves_loop: // When in check search starts from here
|
moves_loop: // When in check search starts from here
|
||||||
|
|
||||||
Square prevSq = to_sq((ss-1)->currentMove);
|
Square prevSq = to_sq((ss-1)->currentMove);
|
||||||
const CounterMoveStats& cmh = CounterMoveHistory[pos.piece_on(prevSq)][prevSq];
|
const CounterMoveStats* cmh = (ss-1)->counterMoves;
|
||||||
|
const CounterMoveStats* fmh = (ss-2)->counterMoves;
|
||||||
|
const CounterMoveStats* fmh2 = (ss-4)->counterMoves;
|
||||||
|
|
||||||
MovePicker mp(pos, ttMove, depth, ss);
|
MovePicker mp(pos, ttMove, depth, ss);
|
||||||
CheckInfo ci(pos);
|
CheckInfo ci(pos);
|
||||||
|
@ -911,6 +914,7 @@ moves_loop: // When in check search starts from here
|
||||||
|
|
||||||
extension = DEPTH_ZERO;
|
extension = DEPTH_ZERO;
|
||||||
captureOrPromotion = pos.capture_or_promotion(move);
|
captureOrPromotion = pos.capture_or_promotion(move);
|
||||||
|
moved_piece = pos.moved_piece(move);
|
||||||
|
|
||||||
givesCheck = type_of(move) == NORMAL && !ci.dcCandidates
|
givesCheck = type_of(move) == NORMAL && !ci.dcCandidates
|
||||||
? ci.checkSquares[type_of(pos.piece_on(from_sq(move)))] & to_sq(move)
|
? ci.checkSquares[type_of(pos.piece_on(from_sq(move)))] & to_sq(move)
|
||||||
|
@ -957,11 +961,12 @@ moves_loop: // When in check search starts from here
|
||||||
&& moveCount >= FutilityMoveCounts[improving][depth])
|
&& moveCount >= FutilityMoveCounts[improving][depth])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// History based pruning
|
// Countermoves based pruning
|
||||||
if ( depth <= 4 * ONE_PLY
|
if ( depth <= 4 * ONE_PLY
|
||||||
&& move != ss->killers[0]
|
&& move != ss->killers[0]
|
||||||
&& thisThread->history[pos.moved_piece(move)][to_sq(move)] < VALUE_ZERO
|
&& (!cmh || (*cmh )[moved_piece][to_sq(move)] < VALUE_ZERO)
|
||||||
&& cmh[pos.moved_piece(move)][to_sq(move)] < VALUE_ZERO)
|
&& (!fmh || (*fmh )[moved_piece][to_sq(move)] < VALUE_ZERO)
|
||||||
|
&& (!fmh2 || (*fmh2)[moved_piece][to_sq(move)] < VALUE_ZERO || (cmh && fmh)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
predictedDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO);
|
predictedDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO);
|
||||||
|
@ -994,7 +999,7 @@ moves_loop: // When in check search starts from here
|
||||||
}
|
}
|
||||||
|
|
||||||
ss->currentMove = move;
|
ss->currentMove = move;
|
||||||
ss->counterMoves = &CounterMoveHistory[pos.moved_piece(move)][to_sq(move)];
|
ss->counterMoves = &CounterMoveHistory[moved_piece][to_sq(move)];
|
||||||
|
|
||||||
// Step 14. Make the move
|
// Step 14. Make the move
|
||||||
pos.do_move(move, st, givesCheck);
|
pos.do_move(move, st, givesCheck);
|
||||||
|
@ -1006,20 +1011,17 @@ moves_loop: // When in check search starts from here
|
||||||
&& !captureOrPromotion)
|
&& !captureOrPromotion)
|
||||||
{
|
{
|
||||||
Depth r = reduction<PvNode>(improving, depth, moveCount);
|
Depth r = reduction<PvNode>(improving, depth, moveCount);
|
||||||
Value hValue = thisThread->history[pos.piece_on(to_sq(move))][to_sq(move)];
|
Value val = thisThread->history[moved_piece][to_sq(move)]
|
||||||
Value cmhValue = cmh[pos.piece_on(to_sq(move))][to_sq(move)];
|
+ (cmh ? (*cmh )[moved_piece][to_sq(move)] : VALUE_ZERO)
|
||||||
|
+ (fmh ? (*fmh )[moved_piece][to_sq(move)] : VALUE_ZERO)
|
||||||
const CounterMoveStats* fm = (ss - 2)->counterMoves;
|
+ (fmh2 ? (*fmh2)[moved_piece][to_sq(move)] : VALUE_ZERO);
|
||||||
const CounterMoveStats* fm2 = (ss - 4)->counterMoves;
|
|
||||||
Value fmValue = (fm ? (*fm)[pos.piece_on(to_sq(move))][to_sq(move)] : VALUE_ZERO);
|
|
||||||
Value fm2Value = (fm2 ? (*fm2)[pos.piece_on(to_sq(move))][to_sq(move)] : VALUE_ZERO);
|
|
||||||
|
|
||||||
// Increase reduction for cut nodes
|
// Increase reduction for cut nodes
|
||||||
if (!PvNode && cutNode)
|
if (!PvNode && cutNode)
|
||||||
r += ONE_PLY;
|
r += ONE_PLY;
|
||||||
|
|
||||||
// Decrease/increase reduction for moves with a good/bad history
|
// Decrease/increase reduction for moves with a good/bad history
|
||||||
int rHist = (hValue + cmhValue + fmValue + fm2Value - 10000) / 20000;
|
int rHist = (val - 10000) / 20000;
|
||||||
r = std::max(DEPTH_ZERO, r - rHist * ONE_PLY);
|
r = std::max(DEPTH_ZERO, r - rHist * ONE_PLY);
|
||||||
|
|
||||||
// Decrease reduction for moves that escape a capture. Filter out
|
// Decrease reduction for moves that escape a capture. Filter out
|
||||||
|
|
Loading…
Add table
Reference in a new issue