No functional change.
#include "misc.h"
uint8_t PopCnt16[1 << 16];
-int8_t SquareDistance[SQUARE_NB][SQUARE_NB];
+uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
Bitboard SquareBB[SQUARE_NB];
Bitboard ForwardRanksBB[COLOR_NB][RANK_NB];
Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
Bitboard PawnAttacks[COLOR_NB][SQUARE_NB];
+Bitboard KingFlank[FILE_NB] = {
+ QueenSide ^ FileDBB, QueenSide, QueenSide,
+ CenterFiles, CenterFiles,
+ KingSide, KingSide, KingSide ^ FileEBB
+};
+
Magic RookMagics[SQUARE_NB];
Magic BishopMagics[SQUARE_NB];
void init_magics(Bitboard table[], Magic magics[], Direction directions[]);
// popcount16() counts the non-zero bits using SWAR-Popcount algorithm
-
unsigned popcount16(unsigned u) {
u -= (u >> 1) & 0x5555U;
u = ((u >> 2) & 0x3333U) + (u & 0x3333U);
void Bitboards::init() {
for (unsigned i = 0; i < (1 << 16); ++i)
- PopCnt16[i] = (uint8_t) popcount16(i);
+ PopCnt16[i] = (uint8_t)popcount16(i);
for (Square s = SQ_A1; s <= SQ_H8; ++s)
SquareBB[s] = (1ULL << s);
- for (Rank r = RANK_1; r < RANK_8; ++r)
- ForwardRanksBB[WHITE][r] = ~(ForwardRanksBB[BLACK][r + 1] = ForwardRanksBB[BLACK][r] | rank_bb(r));
-
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
- if (s1 != s2)
{
SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
DistanceRingBB[s1][SquareDistance[s1][s2]] |= s2;
for (PieceType pt : { BISHOP, ROOK })
for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
- {
- if (!(PseudoAttacks[pt][s1] & s2))
- continue;
-
- LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2;
- BetweenBB[s1][s2] = attacks_bb(pt, s1, SquareBB[s2]) & attacks_bb(pt, s2, SquareBB[s1]);
- }
+ if (PseudoAttacks[pt][s1] & s2)
+ {
+ LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2;
+ BetweenBB[s1][s2] = attacks_bb(pt, s1, SquareBB[s2]) & attacks_bb(pt, s2, SquareBB[s1]);
+ }
}
}
constexpr Bitboard Rank7BB = Rank1BB << (8 * 6);
constexpr Bitboard Rank8BB = Rank1BB << (8 * 7);
-extern int8_t SquareDistance[SQUARE_NB][SQUARE_NB];
+constexpr Bitboard QueenSide = FileABB | FileBBB | FileCBB | FileDBB;
+constexpr Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
+constexpr Bitboard KingSide = FileEBB | FileFBB | FileGBB | FileHBB;
+constexpr Bitboard Center = (FileDBB | FileEBB) & (Rank4BB | Rank5BB);
+
+extern uint8_t PopCnt16[1 << 16];
+extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
extern Bitboard SquareBB[SQUARE_NB];
-extern Bitboard ForwardRanksBB[COLOR_NB][RANK_NB];
extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
extern Bitboard LineBB[SQUARE_NB][SQUARE_NB];
extern Bitboard DistanceRingBB[SQUARE_NB][8];
extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
extern Bitboard PawnAttacks[COLOR_NB][SQUARE_NB];
+extern Bitboard KingFlank[FILE_NB];
/// Magic holds all magic bitboards relevant data for a single square
return bool(DarkSquares & s1) != bool(DarkSquares & s2);
}
+
/// rank_bb() and file_bb() return a bitboard representing all the squares on
/// the given file or rank.
return shift<EAST>(file_bb(f)) | shift<WEST>(file_bb(f));
}
+
/// between_bb() returns a bitboard representing all the squares between the two
/// given ones. For instance, between_bb(SQ_C4, SQ_F7) returns a bitboard with
-/// the bits for square d5 and e6 set. If s1 and s2 are not on the same rank, file
-/// or diagonal, 0 is returned.
+/// the bits for square d5 and e6 set. If s1 and s2 are not on the same rank,
+/// file or diagonal, 0 is returned.
inline Bitboard between_bb(Square s1, Square s2) {
return BetweenBB[s1][s2];
}
-/// forward_ranks_bb() returns a bitboard representing the squares on all the ranks
+/// forward_ranks_bb() returns a bitboard representing the squares on the ranks
/// in front of the given one, from the point of view of the given color. For instance,
/// forward_ranks_bb(BLACK, SQ_D3) will return the 16 squares on ranks 1 and 2.
inline Bitboard forward_ranks_bb(Color c, Square s) {
- return ForwardRanksBB[c][rank_of(s)];
+ return c == WHITE ? ~Rank1BB << 8 * (rank_of(s) - RANK_1)
+ : ~Rank8BB >> 8 * (RANK_8 - rank_of(s));
}
-/// forward_file_bb() returns a bitboard representing all the squares along the line
-/// in front of the given one, from the point of view of the given color:
-/// ForwardFileBB[c][s] = forward_ranks_bb(c, s) & file_bb(s)
+/// forward_file_bb() returns a bitboard representing all the squares along the
+/// line in front of the given one, from the point of view of the given color.
inline Bitboard forward_file_bb(Color c, Square s) {
- return ForwardRanksBB[c][rank_of(s)] & file_bb(s);
+ return forward_ranks_bb(c, s) & file_bb(s);
}
-/// pawn_attack_span() returns a bitboard representing all the squares that can be
-/// attacked by a pawn of the given color when it moves along its file, starting
-/// from the given square:
+/// pawn_attack_span() returns a bitboard representing all the squares that can
+/// be attacked by a pawn of the given color when it moves along its file,
+/// starting from the given square.
inline Bitboard pawn_attack_span(Color c, Square s) {
return forward_ranks_bb(c, s) & adjacent_files_bb(file_of(s));
}
-/// passed_pawn_mask() returns a bitboard mask which can be used to test if a
-/// pawn of the given color and on the given square is a passed pawn:
+/// passed_pawn_span() returns a bitboard which can be used to test if a pawn of
+/// the given color and on the given square is a passed pawn.
-inline Bitboard passed_pawn_mask(Color c, Square s) {
- return pawn_attack_span(c, s) | forward_file_bb(c, s);
+inline Bitboard passed_pawn_span(Color c, Square s) {
+ return forward_ranks_bb(c, s) & (adjacent_files_bb(file_of(s)) | file_bb(s));
}
/// distance() functions return the distance between x and y, defined as the
/// number of steps for a king in x to reach y. Works with squares, ranks, files.
-template<typename T> inline int distance(T x, T y) { return x < y ? y - x : x - y; }
+template<typename T> inline int distance(T x, T y) { return std::abs(x - y); }
template<> inline int distance<Square>(Square x, Square y) { return SquareDistance[x][y]; }
template<typename T1, typename T2> inline int distance(T2 x, T2 y);
#ifndef USE_POPCNT
- extern uint8_t PopCnt16[1 << 16];
union { Bitboard bb; uint16_t u[4]; } v = { b };
return PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]];
namespace {
- constexpr Bitboard QueenSide = FileABB | FileBBB | FileCBB | FileDBB;
- constexpr Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
- constexpr Bitboard KingSide = FileEBB | FileFBB | FileGBB | FileHBB;
- constexpr Bitboard Center = (FileDBB | FileEBB) & (Rank4BB | Rank5BB);
-
- constexpr Bitboard KingFlank[FILE_NB] = {
- QueenSide ^ FileDBB, QueenSide, QueenSide,
- CenterFiles, CenterFiles,
- KingSide, KingSide, KingSide ^ FileEBB
- };
-
// Threshold for lazy and space evaluation
constexpr Value LazyThreshold = Value(1500);
constexpr Value SpaceThreshold = Value(12222);
constexpr Score KnightOnQueen = S( 16, 12);
constexpr Score LongDiagonalBishop = S( 45, 0);
constexpr Score MinorBehindPawn = S( 18, 3);
+ constexpr Score Outpost = S( 9, 3);
constexpr Score PawnlessFlank = S( 17, 95);
constexpr Score RestrictedPiece = S( 7, 7);
constexpr Score RookOnPawn = S( 10, 32);
constexpr Score TrappedRook = S( 47, 4);
constexpr Score WeakQueen = S( 49, 15);
constexpr Score WeakUnopposedPawn = S( 12, 23);
- constexpr Score Outpost = S( 9, 3);
#undef S
constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
: AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
- Bitboard weak, b, b1, b2, safe, unsafeChecks = 0;
+ Bitboard weak, b1, b2, safe, unsafeChecks = 0;
+ Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
int kingDanger = 0;
const Square ksq = pos.square<KING>(Us);
b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
// Enemy rooks checks
- Bitboard RookCheck = b1
- & safe
- & attackedBy[Them][ROOK];
+ rookChecks = b1 & safe & attackedBy[Them][ROOK];
- if (RookCheck)
+ if (rookChecks)
kingDanger += RookSafeCheck;
else
unsafeChecks |= b1 & attackedBy[Them][ROOK];
// Enemy queen safe checks: we count them only if they are from squares from
// which we can't give a rook check, because rook checks are more valuable.
- Bitboard QueenCheck = (b1 | b2)
- & attackedBy[Them][QUEEN]
- & safe
- & ~attackedBy[Us][QUEEN]
- & ~RookCheck;
+ queenChecks = (b1 | b2)
+ & attackedBy[Them][QUEEN]
+ & safe
+ & ~attackedBy[Us][QUEEN]
+ & ~rookChecks;
- if (QueenCheck)
+ if (queenChecks)
kingDanger += QueenSafeCheck;
// Enemy bishops checks: we count them only if they are from squares from
// which we can't give a queen check, because queen checks are more valuable.
- Bitboard BishopCheck = b2
- & attackedBy[Them][BISHOP]
- & safe
- & ~QueenCheck;
+ bishopChecks = b2
+ & attackedBy[Them][BISHOP]
+ & safe
+ & ~queenChecks;
- if (BishopCheck)
+ if (bishopChecks)
kingDanger += BishopSafeCheck;
else
unsafeChecks |= b2 & attackedBy[Them][BISHOP];
// Enemy knights checks
- b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
+ knightChecks = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
- if (b & safe)
+ if (knightChecks & safe)
kingDanger += KnightSafeCheck;
else
- unsafeChecks |= b;
+ unsafeChecks |= knightChecks;
// Unsafe or occupied checking squares will also be considered, as long as
// the square is in the attacker's mobility area.
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
- Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe, restricted;
+ Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
Score score = SCORE_ZERO;
// Non-pawn enemies
}
// Bonus for restricting their piece moves
- restricted = attackedBy[Them][ALL_PIECES]
- & ~stronglyProtected
- & attackedBy[Us][ALL_PIECES];
- score += RestrictedPiece * popcount(restricted);
+ b = attackedBy[Them][ALL_PIECES]
+ & ~stronglyProtected
+ & attackedBy[Us][ALL_PIECES];
+
+ score += RestrictedPiece * popcount(b);
// Bonus for enemy unopposed weak pawns
if (pos.pieces(Us, ROOK, QUEEN))
<< " ------------+-------------+-------------+------------\n"
<< " Material | " << Term(MATERIAL)
<< " Imbalance | " << Term(IMBALANCE)
- << " Initiative | " << Term(INITIATIVE)
<< " Pawns | " << Term(PAWN)
<< " Knights | " << Term(KNIGHT)
<< " Bishops | " << Term(BISHOP)
<< " Threats | " << Term(THREAT)
<< " Passed | " << Term(PASSED)
<< " Space | " << Term(SPACE)
+ << " Initiative | " << Term(INITIATIVE)
<< " ------------+-------------+-------------+------------\n"
<< " Total | " << Term(TOTAL);
} // namespace
-/// generate<CAPTURES> generates all pseudo-legal captures and queen
-/// promotions. Returns a pointer to the end of the move list.
+/// <CAPTURES> Generates all pseudo-legal captures and queen promotions
+/// <QUIETS> Generates all pseudo-legal non-captures and underpromotions
+/// <NON_EVASIONS> Generates all pseudo-legal captures and non-captures
///
-/// generate<QUIETS> generates all pseudo-legal non-captures and
-/// underpromotions. Returns a pointer to the end of the move list.
-///
-/// generate<NON_EVASIONS> generates all pseudo-legal captures and
-/// non-captures. Returns a pointer to the end of the move list.
+/// Returns a pointer to the end of the move list.
template<GenType Type>
ExtMove* generate(const Position& pos, ExtMove* moveList) {
// Flag the pawn
opposed = theirPawns & forward_file_bb(Us, s);
- stoppers = theirPawns & passed_pawn_mask(Us, s);
+ stoppers = theirPawns & passed_pawn_span(Us, s);
lever = theirPawns & PawnAttacks[Us][s];
leverPush = theirPawns & PawnAttacks[Us][s + Up];
doubled = ourPawns & (s - Up);
}
inline bool Position::pawn_passed(Color c, Square s) const {
- return !(pieces(~c, PAWN) & passed_pawn_mask(c, s));
+ return !(pieces(~c, PAWN) & passed_pawn_span(c, s));
}
inline bool Position::advanced_pawn_push(Move m) const {
// Perform a preliminary qsearch to verify that the move holds
value = -qsearch<NonPV>(pos, ss+1, -raisedBeta, -raisedBeta+1);
- // If the qsearch held perform the regular search
+ // If the qsearch held, perform the regular search
if (value >= raisedBeta)
value = -search<NonPV>(pos, ss+1, -raisedBeta, -raisedBeta+1, depth - 4 * ONE_PLY, !cutNode);
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (c) 2013 Ronald de Man
- Copyright (C) 2016-2018 Marco Costalba, Lucas Braesch
+ Copyright (C) 2016-2019 Marco Costalba, Lucas Braesch
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (c) 2013 Ronald de Man
- Copyright (C) 2016-2018 Marco Costalba, Lucas Braesch
+ Copyright (C) 2016-2019 Marco Costalba, Lucas Braesch
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <algorithm>
#include <cassert>
#include <ostream>
+#include <sstream>
#include "misc.h"
#include "search.h"
bool Option::operator==(const char* s) const {
assert(type == "combo");
- return !CaseInsensitiveLess()(currentValue, s)
- && !CaseInsensitiveLess()(s, currentValue);
+ return !CaseInsensitiveLess()(currentValue, s)
+ && !CaseInsensitiveLess()(s, currentValue);
}
/// operator=() updates currentValue and triggers on_change() action. It's up to
-/// the GUI to check for option's limits, but we could receive the new value from
-/// the user by console window, so let's check the bounds anyway.
+/// the GUI to check for option's limits, but we could receive the new value
+/// from the user by console window, so let's check the bounds anyway.
Option& Option::operator=(const string& v) {
|| (type == "spin" && (stof(v) < min || stof(v) > max)))
return *this;
+ if (type == "combo")
+ {
+ OptionsMap comboMap; // To have case insensitive compare
+ string token;
+ std::istringstream ss(defaultValue);
+ while (ss >> token)
+ comboMap[token] << Option();
+ if (!comboMap.count(v) || v == "var")
+ return *this;
+ }
+
if (type != "button")
currentValue = v;