#include "misc.h"
uint8_t PopCnt16[1 << 16];
- int SquareDistance[SQUARE_NB][SQUARE_NB];
+ int8_t SquareDistance[SQUARE_NB][SQUARE_NB];
+Bitboard BoardSizeBB[FILE_NB][RANK_NB];
Bitboard SquareBB[SQUARE_NB];
Bitboard FileBB[FILE_NB];
Bitboard RankBB[RANK_NB];
for (unsigned i = 0; i < (1 << 16); ++i)
PopCnt16[i] = (uint8_t) popcount16(i);
- for (Square s = SQ_A1; s <= SQ_H8; ++s)
- SquareBB[s] = (1ULL << s);
+ for (Square s = SQ_A1; s <= SQ_MAX; ++s)
+ SquareBB[s] = make_bitboard(s);
- for (File f = FILE_A; f <= FILE_H; ++f)
+ for (File f = FILE_A; f <= FILE_MAX; ++f)
FileBB[f] = f > FILE_A ? FileBB[f - 1] << 1 : FileABB;
- for (Rank r = RANK_1; r <= RANK_8; ++r)
- RankBB[r] = r > RANK_1 ? RankBB[r - 1] << 8 : Rank1BB;
+ for (Rank r = RANK_1; r <= RANK_MAX; ++r)
+ RankBB[r] = r > RANK_1 ? RankBB[r - 1] << FILE_NB : Rank1BB;
- for (File f = FILE_A; f <= FILE_MAX; ++f)
- AdjacentFilesBB[f] = (f > FILE_A ? FileBB[f - 1] : 0) | (f < FILE_MAX ? FileBB[f + 1] : 0);
-
- for (Rank r = RANK_1; r < RANK_8; ++r)
+ for (Rank r = RANK_1; r < RANK_MAX; ++r)
ForwardRanksBB[WHITE][r] = ~(ForwardRanksBB[BLACK][r + 1] = ForwardRanksBB[BLACK][r] | RankBB[r]);
for (Color c = WHITE; c <= BLACK; ++c)
- for (Square s = SQ_A1; s <= SQ_H8; ++s)
+ for (Square s = SQ_A1; s <= SQ_MAX; ++s)
{
ForwardFileBB [c][s] = ForwardRanksBB[c][rank_of(s)] & FileBB[file_of(s)];
- PawnAttackSpan[c][s] = ForwardRanksBB[c][rank_of(s)] & AdjacentFilesBB[file_of(s)];
+ PawnAttackSpan[c][s] = ForwardRanksBB[c][rank_of(s)] & adjacent_files_bb(file_of(s));
PassedPawnMask[c][s] = ForwardFileBB [c][s] | PawnAttackSpan[c][s];
}
constexpr Bitboard FileFBB = FileABB << 5;
constexpr Bitboard FileGBB = FileABB << 6;
constexpr Bitboard FileHBB = FileABB << 7;
+#ifdef LARGEBOARDS
+constexpr Bitboard FileIBB = FileABB << 8;
+constexpr Bitboard FileJBB = FileABB << 9;
+constexpr Bitboard FileKBB = FileABB << 10;
+constexpr Bitboard FileLBB = FileABB << 11;
+#endif
+
+#ifdef LARGEBOARDS
+constexpr Bitboard Rank1BB = 0xFFF;
+#else
constexpr Bitboard Rank1BB = 0xFF;
-constexpr Bitboard Rank2BB = Rank1BB << (8 * 1);
-constexpr Bitboard Rank3BB = Rank1BB << (8 * 2);
-constexpr Bitboard Rank4BB = Rank1BB << (8 * 3);
-constexpr Bitboard Rank5BB = Rank1BB << (8 * 4);
-constexpr Bitboard Rank6BB = Rank1BB << (8 * 5);
-constexpr Bitboard Rank7BB = Rank1BB << (8 * 6);
-constexpr Bitboard Rank8BB = Rank1BB << (8 * 7);
+#endif
+constexpr Bitboard Rank2BB = Rank1BB << (FILE_NB * 1);
+constexpr Bitboard Rank3BB = Rank1BB << (FILE_NB * 2);
+constexpr Bitboard Rank4BB = Rank1BB << (FILE_NB * 3);
+constexpr Bitboard Rank5BB = Rank1BB << (FILE_NB * 4);
+constexpr Bitboard Rank6BB = Rank1BB << (FILE_NB * 5);
+constexpr Bitboard Rank7BB = Rank1BB << (FILE_NB * 6);
+constexpr Bitboard Rank8BB = Rank1BB << (FILE_NB * 7);
+#ifdef LARGEBOARDS
+constexpr Bitboard Rank9BB = Rank1BB << (FILE_NB * 8);
+constexpr Bitboard Rank10BB = Rank1BB << (FILE_NB * 9);
+#endif
- extern int SquareDistance[SQUARE_NB][SQUARE_NB];
+ extern int8_t SquareDistance[SQUARE_NB][SQUARE_NB];
+extern Bitboard BoardSizeBB[FILE_NB][RANK_NB];
extern Bitboard SquareBB[SQUARE_NB];
extern Bitboard FileBB[FILE_NB];
extern Bitboard RankBB[RANK_NB];
template<Tracing T> template<Color Us>
Score Evaluation<T>::space() const {
- if (pos.non_pawn_material() < SpaceThreshold)
+ bool pawnsOnly = !(pos.pieces(Us) ^ pos.pieces(Us, PAWN));
+
+ if (pos.non_pawn_material() < SpaceThreshold && !pos.captures_to_hand() && !pawnsOnly)
return SCORE_ZERO;
- constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
+ constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
+ constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
constexpr Bitboard SpaceMask =
Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
: CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
// Find the available squares for our pieces inside the area defined by SpaceMask
Bitboard safe = SpaceMask
- & ~pos.pieces(Us, PAWN)
- & ~attackedBy[Them][PAWN];
+ & ~pos.pieces(Us, PAWN, SHOGI_PAWN)
+ & ~attackedBy[Them][PAWN]
+ & ~attackedBy[Them][SHOGI_PAWN];
+
+ if (pawnsOnly)
+ safe = pos.pieces(Us, PAWN) & ~attackedBy[Them][ALL_PIECES];
// Find all squares which are at most three squares behind some friendly pawn
- Bitboard behind = pos.pieces(Us, PAWN);
+ Bitboard behind = pos.pieces(Us, PAWN, SHOGI_PAWN);
- behind |= (Us == WHITE ? behind >> NORTH : behind << NORTH);
- behind |= (Us == WHITE ? behind >> (2 * NORTH) : behind << (2 * NORTH));
-
+ behind |= shift<Down>(behind);
+ behind |= shift<Down>(shift<Down>(behind));
int bonus = popcount(safe) + popcount(behind & safe);
int weight = pos.count<ALL_PIECES>(Us)
Bitboard blockers = 0;
pinners = 0;
+ if (s == SQ_NONE || !sliders)
+ return blockers;
+
- // Snipers are sliders that attack 's' when a piece is removed
+ // Snipers are sliders that attack 's' when a piece and other snipers are removed
- Bitboard snipers = ( (PseudoAttacks[ ROOK][s] & pieces(QUEEN, ROOK))
- | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
+ Bitboard snipers = 0;
+
+ for (PieceType pt : piece_types())
+ {
+ Bitboard b = sliders & (PseudoAttacks[~c][pt][s] ^ LeaperAttacks[~c][pt][s]) & pieces(c, pt);
+ if (b)
+ snipers |= b & ~attacks_from(~c, pt, s);
+ }
+ Bitboard occupancy = pieces() & ~snipers;
while (snipers)
{
ss->staticEval = eval = pureStaticEval + bonus;
}
else
- ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::Tempo;
+ ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::tempo_value(pos);
- tte->save(posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE, pureStaticEval);
+ tte->save(posKey, VALUE_NONE, pvHit, BOUND_NONE, DEPTH_NONE, MOVE_NONE, pureStaticEval);
}
// Step 7. Razoring (~2 Elo)
if ((ss-1)->moveCount > 15)
r -= ONE_PLY;
- if (!captureOrPromotion)
+ if (!captureOrPromotion && !(pos.must_capture() && MoveList<CAPTURES>(pos).size()))
{
- // Decrease reduction for exact PV nodes (~0 Elo)
- if (pvExact)
- r -= ONE_PLY;
-
// Increase reduction if ttMove is a capture (~0 Elo)
if (ttCapture)
r += ONE_PLY;
// All legal moves have been searched. A special case: If we're in check
// and no legal moves were found, it is checkmate.
if (inCheck && bestValue == -VALUE_INFINITE)
- return mated_in(ss->ply); // Plies to mate from the root
+ return pos.checkmate_value(ss->ply); // Plies to mate from the root
- tte->save(posKey, value_to_tt(bestValue, ss->ply),
+ tte->save(posKey, value_to_tt(bestValue, ss->ply), pvHit,
bestValue >= beta ? BOUND_LOWER :
PvNode && bestValue > oldAlpha ? BOUND_EXACT : BOUND_UPPER,
ttDepth, bestMove, ss->staticEval);
#include "misc.h"
#include "types.h"
-/// TTEntry struct is the 10 bytes transposition table entry, defined as below:
+/// TTEntry struct is the 12 bytes transposition table entry, defined as below:
///
+/// move 32 bit
/// key 16 bit
-/// move 16 bit
/// value 16 bit
/// eval value 16 bit
- /// generation 6 bit
+ /// generation 5 bit
+ /// PvNode 1 bit
/// bound type 2 bit
/// depth 8 bit
token.clear(); // Avoid a stale if getline() returns empty or blank line
is >> skipws >> token;
- // The GUI sends 'ponderhit' to tell us the user has played the expected move.
- // So 'ponderhit' will be sent if we were told to ponder on the same move the
- // user has played. We should continue searching but switch from pondering to
- // normal search. In case Threads.stopOnPonderhit is set we are waiting for
- // 'ponderhit' to stop the search, for instance if max search depth is reached.
if ( token == "quit"
- || token == "stop"
- || (token == "ponderhit" && Threads.stopOnPonderhit))
+ || token == "stop")
Threads.stop = true;
+ // The GUI sends 'ponderhit' to tell us the user has played the expected move.
+ // So 'ponderhit' will be sent if we were told to ponder on the same move the
+ // user has played. We should continue searching but switch from pondering to
+ // normal search.
else if (token == "ponderhit")
- Threads.ponder = false; // Switch to normal search
+ Threads.main()->ponder = false; // Switch to normal search
- else if (token == "uci")
+ else if (token == "uci" || token == "usi")
+ {
+ Options["Protocol"] = token;
sync_cout << "id name " << engine_info(true)
<< "\n" << Options
- << "\nuciok" << sync_endl;
+ << "\n" << token << "ok" << sync_endl;
+ }
else if (token == "setoption") setoption(is);
else if (token == "go") go(pos, is, states);