X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Ftypes.h;h=bfcd3f23f11cf07b16d1366495c4afdd74530ace;hp=3cb93a649a6e5f3c0d2e4062675675b8684664ba;hb=ddcbacd04d1c860e808202ce8c1206c8acdca627;hpb=54f6ce70fd68b38f053cd7d338bed1a74d92bb8b diff --git a/src/types.h b/src/types.h index 3cb93a64..bfcd3f23 100644 --- a/src/types.h +++ b/src/types.h @@ -2,7 +2,7 @@ Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad - Copyright (C) 2015-2017 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad + Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,6 +43,7 @@ #include #include #include +#include #if defined(_MSC_VER) // Disable some silly and noisy warning from MSVC compiler @@ -80,28 +81,28 @@ #endif #ifdef USE_POPCNT -const bool HasPopCnt = true; +constexpr bool HasPopCnt = true; #else -const bool HasPopCnt = false; +constexpr bool HasPopCnt = false; #endif #ifdef USE_PEXT -const bool HasPext = true; +constexpr bool HasPext = true; #else -const bool HasPext = false; +constexpr bool HasPext = false; #endif #ifdef IS_64BIT -const bool Is64Bit = true; +constexpr bool Is64Bit = true; #else -const bool Is64Bit = false; +constexpr bool Is64Bit = false; #endif typedef uint64_t Key; typedef uint64_t Bitboard; -const int MAX_MOVES = 256; -const int MAX_PLY = 128; +constexpr int MAX_MOVES = 256; +constexpr int MAX_PLY = 246; /// A move needs 16 bits to be stored /// @@ -131,24 +132,20 @@ enum Color { WHITE, BLACK, COLOR_NB = 2 }; -enum CastlingSide { - KING_SIDE, QUEEN_SIDE, CASTLING_SIDE_NB = 2 -}; - -enum CastlingRight { +enum CastlingRights { NO_CASTLING, WHITE_OO, WHITE_OOO = WHITE_OO << 1, BLACK_OO = WHITE_OO << 2, BLACK_OOO = WHITE_OO << 3, - ANY_CASTLING = WHITE_OO | WHITE_OOO | BLACK_OO | BLACK_OOO, - CASTLING_RIGHT_NB = 16 -}; -template struct MakeCastling { - static constexpr CastlingRight - right = C == WHITE ? S == QUEEN_SIDE ? WHITE_OOO : WHITE_OO - : S == QUEEN_SIDE ? BLACK_OOO : BLACK_OO; + KING_SIDE = WHITE_OO | BLACK_OO, + QUEEN_SIDE = WHITE_OOO | BLACK_OOO, + WHITE_CASTLING = WHITE_OO | WHITE_OOO, + BLACK_CASTLING = BLACK_OO | BLACK_OOO, + ANY_CASTLING = WHITE_CASTLING | BLACK_CASTLING, + + CASTLING_RIGHT_NB = 16 }; enum Phase { @@ -159,7 +156,6 @@ enum Phase { enum ScaleFactor { SCALE_FACTOR_DRAW = 0, - SCALE_FACTOR_ONEPAWN = 48, SCALE_FACTOR_NORMAL = 64, SCALE_FACTOR_MAX = 128, SCALE_FACTOR_NONE = 255 @@ -180,14 +176,17 @@ enum Value : int { VALUE_INFINITE = 32001, VALUE_NONE = 32002, - VALUE_MATE_IN_MAX_PLY = VALUE_MATE - 2 * MAX_PLY, - VALUE_MATED_IN_MAX_PLY = -VALUE_MATE + 2 * MAX_PLY, + VALUE_TB_WIN_IN_MAX_PLY = VALUE_MATE - 2 * MAX_PLY, + VALUE_TB_LOSS_IN_MAX_PLY = -VALUE_MATE + 2 * MAX_PLY, + VALUE_MATE_IN_MAX_PLY = VALUE_MATE - MAX_PLY, + VALUE_MATED_IN_MAX_PLY = -VALUE_MATE + MAX_PLY, - PawnValueMg = 171, PawnValueEg = 240, - KnightValueMg = 764, KnightValueEg = 848, - BishopValueMg = 826, BishopValueEg = 891, - RookValueMg = 1282, RookValueEg = 1373, - QueenValueMg = 2526, QueenValueEg = 2646, + PawnValueMg = 128, PawnValueEg = 213, + KnightValueMg = 781, KnightValueEg = 854, + BishopValueMg = 825, BishopValueEg = 915, + RookValueMg = 1276, RookValueEg = 1380, + QueenValueMg = 2538, QueenValueEg = 2682, + Tempo = 28, MidgameLimit = 15258, EndgameLimit = 3915 }; @@ -195,7 +194,6 @@ enum Value : int { enum PieceType { NO_PIECE_TYPE, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, ALL_PIECES = 0, - QUEEN_DIAGONAL = 7, PIECE_TYPE_NB = 8 }; @@ -206,23 +204,25 @@ enum Piece { PIECE_NB = 16 }; -extern Value PieceValue[PHASE_NB][PIECE_NB]; +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 }, + { VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg, VALUE_ZERO, VALUE_ZERO, + VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg, VALUE_ZERO, VALUE_ZERO } +}; -enum Depth : int { +typedef int Depth; - ONE_PLY = 1, +enum : int { - DEPTH_ZERO = 0 * ONE_PLY, - DEPTH_QS_CHECKS = 0 * ONE_PLY, - DEPTH_QS_NO_CHECKS = -1 * ONE_PLY, - DEPTH_QS_RECAPTURES = -5 * ONE_PLY, + DEPTH_QS_CHECKS = 0, + DEPTH_QS_NO_CHECKS = -1, + DEPTH_QS_RECAPTURES = -5, - DEPTH_NONE = -6 * ONE_PLY, - DEPTH_MAX = MAX_PLY * ONE_PLY + DEPTH_NONE = -6, + DEPTH_OFFSET = DEPTH_NONE }; -static_assert(!(ONE_PLY & (ONE_PLY - 1)), "ONE_PLY is not a power of 2"); - enum Square : int { SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_F1, SQ_G1, SQ_H1, SQ_A2, SQ_B2, SQ_C2, SQ_D2, SQ_E2, SQ_F2, SQ_G2, SQ_H2, @@ -258,10 +258,10 @@ enum Rank : int { }; -/// Score enum stores a middlegame and an endgame value in a single integer -/// (enum). The least significant 16 bits are used to store the endgame value -/// and the upper 16 bits are used to store the middlegame value. Take some -/// care to avoid left-shifting a signed int to avoid undefined behavior. +/// Score enum stores a middlegame and an endgame value in a single integer (enum). +/// The least significant 16 bits are used to store the middlegame value and the +/// upper 16 bits are used to store the endgame value. We have to take care to +/// avoid left-shifting a signed int to avoid undefined behavior. enum Score : int { SCORE_ZERO }; constexpr Score make_score(int mg, int eg) { @@ -294,7 +294,6 @@ inline T& operator--(T& d) { return d = T(int(d) - 1); } #define ENABLE_FULL_OPERATORS_ON(T) \ ENABLE_BASE_OPERATORS_ON(T) \ -ENABLE_INCR_OPERATORS_ON(T) \ constexpr T operator*(int i, T d) { return T(i * int(d)); } \ constexpr T operator*(T d, int i) { return T(int(d) * i); } \ constexpr T operator/(T d, int i) { return T(int(d) / i); } \ @@ -303,12 +302,10 @@ inline T& operator*=(T& d, int i) { return d = T(int(d) * i); } \ inline T& operator/=(T& d, int i) { return d = T(int(d) / i); } ENABLE_FULL_OPERATORS_ON(Value) -ENABLE_FULL_OPERATORS_ON(Depth) ENABLE_FULL_OPERATORS_ON(Direction) ENABLE_INCR_OPERATORS_ON(PieceType) ENABLE_INCR_OPERATORS_ON(Piece) -ENABLE_INCR_OPERATORS_ON(Color) ENABLE_INCR_OPERATORS_ON(Square) ENABLE_INCR_OPERATORS_ON(File) ENABLE_INCR_OPERATORS_ON(Rank) @@ -326,10 +323,10 @@ inline Value& operator+=(Value& v, int i) { return v = v + i; } inline Value& operator-=(Value& v, int i) { return v = v - i; } /// Additional operators to add a Direction to a Square -inline Square operator+(Square s, Direction d) { return Square(int(s) + int(d)); } -inline Square operator-(Square s, Direction d) { return Square(int(s) - int(d)); } -inline Square& operator+=(Square &s, Direction d) { return s = s + d; } -inline Square& operator-=(Square &s, Direction d) { return s = s - d; } +constexpr Square operator+(Square s, Direction d) { return Square(int(s) + int(d)); } +constexpr Square operator-(Square s, Direction d) { return Square(int(s) - int(d)); } +inline Square& operator+=(Square& s, Direction d) { return s = s + d; } +inline Square& operator-=(Square& s, Direction d) { return s = s - d; } /// Only declared but not defined. We don't want to multiply two scores due to /// a very high risk of overflow. So user should explicitly convert to integer. @@ -347,29 +344,34 @@ inline Score operator*(Score s, int i) { assert(eg_value(result) == (i * eg_value(s))); assert(mg_value(result) == (i * mg_value(s))); - assert((i == 0) || (result / i) == s ); + assert((i == 0) || (result / i) == s); return result; } +/// Multiplication of a Score by a boolean +inline Score operator*(Score s, bool b) { + return Score(int(s) * int(b)); +} + constexpr Color operator~(Color c) { return Color(c ^ BLACK); // Toggle color } -constexpr Square operator~(Square s) { - return Square(s ^ SQ_A8); // Vertical flip SQ_A1 -> SQ_A8 +constexpr Square flip_rank(Square s) { + return Square(s ^ SQ_A8); } -constexpr File operator~(File f) { - return File(f ^ FILE_H); // Horizontal flip FILE_A -> FILE_H +constexpr Square flip_file(Square s) { + return Square(s ^ SQ_H1); } constexpr Piece operator~(Piece pc) { return Piece(pc ^ 8); // Swap color of piece B_KNIGHT -> W_KNIGHT } -constexpr CastlingRight operator|(Color c, CastlingSide s) { - return CastlingRight(WHITE_OO << ((s == QUEEN_SIDE) + 2 * c)); +constexpr CastlingRights operator&(Color c, CastlingRights cr) { + return CastlingRights((c == WHITE ? WHITE_CASTLING : BLACK_CASTLING) & cr); } constexpr Value mate_in(int ply) { @@ -421,11 +423,6 @@ constexpr Rank relative_rank(Color c, Square s) { return relative_rank(c, rank_of(s)); } -inline bool opposite_colors(Square s1, Square s2) { - int s = int(s1) ^ int(s2); - return ((s >> 3) ^ s) & 1; -} - constexpr Direction pawn_push(Color c) { return c == WHITE ? NORTH : SOUTH; } @@ -450,10 +447,14 @@ constexpr PieceType promotion_type(Move m) { return PieceType(((m >> 12) & 3) + KNIGHT); } -inline Move make_move(Square from, Square to) { +constexpr Move make_move(Square from, Square to) { return Move((from << 6) + to); } +constexpr Move reverse_move(Move m) { + return make_move(to_sq(m), from_sq(m)); +} + template constexpr Move make(Square from, Square to, PieceType pt = KNIGHT) { return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);