From 6c695b61ad5b2064f400a81aeaf6a7f775d849a9 Mon Sep 17 00:00:00 2001 From: h zy <2658628026@qq.com> Date: Mon, 23 Sep 2024 04:15:41 +0800 Subject: [PATCH] allow pass rule --- cpp/game/board.cpp | 14 +++++++++++++- cpp/game/board.h | 5 ++++- cpp/game/boardhistory.cpp | 3 ++- cpp/game/gamelogic.cpp | 20 ++++++++++++++------ cpp/game/gamelogic.h | 2 +- cpp/neuralnet/nninputs.cpp | 2 ++ 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/cpp/game/board.cpp b/cpp/game/board.cpp index 675a812d9..71c9a00ab 100644 --- a/cpp/game/board.cpp +++ b/cpp/game/board.cpp @@ -24,8 +24,10 @@ Hash128 Board::ZOBRIST_BOARD_HASH[MAX_ARR_SIZE][4]; Hash128 Board::ZOBRIST_PLAYER_HASH[4]; Hash128 Board::ZOBRIST_MOVENUM_HASH[MAX_ARR_SIZE]; Hash128 Board::ZOBRIST_BOARD_HASH2[MAX_ARR_SIZE][4]; -const Hash128 Board::ZOBRIST_GAME_IS_OVER = //Based on sha256 hash of Board::ZOBRIST_GAME_IS_OVER +const Hash128 Board::ZOBRIST_GAME_IS_OVER = // Based on sha256 hash of Board::ZOBRIST_GAME_IS_OVER Hash128(0xb6f9e465597a77eeULL, 0xf1d583d960a4ce7fULL); +const Hash128 Board::ZOBRIST_LAST_MOVE_PASS = + Hash128(0x890d44c415a4224cULL, 0xdea1afbf9c07a697ULL); //LOCATION-------------------------------------------------------------------------------- Loc Location::getLoc(int x, int y, int x_size) @@ -109,6 +111,7 @@ Board::Board(const Board& other) movenum = other.movenum; stonenum = other.stonenum; + isLastMovePass = other.isLastMovePass; pos_hash = other.pos_hash; memcpy(adj_offsets, other.adj_offsets, sizeof(short)*8); @@ -128,6 +131,7 @@ void Board::init(int xS, int yS) movenum = 0; stonenum = 0; + isLastMovePass = false; for(int y = 0; y < y_size; y++) { @@ -310,8 +314,14 @@ void Board::playMoveAssumeLegal(Loc loc, Player pla) //Pass? if(loc == PASS_LOC) { + if(!isLastMovePass) + pos_hash ^= ZOBRIST_LAST_MOVE_PASS; + isLastMovePass = true; return; } + if(isLastMovePass) + pos_hash ^= ZOBRIST_LAST_MOVE_PASS; + isLastMovePass = false; setStone(loc, pla); } @@ -364,6 +374,8 @@ void Board::checkConsistency() const { } tmp_pos_hash ^= ZOBRIST_MOVENUM_HASH[movenum]; + if(isLastMovePass) + tmp_pos_hash ^= ZOBRIST_LAST_MOVE_PASS; if(pos_hash != tmp_pos_hash) throw StringError(errLabel + "Pos hash does not match expected"); diff --git a/cpp/game/board.h b/cpp/game/board.h index 187cc5019..9b0ff981b 100644 --- a/cpp/game/board.h +++ b/cpp/game/board.h @@ -14,9 +14,10 @@ #ifdef COMPILE_MAX_BOARD_LEN static_assert(COMPILE_MAX_BOARD_LEN should not be defined); #endif -#define COMPILE_MAX_BOARD_LEN 9 +#define COMPILE_MAX_BOARD_LEN 15 static const bool LONGWIN = true; +static const bool ALLOW_PASS = false; @@ -121,6 +122,7 @@ struct Board static Hash128 ZOBRIST_BOARD_HASH2[MAX_ARR_SIZE][4]; static Hash128 ZOBRIST_PLAYER_HASH[4]; static const Hash128 ZOBRIST_GAME_IS_OVER; + static const Hash128 ZOBRIST_LAST_MOVE_PASS; //Structs--------------------------------------- @@ -182,6 +184,7 @@ struct Board int movenum; //how many moves int stonenum; //how many stones on board + bool isLastMovePass; /* PointList empty_list; //List of all empty locations on board */ Hash128 pos_hash; //A zobrist hash of the current board position (does not include ko point or player to move) diff --git a/cpp/game/boardhistory.cpp b/cpp/game/boardhistory.cpp index 737945e63..73cb50b2f 100644 --- a/cpp/game/boardhistory.cpp +++ b/cpp/game/boardhistory.cpp @@ -215,6 +215,7 @@ void BoardHistory::makeBoardMoveAssumeLegal(Board& board, Loc moveLoc, Player mo isNoResult = false; isResignation = false; + bool isLastMovePass = board.isLastMovePass; board.playMoveAssumeLegal(moveLoc,movePla); @@ -227,7 +228,7 @@ void BoardHistory::makeBoardMoveAssumeLegal(Board& board, Loc moveLoc, Player mo presumedNextMovePla = getOpp(movePla); - Color maybeWinner = GameLogic::checkWinnerAfterPlayed(board, *this, movePla, moveLoc); + Color maybeWinner = GameLogic::checkWinnerAfterPlayed(board, *this, movePla, moveLoc, isLastMovePass); if(maybeWinner!=C_WALL) { //game finished setWinner(maybeWinner); } diff --git a/cpp/game/gamelogic.cpp b/cpp/game/gamelogic.cpp index 027f7a4b2..1f35c776b 100644 --- a/cpp/game/gamelogic.cpp +++ b/cpp/game/gamelogic.cpp @@ -59,15 +59,23 @@ Color GameLogic::checkWinnerAfterPlayed( const Board& board, const BoardHistory& hist, Player pla, - Loc loc) { - - if(loc == Board::PASS_LOC) - return getOpp(pla); //pass is not allowed + Loc loc, + bool isLastMovePass) { + + if(loc == Board::PASS_LOC) { + if (ALLOW_PASS) + { + if(isLastMovePass) + return C_EMPTY; + } + else + return getOpp(pla); // pass is not allowed + } if(isFour(board, pla, LONGWIN, loc)) return pla; - if(board.movenum >= board.x_size * board.y_size) + if(board.stonenum >= board.x_size * board.y_size) return C_EMPTY; return C_WALL; @@ -91,7 +99,7 @@ void GameLogic::ResultsBeforeNN::init(const Board& board, const BoardHistory& hi int8_t Board::movePriority(Loc loc, Player pla) const { if(!isLegal(loc, pla)) return -2; - if(loc == PASS_LOC) + if(!ALLOW_PASS && loc == PASS_LOC) return -1; if(isFour(*this, pla, LONGWIN, loc)) return 2; diff --git a/cpp/game/gamelogic.h b/cpp/game/gamelogic.h index ec408948c..a0296ae05 100644 --- a/cpp/game/gamelogic.h +++ b/cpp/game/gamelogic.h @@ -26,7 +26,7 @@ namespace GameLogic { static const MovePriority MP_ILLEGAL = -1;//illegal moves //C_EMPTY = draw, C_WALL = not finished - Color checkWinnerAfterPlayed(const Board& board, const BoardHistory& hist, Player pla, Loc loc); + Color checkWinnerAfterPlayed(const Board& board, const BoardHistory& hist, Player pla, Loc loc, bool isLastMovePass); //some results calculated before calculating NN diff --git a/cpp/neuralnet/nninputs.cpp b/cpp/neuralnet/nninputs.cpp index 1811b9b4d..bd8dcee24 100644 --- a/cpp/neuralnet/nninputs.cpp +++ b/cpp/neuralnet/nninputs.cpp @@ -562,6 +562,8 @@ void NNInputs::fillRowV7( rowGlobal[6] = board.x_size % 2 == 1; rowGlobal[7] = board.y_size % 2 == 1; + rowGlobal[8] = board.isLastMovePass; + // Parameter 0 noResultUtilityForWhite, when draw, white's win rate = 0.5*(noResultUtilityForWhite+1) rowGlobal[14] = pla == C_WHITE ? nnInputParams.noResultUtilityForWhite : -nnInputParams.noResultUtilityForWhite;