添加了新的 Stack 类但暂未使用

This commit is contained in:
Calcitem 2020-09-23 00:51:03 +08:00
parent f44d6d2fd4
commit 29bfdbdd39
7 changed files with 131 additions and 20 deletions

View File

@ -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)
{

View File

@ -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,

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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