添加了新的 Stack 类但暂未使用
This commit is contained in:
parent
f44d6d2fd4
commit
29bfdbdd39
|
@ -18,8 +18,10 @@
|
|||
*/
|
||||
|
||||
#include <random>
|
||||
#include <array>
|
||||
|
||||
#include "movegen.h"
|
||||
#include "misc.h"
|
||||
#include "position.h"
|
||||
#include "option.h"
|
||||
|
||||
|
@ -241,10 +243,10 @@ void MoveList::create()
|
|||
|
||||
void MoveList::shuffle()
|
||||
{
|
||||
array<Square, 4> movePriorityTable0 = { SQ_17, SQ_19, SQ_21, SQ_23 };
|
||||
array<Square, 8> movePriorityTable1 = { SQ_25, SQ_27, SQ_29, SQ_31, SQ_9, SQ_11, SQ_13, SQ_15 };
|
||||
array<Square, 4> movePriorityTable2 = { SQ_16, SQ_18, SQ_20, SQ_22 };
|
||||
array<Square, 8> movePriorityTable3 = { SQ_24, SQ_26, SQ_28, SQ_30, SQ_8, SQ_10, SQ_12, SQ_14 };
|
||||
std::array<Square, 4> movePriorityTable0 = { SQ_17, SQ_19, SQ_21, SQ_23 };
|
||||
std::array<Square, 8> movePriorityTable1 = { SQ_25, SQ_27, SQ_29, SQ_31, SQ_9, SQ_11, SQ_13, SQ_15 };
|
||||
std::array<Square, 4> movePriorityTable2 = { SQ_16, SQ_18, SQ_20, SQ_22 };
|
||||
std::array<Square, 8> movePriorityTable3 = { SQ_24, SQ_26, SQ_28, SQ_30, SQ_8, SQ_10, SQ_12, SQ_14 };
|
||||
|
||||
if (rule.nTotalPiecesEachSide == 9)
|
||||
{
|
||||
|
|
102
src/movepick.h
102
src/movepick.h
|
@ -34,6 +34,108 @@ struct ExtMove;
|
|||
void partial_insertion_sort(ExtMove *begin, ExtMove *end, int limit);
|
||||
|
||||
|
||||
/// StatsEntry stores the stat table value. It is usually a number but could
|
||||
/// be a move or even a nested history. We use a class instead of naked value
|
||||
/// to directly call history update operator<<() on the entry so to use stats
|
||||
/// tables at caller sites as simple multi-dim arrays.
|
||||
template<typename T, int D>
|
||||
class StatsEntry
|
||||
{
|
||||
|
||||
T entry;
|
||||
|
||||
public:
|
||||
void operator=(const T &v)
|
||||
{
|
||||
entry = v;
|
||||
}
|
||||
T *operator&()
|
||||
{
|
||||
return &entry;
|
||||
}
|
||||
T *operator->()
|
||||
{
|
||||
return &entry;
|
||||
}
|
||||
operator const T &() const
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
|
||||
void operator<<(int bonus)
|
||||
{
|
||||
assert(abs(bonus) <= D); // Ensure range is [-D, D]
|
||||
static_assert(D <= std::numeric_limits<T>::max(), "D overflows T");
|
||||
|
||||
entry += T(bonus - entry * abs(bonus) / D);
|
||||
|
||||
assert(abs(entry) <= D);
|
||||
}
|
||||
};
|
||||
|
||||
/// Stats is a generic N-dimensional array used to store various statistics.
|
||||
/// The first template parameter T is the base type of the array, the second
|
||||
/// template parameter D limits the range of updates in [-D, D] when we update
|
||||
/// values with the << operator, while the last parameters (Size and Sizes)
|
||||
/// encode the dimensions of the array.
|
||||
template <typename T, int D, int Size, int... Sizes>
|
||||
struct Stats : public std::array<Stats<T, D, Sizes...>, Size>
|
||||
{
|
||||
typedef Stats<T, D, Size, Sizes...> stats;
|
||||
|
||||
void fill(const T &v)
|
||||
{
|
||||
|
||||
// For standard-layout 'this' points to first struct member
|
||||
assert(std::is_standard_layout<stats>::value);
|
||||
|
||||
typedef StatsEntry<T, D> entry;
|
||||
entry *p = reinterpret_cast<entry *>(this);
|
||||
std::fill(p, p + sizeof(*this) / sizeof(entry), v);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int D, int Size>
|
||||
struct Stats<T, D, Size> : public std::array<StatsEntry<T, D>, Size> {};
|
||||
|
||||
/// In stats table, D=0 means that the template parameter is not used
|
||||
enum StatsParams
|
||||
{
|
||||
NOT_USED = 0
|
||||
};
|
||||
enum StatsType
|
||||
{
|
||||
NoCaptures, Captures
|
||||
};
|
||||
|
||||
/// ButterflyHistory records how often quiet moves have been successful or
|
||||
/// unsuccessful during the current search, and is used for reduction and move
|
||||
/// ordering decisions. It uses 2 tables (one for each color) indexed by
|
||||
/// the move's from and to squares, see www.chessprogramming.org/Butterfly_Boards
|
||||
typedef Stats<int16_t, 10692, COLOR_NB, int(SQUARE_NB) *int(SQUARE_NB)> ButterflyHistory;
|
||||
|
||||
/// LowPlyHistory at higher depths records successful quiet moves on plies 0 to 3
|
||||
/// and quiet moves which are/were in the PV (ttPv)
|
||||
/// It get cleared with each new search and get filled during iterative deepening
|
||||
constexpr int MAX_LPH = 4;
|
||||
typedef Stats<int16_t, 10692, MAX_LPH, int(SQUARE_NB) *int(SQUARE_NB)> LowPlyHistory;
|
||||
|
||||
/// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous
|
||||
/// move, see www.chessprogramming.org/Countermove_Heuristic
|
||||
typedef Stats<Move, NOT_USED, PIECE_NB, SQUARE_NB> CounterMoveHistory;
|
||||
|
||||
/// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type]
|
||||
typedef Stats<int16_t, 10692, PIECE_NB, SQUARE_NB, PIECE_TYPE_NB> CapturePieceToHistory;
|
||||
|
||||
/// PieceToHistory is like ButterflyHistory but is addressed by a move's [piece][to]
|
||||
typedef Stats<int16_t, 29952, PIECE_NB, SQUARE_NB> PieceToHistory;
|
||||
|
||||
/// ContinuationHistory is the combined history of a given pair of moves, usually
|
||||
/// the current one given a previous one. The nested history table is based on
|
||||
/// PieceToHistory instead of ButterflyBoards.
|
||||
typedef Stats<PieceToHistory, NOT_USED, PIECE_NB, SQUARE_NB> ContinuationHistory;
|
||||
|
||||
|
||||
/// MovePicker class is used to pick one pseudo legal move at a time from the
|
||||
/// current position. The most important method is next_move(), which returns a
|
||||
/// new pseudo legal move each time it is called, until there are no moves left,
|
||||
|
|
|
@ -496,7 +496,7 @@ void Position::undo_move(Move m)
|
|||
m = m;
|
||||
}
|
||||
|
||||
void Position::undo_move(Stack<Position> &ss)
|
||||
void Position::undo_move(Sanmill::Stack<Position> &ss)
|
||||
{
|
||||
memcpy(this, ss.top(), sizeof(Position));
|
||||
ss.pop();
|
||||
|
|
|
@ -24,10 +24,11 @@
|
|||
#include <deque>
|
||||
#include <memory> // For std::unique_ptr
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "types.h"
|
||||
#include "rule.h"
|
||||
#include "search.h"
|
||||
#include "stack.h"
|
||||
|
||||
/// StateInfo struct stores information needed to restore a Position object to
|
||||
/// its previous state when we retract a move. Whenever a move is made on the
|
||||
|
@ -89,7 +90,7 @@ public:
|
|||
// Doing and undoing moves
|
||||
void do_move(Move m, StateInfo &newSt);
|
||||
void undo_move(Move m);
|
||||
void undo_move(Stack<Position> &ss);
|
||||
void undo_move(Sanmill::Stack<Position> &ss);
|
||||
void undo_null_move();
|
||||
void do_null_move();
|
||||
|
||||
|
@ -145,9 +146,9 @@ public:
|
|||
Color get_winner() const;
|
||||
void set_gameover(Color w, GameOverReason reason);
|
||||
|
||||
void mirror(vector <string> &cmdlist, bool cmdChange = true);
|
||||
void turn(vector <string> &cmdlist, bool cmdChange = true);
|
||||
void rotate(vector <string> &cmdlist, int degrees, bool cmdChange = true);
|
||||
void mirror(std::vector <std::string> &cmdlist, bool cmdChange = true);
|
||||
void turn(std::vector <std::string> &cmdlist, bool cmdChange = true);
|
||||
void rotate(std::vector <std::string> &cmdlist, int degrees, bool cmdChange = true);
|
||||
|
||||
void create_mill_table();
|
||||
int add_mills(Square s);
|
||||
|
|
|
@ -260,7 +260,7 @@ void Thread::search()
|
|||
return;
|
||||
}
|
||||
|
||||
Value MTDF(Position *pos, Stack<Position> &ss, Value firstguess, Depth depth, Depth originDepth, Move &bestMove);
|
||||
Value MTDF(Position *pos, Sanmill::Stack<Position> &ss, Value firstguess, Depth depth, Depth originDepth, Move &bestMove);
|
||||
|
||||
vector<Key> moveHistory;
|
||||
|
||||
|
@ -679,7 +679,7 @@ void MainThread::check_time()
|
|||
|
||||
// search<>() is the main search function for both PV and non-PV nodes
|
||||
|
||||
Value search(Position *pos, Stack<Position> &ss, Depth depth, Depth originDepth, Value alpha, Value beta, Move &bestMove)
|
||||
Value search(Position *pos, Sanmill::Stack<Position> &ss, Depth depth, Depth originDepth, Value alpha, Value beta, Move &bestMove)
|
||||
{
|
||||
Value value;
|
||||
Value bestValue = -VALUE_INFINITE;
|
||||
|
@ -899,7 +899,7 @@ Value search(Position *pos, Stack<Position> &ss, Depth depth, Depth originDepth,
|
|||
return bestValue;
|
||||
}
|
||||
|
||||
Value MTDF(Position *pos, Stack<Position> &ss, Value firstguess, Depth depth, Depth originDepth, Move &bestMove)
|
||||
Value MTDF(Position *pos, Sanmill::Stack<Position> &ss, Value firstguess, Depth depth, Depth originDepth, Move &bestMove)
|
||||
{
|
||||
Value g = firstguess;
|
||||
Value lowerbound = -VALUE_INFINITE;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "stack.h"
|
||||
#include "tt.h"
|
||||
#include "endgame.h"
|
||||
#include "movepick.h"
|
||||
#include "types.h"
|
||||
|
||||
#ifdef CYCLE_STAT
|
||||
|
@ -42,7 +43,7 @@ namespace Search
|
|||
/// Threshold used for countermoves based pruning
|
||||
constexpr int CounterMovePruneThreshold = 0;
|
||||
|
||||
#if 0
|
||||
|
||||
/// Stack struct keeps track of the information we need to remember from nodes
|
||||
/// shallower and deeper in the tree during the search. Each search thread has
|
||||
/// its own array of Stack objects, indexed by the current ply.
|
||||
|
@ -50,6 +51,7 @@ constexpr int CounterMovePruneThreshold = 0;
|
|||
struct Stack
|
||||
{
|
||||
Move *pv;
|
||||
PieceToHistory *continuationHistory;
|
||||
int ply;
|
||||
Move currentMove;
|
||||
Move excludedMove;
|
||||
|
@ -59,7 +61,7 @@ struct Stack
|
|||
int moveCount;
|
||||
bool inCheck;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/// RootMove struct is used for moves at the root of the tree. For each root move
|
||||
/// we store a score and a PV (really a refutation in the case of moves which
|
||||
|
@ -186,7 +188,7 @@ public:
|
|||
private:
|
||||
Position *pos { nullptr };
|
||||
|
||||
Stack<Position> ss;
|
||||
Sanmill::Stack<Position> ss;
|
||||
|
||||
// bool requiredQuit {false}; // TODO
|
||||
|
||||
|
|
12
src/stack.h
12
src/stack.h
|
@ -23,6 +23,9 @@
|
|||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
namespace Sanmill
|
||||
{
|
||||
|
||||
template <typename T, size_t capacity = 128>
|
||||
class Stack
|
||||
{
|
||||
|
@ -38,7 +41,7 @@ public:
|
|||
}
|
||||
|
||||
~Stack()
|
||||
{
|
||||
{
|
||||
//memset(arr, 0, sizeof(T) * capacity);
|
||||
//delete[] arr;
|
||||
}
|
||||
|
@ -131,8 +134,7 @@ public:
|
|||
|
||||
inline void erase(int index)
|
||||
{
|
||||
for (int i = index; i < capacity - 1; i++)
|
||||
{
|
||||
for (int i = index; i < capacity - 1; i++) {
|
||||
arr[i] = arr[i + 1];
|
||||
}
|
||||
|
||||
|
@ -141,7 +143,9 @@ public:
|
|||
|
||||
private:
|
||||
T *arr;
|
||||
int p { -1 };
|
||||
int p{ -1 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // STACK_H
|
||||
|
|
Loading…
Reference in New Issue