position: 重新创建 StateInfo 结构体并作为 Position 的成员

This commit is contained in:
Calcitem 2020-07-05 21:57:33 +08:00
parent 19189dbfe1
commit bbfe0293a2
6 changed files with 93 additions and 66 deletions

View File

@ -338,7 +338,7 @@ ExtMove *generateMoves(/* TODO: const */ Position *position, ExtMove *moveList)
for (int i = Board::MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) {
oldSquare = static_cast<Square>(MoveList::movePriorityTable[i]);
if (!position->selectPiece(oldSquare)) {
if (!position->_selectPiece(oldSquare)) {
continue;
}

View File

@ -188,7 +188,7 @@ int AIAlgorithm::search(Depth depth)
static int nRepetition = 0;
if (position->getPhase() == PHASE_MOVING) {
Key key = position->getPosKey();
Key key = position->key();
if (std::find(moveHistory.begin(), moveHistory.end(), key) != moveHistory.end()) {
nRepetition++;
@ -313,7 +313,7 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
#endif // TT_MOVE_ENABLE
#if defined (TRANSPOSITION_TABLE_ENABLE) || defined(ENDGAME_LEARNING)
Key posKey = pos->getPosKey();
Key posKey = pos->key();
#endif
#ifdef ENDGAME_LEARNING
@ -404,13 +404,13 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
// TODO: WIP
st->generateNullMove(moves);
st->generateChildren(moves, this, node);
doNullMove();
do_null_move();
int moveCount = st->generateMoves(moves);
if (moveCount)
{
st->generateChildren(moves, this, node->children[0]);
value = -search(depth - 1 - 2, -beta, -beta + 1, node->children[0]);
undoNullMove();
undo_null_move();
if (value >= beta) {
bestValue = beta;
@ -471,7 +471,7 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
stashPosition();
Color before = pos->sideToMove;
Move move = extMoves[i].move;
doMove(move);
do_move(move);
Color after = pos->sideToMove;
if (gameOptions.getDepthExtension() == true && nchild == 1) {
@ -556,9 +556,9 @@ void AIAlgorithm::stashPosition()
positionStack.push(*(pos));
}
void AIAlgorithm::doMove(Move move)
void AIAlgorithm::do_move(Move move)
{
pos->doMove(move);
pos->do_move(move);
}
void AIAlgorithm::undoMove()
@ -568,14 +568,14 @@ void AIAlgorithm::undoMove()
positionStack.pop();
}
void AIAlgorithm::doNullMove()
void AIAlgorithm::do_null_move()
{
pos->doNullMove();
pos->do_null_move();
}
void AIAlgorithm::undoNullMove()
void AIAlgorithm::undo_null_move()
{
pos->undoNullMove();
pos->undo_null_move();
}
#ifdef ALPHABETA_AI
@ -624,7 +624,7 @@ const char* AIAlgorithm::nextMove()
Endgame endgame;
endgame.type = state->position->playerSideToMove == PLAYER_BLACK ?
ENDGAME_PLAYER_WHITE_WIN : ENDGAME_PLAYER_BLACK_WIN;
key_t endgameHash = position->getPosKey(); // TODO: Do not generate hash repeately
key_t endgameHash = position->key(); // TODO: Do not generate hash repeately
recordEndgameHash(endgameHash, endgame);
}
}

View File

@ -82,12 +82,12 @@ public:
void stashPosition();
void doMove(Move move);
void do_move(Move move);
void undoMove();
void doNullMove();
void undoNullMove();
void do_null_move();
void undo_null_move();
#ifdef TRANSPOSITION_TABLE_ENABLE
void clearTT();

View File

@ -93,7 +93,7 @@ bool Position::setPosition(const struct Rule *newRule)
action = ACTION_PLACE;
memset(board.locations, 0, sizeof(board.locations));
key = 0;
st.key = 0;
memset(board.byTypeBB, 0, sizeof(board.byTypeBB));
if (countPiecesOnBoard() == -1) {
@ -143,7 +143,7 @@ bool Position::reset()
winner = NOBODY;
memset(board.locations, 0, sizeof(board.locations));
key = 0;
st.key = 0;
memset(board.byTypeBB, 0, sizeof(board.byTypeBB));
nPiecesOnBoard[BLACK] = nPiecesOnBoard[WHITE] = 0;
@ -197,7 +197,7 @@ bool Position::start()
}
}
bool Position::placePiece(Square square, bool updateCmdlist)
bool Position::place_piece(Square square, bool updateCmdlist)
{
File file;
Rank rank;
@ -353,17 +353,17 @@ bool Position::_placePiece(File file, Rank rank)
{
Square square = Board::polarToSquare(file, rank);
return placePiece(square, true);
return place_piece(square, true);
}
bool Position::_removePiece(File file, Rank rank)
{
Square square = Board::polarToSquare(file, rank);
return removePiece(square, 1);
return remove_piece(square, 1);
}
bool Position::removePiece(Square square, bool updateCmdlist)
bool Position::remove_piece(Square square, bool updateCmdlist)
{
if (phase & PHASE_NOTPLAYING)
return false;
@ -473,7 +473,7 @@ out:
return true;
}
bool Position::selectPiece(Square square)
bool Position::_selectPiece(Square square)
{
if (phase != PHASE_MOVING)
return false;
@ -491,9 +491,9 @@ bool Position::selectPiece(Square square)
return false;
}
bool Position::selectPiece(File file, Rank rank)
bool Position::_selectPiece(File file, Rank rank)
{
return selectPiece(Board::polarToSquare(file, rank));
return _selectPiece(Board::polarToSquare(file, rank));
}
bool Position::giveup(Color loser)
@ -545,7 +545,7 @@ bool Position::command(const char *cmd)
tm = mm * 60 + ss;
}
if (selectPiece(file1, rank1)) {
if (_selectPiece(file1, rank1)) {
return _placePiece(file2, rank2);
}
@ -595,20 +595,20 @@ bool Position::command(const char *cmd)
return false;
}
bool Position::doMove(Move m)
bool Position::do_move(Move m)
{
MoveType mt = type_of(m);
switch (mt) {
case MOVETYPE_REMOVE:
return removePiece(static_cast<Square>(-m));
return remove_piece(static_cast<Square>(-m));
case MOVETYPE_MOVE:
if (selectPiece(from_sq(m))) {
return placePiece(to_sq(m));
if (_selectPiece(from_sq(m))) {
return place_piece(to_sq(m));
}
break;
case MOVETYPE_PLACE:
return placePiece(to_sq(m));
return place_piece(to_sq(m));
default:
break;
}
@ -829,13 +829,13 @@ void Position::changeSideToMove()
setSideToMove(~sideToMove);
}
bool Position::doNullMove()
bool Position::do_null_move()
{
changeSideToMove();
return true;
}
bool Position::undoNullMove()
bool Position::undo_null_move()
{
changeSideToMove();
return true;
@ -901,10 +901,10 @@ time_t Position::getElapsedTime(int us)
void Position::constructKey()
{
key = 0;
st.key = 0;
}
Key Position::getPosKey()
Key Position::key()
{
// TODO: Move to suitable function
return updateKeyMisc();
@ -920,9 +920,9 @@ Key Position::updateKey(Square square)
//Location loc = board.locations[square];
//int pieceType = loc == 0x0f? 3 : loc >> PLAYER_SHIFT;
key ^= zobrist[square][pieceType];
st.key ^= zobrist[square][pieceType];
return key;
return st.key;
}
Key Position::revertKey(Square square)
@ -934,7 +934,7 @@ Key Position::updateKeyMisc()
{
const int KEY_MISC_BIT = 8;
key = key << KEY_MISC_BIT >> KEY_MISC_BIT;
st.key = st.key << KEY_MISC_BIT >> KEY_MISC_BIT;
Key hi = 0;
if (sideToMove == WHITE) {
@ -948,14 +948,14 @@ Key Position::updateKeyMisc()
hi |= static_cast<Key>(nPiecesNeedRemove) << 2;
hi |= static_cast<Key>(nPiecesInHand[BLACK]) << 4; // TODO: may use phase is also OK?
key = key | (hi << (CHAR_BIT * sizeof(Key) - KEY_MISC_BIT));
st.key = st.key | (hi << (CHAR_BIT * sizeof(Key) - KEY_MISC_BIT));
return key;
return st.key;
}
Key Position::getNextPrimaryKey(Move m)
{
Key npKey = key /* << 8 >> 8 */;
Key npKey = st.key /* << 8 >> 8 */;
Square sq = static_cast<Square>(to_sq(m));;
MoveType mt = type_of(m);

View File

@ -20,6 +20,9 @@
#ifndef POSITION_H
#define POSITION_H
#include <cassert>
#include <deque>
#include <memory> // For std::unique_ptr
#include <string>
#include <cstring>
@ -36,6 +39,30 @@ class Node;
extern string tips;
/// 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
/// board (by calling Position::do_move), a StateInfo object must be passed.
struct StateInfo
{
// Copied when making a move
int rule50;
int pliesFromNull;
// Not copied when making a move (will be recomputed anyhow)
Key key;
Piece capturedPiece;
StateInfo *previous;
int repetition;
};
/// A list to keep track of the position states along the setup moves (from the
/// start position to the position just before the search starts). Needed by
/// 'draw by repetition' detection. Use a std::deque because pointers to
/// elements are not invalidated upon list resizing.
typedef std::unique_ptr<std::deque<StateInfo>> StateListPtr;
class Position
{
public:
@ -45,9 +72,30 @@ public:
Position(const Position &) = delete;
Position &operator=(const Position &) = delete;
// Properties of moves
bool _selectPiece(Square s);
bool place_piece(Square s, bool updateCmdlist = false);
bool remove_piece(Square s, bool updateCmdlist = false);
bool _selectPiece(File file, Rank rank);
bool _placePiece(File file, Rank rank);
bool _removePiece(File file, Rank rank);
// Doing and undoing moves
bool do_move(Move m);
bool do_null_move();
bool undo_null_move();
// Accessing hash keys
Key key();
Key revertKey(Square square);
Key updateKey(Square square);
Key updateKeyMisc();
Key getNextPrimaryKey(Move m);
Board board;
Key key {0};
// Other properties of the position
enum Phase phase {PHASE_NONE};
@ -127,11 +175,6 @@ public:
return nPiecesOnBoard[c];
}
int getNum_NeedRemove() const
{
return nPiecesNeedRemove;
}
int getMobilityDiff(Color turn, int nPiecesOnBoard[], bool includeFobidden);
bool reset();
@ -156,26 +199,8 @@ public:
void setTips();
bool doNullMove();
bool undoNullMove();
Color getWinner() const;
bool selectPiece(File file, Rank rank);
bool _placePiece(File file, Rank rank);
bool _removePiece(File file, Rank rank);
bool doMove(Move move);
bool selectPiece(Square square);
bool placePiece(Square square, bool updateCmdlist = false);
bool removePiece(Square square, bool updateCmdlist = false);
Key getPosKey();
Key revertKey(Square square);
Key updateKey(Square square);
Key updateKeyMisc();
Key getNextPrimaryKey(Move m);
int score[COLOR_NB] = { 0 };
int score_draw { 0 };
int nPlayed { 0 };
@ -229,6 +254,8 @@ private:
time_t currentTime {};
time_t elapsedSeconds[COLOR_NB];
StateInfo st;
};
#endif /* POSITION_H */

View File

@ -817,7 +817,7 @@ bool GameController::actionPiece(QPointF pos)
piece = qgraphicsitem_cast<PieceItem *>(item);
if (!piece)
break;
if (position->selectPiece(file, rank)) {
if (position->_selectPiece(file, rank)) {
// 播放选子音效
playSound(GAME_SOUND_SELECT, position->getSideToMove());
result = true;