Rev 169 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 169 | Rev 185 | ||
---|---|---|---|
Line 4... | Line 4... | ||
4 | Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad |
4 | Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad |
5 | Copyright (C) 2015- |
5 | Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad |
6 | 6 | ||
7 | Stockfish is free software: you can redistribute it and/or modify |
7 | Stockfish is free software: you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation, either version 3 of the License, or |
9 | the Free Software Foundation, either version 3 of the License, or |
10 | (at your option) any later version. |
10 | (at your option) any later version. |
Line 21... | Line 21... | ||
21 | #ifndef MOVEPICK_H_INCLUDED |
21 | #ifndef MOVEPICK_H_INCLUDED |
22 | #define MOVEPICK_H_INCLUDED |
22 | #define MOVEPICK_H_INCLUDED |
23 | 23 | ||
24 | #include <array> |
24 | #include <array> |
25 | #include <limits> |
25 | #include <limits> |
- | 26 | #include <type_traits> |
|
26 | 27 | ||
27 | #include "movegen.h" |
28 | #include "movegen.h" |
28 | #include "position.h" |
29 | #include "position.h" |
29 | #include "types.h" |
30 | #include "types.h" |
30 | 31 | ||
31 | /// |
32 | /// StatsEntry stores the stat table value. It is usually a number but could |
- | 33 | /// be a move or even a nested history. We use a class instead of naked value |
|
32 |
|
34 | /// to directly call history update operator<<() on the entry so to use stats |
33 |
|
35 | /// tables at caller sites as simple multi-dim arrays. |
- | 36 | template<typename T, int D> |
|
- | 37 | class StatsEntry { |
|
34 | 38 | ||
35 | void fill(const T& v) { |
- | |
36 | T* p = &(*this)[0][0]; |
- | |
37 | std::fill(p, p + sizeof(*this) / sizeof(*p), v); |
- | |
38 |
|
39 | T entry; |
39 | 40 | ||
- | 41 | public: |
|
40 | void |
42 | void operator=(const T& v) { entry = v; } |
- | 43 | T* operator&() { return &entry; } |
|
- | 44 | T* operator->() { return &entry; } |
|
- | 45 | operator const T&() const { return entry; } |
|
41 | 46 | ||
- | 47 | void operator<<(int bonus) { |
|
42 | assert(abs(bonus) <= D); // Ensure range is [- |
48 | assert(abs(bonus) <= D); // Ensure range is [-D, D] |
43 |
|
49 | static_assert(D <= std::numeric_limits<T>::max(), "D overflows T"); |
44 | 50 | ||
45 | entry += bonus |
51 | entry += bonus - entry * abs(bonus) / D; |
46 | 52 | ||
47 | assert(abs(entry) <= |
53 | assert(abs(entry) <= D); |
48 | } |
54 | } |
49 | }; |
55 | }; |
50 | 56 | ||
51 | /// |
57 | /// Stats is a generic N-dimensional array used to store various statistics. |
- | 58 | /// The first template parameter T is the base type of the array, the second |
|
- | 59 | /// template parameter D limits the range of updates in [-D, D] when we update |
|
- | 60 | /// values with the << operator, while the last parameters (Size and Sizes) |
|
- | 61 | /// encode the dimensions of the array. |
|
52 | template< |
62 | template <typename T, int D, int Size, int... Sizes> |
53 | struct |
63 | struct Stats : public std::array<Stats<T, D, Sizes...>, Size> |
- | 64 | { |
|
- | 65 | typedef Stats<T, D, Size, Sizes...> stats; |
|
54 | 66 | ||
55 | void fill(const T& v) { |
67 | void fill(const T& v) { |
56 | T* p = &(*this)[0][0][0]; |
- | |
57 | std::fill(p, p + sizeof(*this) / sizeof(*p), v); |
- | |
58 | } |
- | |
59 | - | ||
60 | void update(T& entry, int bonus, const int D, const int W) { |
- | |
61 | - | ||
62 | assert(abs(bonus) <= D); // Ensure range is [-W * D, W * D] |
- | |
63 | assert(abs(W * D) < (std::numeric_limits<T>::max)()); // Ensure we don't overflow |
- | |
64 | 68 | ||
- | 69 | // For standard-layout 'this' points to first struct member |
|
65 |
|
70 | assert(std::is_standard_layout<stats>::value); |
66 | 71 | ||
67 |
|
72 | typedef StatsEntry<T, D> entry; |
- | 73 | entry* p = reinterpret_cast<entry*>(this); |
|
- | 74 | std::fill(p, p + sizeof(*this) / sizeof(entry), v); |
|
68 | } |
75 | } |
69 | }; |
76 | }; |
70 | 77 | ||
71 |
|
78 | template <typename T, int D, int Size> |
72 | /// and to squares, see chessprogramming.wikispaces.com/Butterfly+Boards |
- | |
73 |
|
79 | struct Stats<T, D, Size> : public std::array<StatsEntry<T, D>, Size> {}; |
74 | 80 | ||
75 | /// |
81 | /// In stats table, D=0 means that the template parameter is not used |
76 |
|
82 | enum StatsParams { NOT_USED = 0 }; |
77 | 83 | ||
78 | /// CapturePieceToBoards are addressed by a move's [piece][to][captured piece type] information |
- | |
79 | typedef StatCubes<PIECE_NB, SQUARE_NB, PIECE_TYPE_NB> CapturePieceToBoards; |
- | |
80 | 84 | ||
81 | /// ButterflyHistory records how often quiet moves have been successful or |
85 | /// ButterflyHistory records how often quiet moves have been successful or |
82 | /// unsuccessful during the current search, and is used for reduction and move |
86 | /// unsuccessful during the current search, and is used for reduction and move |
83 | /// ordering decisions. It uses |
87 | /// ordering decisions. It uses 2 tables (one for each color) indexed by |
84 |
|
88 | /// the move's from and to squares, see chessprogramming.wikispaces.com/Butterfly+Boards |
- | 89 | typedef Stats<int16_t, 10692, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)> ButterflyHistory; |
|
85 | 90 | ||
- | 91 | /// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous |
|
86 |
|
92 | /// move, see chessprogramming.wikispaces.com/Countermove+Heuristic |
87 |
|
93 | typedef Stats<Move, NOT_USED, PIECE_NB, SQUARE_NB> CounterMoveHistory; |
88 | } |
- | |
89 | }; |
- | |
90 | 94 | ||
91 | /// |
95 | /// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type] |
92 |
|
96 | typedef Stats<int16_t, 10692, PIECE_NB, SQUARE_NB, PIECE_TYPE_NB> CapturePieceToHistory; |
93 | 97 | ||
94 |
|
98 | /// PieceToHistory is like ButterflyHistory but is addressed by a move's [piece][to] |
95 |
|
99 | typedef Stats<int16_t, 29952, PIECE_NB, SQUARE_NB> PieceToHistory; |
96 | } |
- | |
97 | }; |
- | |
98 | 100 | ||
99 | /// CapturePieceToHistory is like PieceToHistory, but is based on CapturePieceToBoards |
- | |
100 | struct CapturePieceToHistory : public CapturePieceToBoards { |
- | |
101 | - | ||
102 | void update(Piece pc, Square to, PieceType captured, int bonus) { |
- | |
103 | StatCubes::update((*this)[pc][to][captured], bonus, 324, 2); |
- | |
104 | } |
- | |
105 | }; |
- | |
106 | - | ||
107 | /// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous |
- | |
108 | /// move, see chessprogramming.wikispaces.com/Countermove+Heuristic |
- | |
109 | typedef StatBoards<PIECE_NB, SQUARE_NB, Move> CounterMoveHistory; |
- | |
110 | - | ||
111 | /// ContinuationHistory is the history of a given pair of moves, usually |
101 | /// ContinuationHistory is the combined history of a given pair of moves, usually |
112 | /// current one given a previous one. |
102 | /// the current one given a previous one. The nested history table is based on |
113 | /// instead of ButterflyBoards. |
103 | /// PieceToHistory instead of ButterflyBoards. |
114 | typedef |
104 | typedef Stats<PieceToHistory, NOT_USED, PIECE_NB, SQUARE_NB> ContinuationHistory; |
115 | 105 | ||
116 | 106 | ||
117 | /// MovePicker class is used to pick one pseudo legal move at a time from the |
107 | /// MovePicker class is used to pick one pseudo legal move at a time from the |
118 | /// current position. The most important method is next_move(), which returns a |
108 | /// current position. The most important method is next_move(), which returns a |
119 | /// new pseudo legal move each time it is called, until there are no moves left, |
109 | /// new pseudo legal move each time it is called, until there are no moves left, |
120 | /// when MOVE_NONE is returned. In order to improve the efficiency of the alpha |
110 | /// when MOVE_NONE is returned. In order to improve the efficiency of the alpha |
121 | /// beta algorithm, MovePicker attempts to return the moves which are most likely |
111 | /// beta algorithm, MovePicker attempts to return the moves which are most likely |
122 | /// to get a cut-off first. |
112 | /// to get a cut-off first. |
123 | - | ||
124 | class MovePicker { |
113 | class MovePicker { |
- | 114 | ||
- | 115 | enum PickType { Next, Best }; |
|
- | 116 | ||
125 | public: |
117 | public: |
126 | MovePicker(const MovePicker&) = delete; |
118 | MovePicker(const MovePicker&) = delete; |
127 | MovePicker& operator=(const MovePicker&) = delete; |
119 | MovePicker& operator=(const MovePicker&) = delete; |
128 | MovePicker(const Position&, Move, Value, const CapturePieceToHistory*); |
120 | MovePicker(const Position&, Move, Value, const CapturePieceToHistory*); |
129 | MovePicker(const Position&, Move, Depth, const ButterflyHistory*, |
121 | MovePicker(const Position&, Move, Depth, const ButterflyHistory*, |
- | 122 | const CapturePieceToHistory*, |
|
- | 123 | const PieceToHistory**, |
|
- | 124 | Square); |
|
130 | MovePicker(const Position&, Move, Depth, const ButterflyHistory*, |
125 | MovePicker(const Position&, Move, Depth, const ButterflyHistory*, |
- | 126 | const CapturePieceToHistory*, |
|
- | 127 | const PieceToHistory**, |
|
- | 128 | Move, |
|
- | 129 | Move*); |
|
131 | Move next_move(bool skipQuiets = false); |
130 | Move next_move(bool skipQuiets = false); |
132 | 131 | ||
133 | private: |
132 | private: |
- | 133 | template<PickType T, typename Pred> Move select(Pred); |
|
134 | template<GenType> void score(); |
134 | template<GenType> void score(); |
135 | ExtMove* begin() { return cur; } |
135 | ExtMove* begin() { return cur; } |
136 | ExtMove* end() { return endMoves; } |
136 | ExtMove* end() { return endMoves; } |
137 | 137 | ||
138 | const Position& pos; |
138 | const Position& pos; |
139 | const ButterflyHistory* mainHistory; |
139 | const ButterflyHistory* mainHistory; |
140 | const CapturePieceToHistory* captureHistory; |
140 | const CapturePieceToHistory* captureHistory; |
141 | const PieceToHistory** |
141 | const PieceToHistory** continuationHistory; |
142 | Move |
142 | Move ttMove; |
143 | ExtMove *cur, *endMoves, *endBadCaptures; |
143 | ExtMove refutations[3], *cur, *endMoves, *endBadCaptures; |
144 | int stage; |
144 | int stage; |
- | 145 | Move move; |
|
145 | Square recaptureSquare; |
146 | Square recaptureSquare; |
146 | Value threshold; |
147 | Value threshold; |
147 | Depth depth; |
148 | Depth depth; |
148 | ExtMove moves[MAX_MOVES]; |
149 | ExtMove moves[MAX_MOVES]; |
149 | }; |
150 | }; |