/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
- Copyright (C) 2004-2020 The Stockfish developers (see AUTHORS file)
+ Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/// _WIN32 Building on Windows (any)
/// _WIN64 Building on Windows 64 bit
+#if defined(__GNUC__ ) && (__GNUC__ < 9 || (__GNUC__ == 9 && __GNUC_MINOR__ <= 2)) && defined(_WIN32) && !defined(__clang__)
+#define ALIGNAS_ON_STACK_VARIABLES_BROKEN
+#endif
+
+#define ASSERT_ALIGNED(ptr, alignment) assert(reinterpret_cast<uintptr_t>(ptr) % alignment == 0)
+
#if defined(_WIN64) && defined(_MSC_VER) // No Makefile used
# include <intrin.h> // Microsoft header for _BitScanForward64()
# define IS_64BIT
# define pext(b, m) 0
#endif
+namespace Stockfish {
+
#ifdef USE_POPCNT
constexpr bool HasPopCnt = true;
#else
/// bit 6-11: origin square (from 0 to 63)
/// bit 12-13: promotion piece type - 2 (from KNIGHT-2 to QUEEN-2)
/// bit 14-15: special move flag: promotion (1), en passant (2), castling (3)
-/// NOTE: EN-PASSANT bit is set only when a pawn can be captured
+/// NOTE: en passant bit is set only when a pawn can be captured
///
/// Special cases are MOVE_NONE and MOVE_NULL. We can sneak these in because in
/// any normal move destination square is always different from origin square
enum MoveType {
NORMAL,
PROMOTION = 1 << 14,
- ENPASSANT = 2 << 14,
+ EN_PASSANT = 2 << 14,
CASTLING = 3 << 14
};
VALUE_MATE_IN_MAX_PLY = VALUE_MATE - MAX_PLY,
VALUE_MATED_IN_MAX_PLY = -VALUE_MATE_IN_MAX_PLY,
+ // In the code, we make the assumption that these values
+ // are such that non_pawn_material() can be used to uniquely
+ // identify the material on the board.
PawnValueMg = 126, PawnValueEg = 208,
KnightValueMg = 781, KnightValueEg = 854,
BishopValueMg = 825, BishopValueEg = 915,
RookValueMg = 1276, RookValueEg = 1380,
QueenValueMg = 2538, QueenValueEg = 2682,
- Tempo = 28,
MidgameLimit = 15258, EndgameLimit = 3915
};
enum Piece {
NO_PIECE,
- W_PAWN = 1, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
- B_PAWN = 9, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING,
+ W_PAWN = PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
+ B_PAWN = PAWN + 8, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING,
PIECE_NB = 16
};
-// An ID used to track the pieces. Max. 32 pieces on board.
-enum PieceId {
- PIECE_ID_ZERO = 0,
- PIECE_ID_KING = 30,
- PIECE_ID_WKING = 30,
- PIECE_ID_BKING = 31,
- PIECE_ID_NONE = 32
-};
-
-inline PieceId operator++(PieceId& d, int) {
-
- PieceId x = d;
- d = PieceId(int(d) + 1);
- return x;
-}
-
constexpr Value PieceValue[PHASE_NB][PIECE_NB] = {
{ VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg, VALUE_ZERO, VALUE_ZERO,
VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg, VALUE_ZERO, VALUE_ZERO },
DEPTH_QS_RECAPTURES = -5,
DEPTH_NONE = -6,
- DEPTH_OFFSET = DEPTH_NONE
+
+ DEPTH_OFFSET = -7 // value used only for TT entry occupancy check
};
enum Square : int {
RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8, RANK_NB
};
-// unique number for each piece type on each square
-enum PieceSquare : uint32_t {
- PS_NONE = 0,
- PS_W_PAWN = 1,
- PS_B_PAWN = 1 * SQUARE_NB + 1,
- PS_W_KNIGHT = 2 * SQUARE_NB + 1,
- PS_B_KNIGHT = 3 * SQUARE_NB + 1,
- PS_W_BISHOP = 4 * SQUARE_NB + 1,
- PS_B_BISHOP = 5 * SQUARE_NB + 1,
- PS_W_ROOK = 6 * SQUARE_NB + 1,
- PS_B_ROOK = 7 * SQUARE_NB + 1,
- PS_W_QUEEN = 8 * SQUARE_NB + 1,
- PS_B_QUEEN = 9 * SQUARE_NB + 1,
- PS_W_KING = 10 * SQUARE_NB + 1,
- PS_END = PS_W_KING, // pieces without kings (pawns included)
- PS_B_KING = 11 * SQUARE_NB + 1,
- PS_END2 = 12 * SQUARE_NB + 1
-};
-
-struct ExtPieceSquare {
- PieceSquare from[COLOR_NB];
-};
-
-// Array for finding the PieceSquare corresponding to the piece on the board
-extern ExtPieceSquare kpp_board_index[PIECE_NB];
-
-constexpr bool is_ok(PieceId pid);
-constexpr Square rotate180(Square sq);
-
-// Structure holding which tracked piece (PieceId) is where (PieceSquare)
-class EvalList {
-
-public:
- // Max. number of pieces without kings is 30 but must be a multiple of 4 in AVX2
- static const int MAX_LENGTH = 32;
-
- // Array that holds the piece id for the pieces on the board
- PieceId piece_id_list[SQUARE_NB];
-
- // List of pieces, separate from White and Black POV
- PieceSquare* piece_list_fw() const { return const_cast<PieceSquare*>(pieceListFw); }
- PieceSquare* piece_list_fb() const { return const_cast<PieceSquare*>(pieceListFb); }
-
- // Place the piece pc with piece_id on the square sq on the board
- void put_piece(PieceId piece_id, Square sq, Piece pc)
- {
- assert(is_ok(piece_id));
- if (pc != NO_PIECE)
- {
- pieceListFw[piece_id] = PieceSquare(kpp_board_index[pc].from[WHITE] + sq);
- pieceListFb[piece_id] = PieceSquare(kpp_board_index[pc].from[BLACK] + rotate180(sq));
- piece_id_list[sq] = piece_id;
- }
- else
- {
- pieceListFw[piece_id] = PS_NONE;
- pieceListFb[piece_id] = PS_NONE;
- piece_id_list[sq] = piece_id;
- }
- }
-
- // Convert the specified piece_id piece to ExtPieceSquare type and return it
- ExtPieceSquare piece_with_id(PieceId piece_id) const
- {
- ExtPieceSquare eps;
- eps.from[WHITE] = pieceListFw[piece_id];
- eps.from[BLACK] = pieceListFb[piece_id];
- return eps;
- }
-
-private:
- PieceSquare pieceListFw[MAX_LENGTH];
- PieceSquare pieceListFb[MAX_LENGTH];
-};
-
-// For differential evaluation of pieces that changed since last turn
+// Keep track of what a move changes on the board (used by NNUE)
struct DirtyPiece {
// Number of changed pieces
int dirty_num;
- // The ids of changed pieces, max. 2 pieces can change in one move
- PieceId pieceId[2];
+ // Max 3 pieces can change in one move. A promotion with capture moves
+ // both the pawn and the captured piece to SQ_NONE and the piece promoted
+ // to from SQ_NONE to the capture square.
+ Piece piece[3];
- // What changed from the piece with that piece number
- ExtPieceSquare old_piece[2];
- ExtPieceSquare new_piece[2];
+ // From and to squares, which may be SQ_NONE
+ Square from[3];
+ Square to[3];
};
/// Score enum stores a middlegame and an endgame value in a single integer (enum).
ENABLE_FULL_OPERATORS_ON(Direction)
ENABLE_INCR_OPERATORS_ON(Piece)
-ENABLE_INCR_OPERATORS_ON(PieceSquare)
-ENABLE_INCR_OPERATORS_ON(PieceId)
ENABLE_INCR_OPERATORS_ON(PieceType)
ENABLE_INCR_OPERATORS_ON(Square)
ENABLE_INCR_OPERATORS_ON(File)
return Color(pc >> 3);
}
-constexpr bool is_ok(PieceId pid) {
- return pid < PIECE_ID_NONE;
-}
-
constexpr bool is_ok(Square s) {
return s >= SQ_A1 && s <= SQ_H8;
}
return Square(m & 0x3F);
}
-// Return relative square when turning the board 180 degrees
-constexpr Square rotate180(Square sq) {
- return (Square)(sq ^ 0x3F);
-}
-
constexpr int from_to(Move m) {
- return m & 0xFFF;
+ return m & 0xFFF;
}
constexpr MoveType type_of(Move m) {
return Move((from << 6) + to);
}
-constexpr Move reverse_move(Move m) {
- return make_move(to_sq(m), from_sq(m));
-}
-
template<MoveType T>
constexpr Move make(Square from, Square to, PieceType pt = KNIGHT) {
return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);
return seed * 6364136223846793005ULL + 1442695040888963407ULL;
}
+} // namespace Stockfish
+
#endif // #ifndef TYPES_H_INCLUDED
#include "tune.h" // Global visibility to tuning setup