endgame: refactor
Known Issue: After the previous series of code refactoring, it still cannot work normally, but it can work normally in the early stage.
This commit is contained in:
parent
b3577d6b78
commit
096af01919
|
@ -97,7 +97,6 @@
|
|||
|
||||
//#define ENDGAME_LEARNING
|
||||
//#define ENDGAME_LEARNING_FORCE
|
||||
//#define ENDGAME_LEARNING_DEBUG
|
||||
|
||||
#define THREEFOLD_REPETITION
|
||||
|
||||
|
|
|
@ -31,21 +31,20 @@
|
|||
using namespace std;
|
||||
using namespace CTSL;
|
||||
|
||||
// TODO: uint8_t
|
||||
enum endgame_t : uint32_t
|
||||
static const int SAVE_ENDGAME_EVERY_N_GAMES = 256;
|
||||
|
||||
enum class EndGameType : uint32_t
|
||||
{
|
||||
ENDGAME_NONE,
|
||||
ENDGAME_PLAYER_BLACK_WIN,
|
||||
ENDGAME_PLAYER_WHITE_WIN,
|
||||
ENDGAME_DRAW,
|
||||
none,
|
||||
blackWin,
|
||||
whiteWin,
|
||||
draw,
|
||||
};
|
||||
|
||||
//#pragma pack (push, 1)
|
||||
struct Endgame
|
||||
{
|
||||
endgame_t type;
|
||||
EndGameType type;
|
||||
};
|
||||
//#pragma pack(pop)
|
||||
|
||||
extern HashMap<Key, Endgame> endgameHashMap;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
bool getLearnEndgameEnabled()
|
||||
bool isEndgameLearningEnabled()
|
||||
{
|
||||
#ifdef ENDGAME_LEARNING_FORCE
|
||||
return true;
|
||||
|
|
|
@ -169,7 +169,7 @@ Position::Position()
|
|||
|
||||
reset();
|
||||
|
||||
score[BLACK] = score[WHITE] = score_draw = nPlayed = 0;
|
||||
score[BLACK] = score[WHITE] = score_draw = gamesPlayedCount = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -693,7 +693,7 @@ int Position::piece_on_board_count()
|
|||
return pieceOnBoardCount[BLACK] + pieceOnBoardCount[WHITE];
|
||||
}
|
||||
|
||||
int Position::get_piece_in_hand_count()
|
||||
int Position::piece_in_hand_count()
|
||||
{
|
||||
pieceInHandCount[BLACK] = rule.piecesCount - pieceOnBoardCount[BLACK];
|
||||
pieceInHandCount[WHITE] = rule.piecesCount - pieceOnBoardCount[WHITE];
|
||||
|
@ -736,8 +736,9 @@ bool Position::reset()
|
|||
currentSquare = SQ_0;
|
||||
|
||||
#ifdef ENDGAME_LEARNING
|
||||
if (gameOptions.getLearnEndgameEnabled() && nPlayed != 0 && nPlayed % 256 == 0) {
|
||||
Thread::recordEndgameHashMapToFile();
|
||||
if (gameOptions.isEndgameLearningEnabled() &&
|
||||
gamesPlayedCount > 0 && gamesPlayedCount % SAVE_ENDGAME_EVERY_N_GAMES == 0) {
|
||||
Thread::saveEndgameHashMapToFile();
|
||||
}
|
||||
#endif /* ENDGAME_LEARNING */
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ public:
|
|||
static void print_board();
|
||||
|
||||
int piece_on_board_count();
|
||||
int get_piece_in_hand_count();
|
||||
int piece_in_hand_count();
|
||||
|
||||
int piece_on_board_count(Color c);
|
||||
int piece_in_hand_count(Color c);
|
||||
|
@ -203,7 +203,7 @@ public:
|
|||
static Bitboard millTableBB[SQUARE_NB][LD_NB];
|
||||
|
||||
Square currentSquare;
|
||||
int nPlayed { 0 };
|
||||
int gamesPlayedCount { 0 };
|
||||
|
||||
char cmdline[64] { '\0' };
|
||||
|
||||
|
|
|
@ -233,14 +233,14 @@ Value search(Position *pos, Sanmill::Stack<Position> &ss, Depth depth, Depth ori
|
|||
#ifdef ENDGAME_LEARNING
|
||||
Endgame endgame;
|
||||
|
||||
if (gameOptions.getLearnEndgameEnabled() &&
|
||||
Thread::findEndgameHash(posKey, endgame)) {
|
||||
if (gameOptions.isEndgameLearningEnabled() &&
|
||||
Thread::probeEndgameHash(posKey, endgame)) {
|
||||
switch (endgame.type) {
|
||||
case ENDGAME_PLAYER_BLACK_WIN:
|
||||
case EndGameType::blackWin:
|
||||
bestValue = VALUE_MATE;
|
||||
bestValue += depth;
|
||||
break;
|
||||
case ENDGAME_PLAYER_WHITE_WIN:
|
||||
case EndGameType::whiteWin:
|
||||
bestValue = -VALUE_MATE;
|
||||
bestValue -= depth;
|
||||
break;
|
||||
|
|
|
@ -424,15 +424,15 @@ Depth Thread::adjustDepth()
|
|||
|
||||
#ifdef ENDGAME_LEARNING
|
||||
const Depth movingDiffDepthTable[] = {
|
||||
0, 0, 0, /* 0 ~ 2 */
|
||||
0, 0, 0, 0, 0, /* 3 ~ 7 */
|
||||
0, 0, 0, 0, 0 /* 8 ~ 12 */
|
||||
0, 0, 0, /* 0 ~ 2 */
|
||||
0, 0, 0, 0, 0, /* 3 ~ 7 */
|
||||
0, 0, 0, 0, 0 /* 8 ~ 12 */
|
||||
};
|
||||
#else
|
||||
const Depth movingDiffDepthTable[] = {
|
||||
0, 0, 0, /* 0 ~ 2 */
|
||||
0, 0, 0, /* 0 ~ 2 */
|
||||
11, 11, 10, 9, 8, /* 3 ~ 7 */
|
||||
7, 6, 5, 4, 3 /* 8 ~ 12 */
|
||||
7, 6, 5, 4, 3 /* 8 ~ 12 */
|
||||
};
|
||||
#endif /* ENDGAME_LEARNING */
|
||||
|
||||
|
@ -506,12 +506,6 @@ void Thread::clearTT()
|
|||
#ifdef TRANSPOSITION_TABLE_ENABLE
|
||||
TranspositionTable::clear();
|
||||
#endif // TRANSPOSITION_TABLE_ENABLE
|
||||
|
||||
#ifdef ENDGAME_LEARNING
|
||||
// TODO: ??????????
|
||||
//clearEndgameHashMap();
|
||||
//endgameList.clear();
|
||||
#endif // ENDGAME_LEARNING
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,13 +542,13 @@ string Thread::nextMove()
|
|||
|
||||
#ifdef ENDGAME_LEARNING
|
||||
// Check if very weak
|
||||
if (gameOptions.getLearnEndgameEnabled()) {
|
||||
if (gameOptions.isEndgameLearningEnabled()) {
|
||||
if (bestValue <= -VALUE_KNOWN_WIN) {
|
||||
Endgame endgame;
|
||||
endgame.type = state->position->playerSideToMove == PLAYER_BLACK ?
|
||||
ENDGAME_PLAYER_WHITE_WIN : ENDGAME_PLAYER_BLACK_WIN;
|
||||
whiteWin : blackWin;
|
||||
Key endgameHash = position->key(); // TODO: Do not generate hash repeately
|
||||
recordEndgameHash(endgameHash, endgame);
|
||||
saveEndgameHash(endgameHash, endgame);
|
||||
}
|
||||
}
|
||||
#endif /* ENDGAME_LEARNING */
|
||||
|
@ -591,31 +585,28 @@ string Thread::nextMove()
|
|||
}
|
||||
|
||||
#ifdef ENDGAME_LEARNING
|
||||
bool Thread::findEndgameHash(Key posKey, Endgame &endgame)
|
||||
bool Thread::probeEndgameHash(Key posKey, Endgame &endgame)
|
||||
{
|
||||
return endgameHashMap.find(posKey, endgame);
|
||||
}
|
||||
|
||||
int Thread::recordEndgameHash(Key posKey, const Endgame &endgame)
|
||||
int Thread::saveEndgameHash(Key posKey, const Endgame &endgame)
|
||||
{
|
||||
//hashMapMutex.lock();
|
||||
Key hashValue = endgameHashMap.insert(posKey, endgame);
|
||||
unsigned addr = hashValue * (sizeof(posKey) + sizeof(endgame));
|
||||
//hashMapMutex.unlock();
|
||||
|
||||
loggerDebug("[endgame] Record 0x%08I32x (%d) to Endgame Hash map, TTEntry: 0x%08I32x, Address: 0x%08I32x\n", posKey, endgame.type, hashValue, addr);
|
||||
loggerDebug("[endgame] Record 0x%08I32x (%d) to Endgame hash map, TTEntry: 0x%08I32x, Address: 0x%08I32x\n",
|
||||
posKey, endgame.type, hashValue, addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Thread::clearEndgameHashMap()
|
||||
{
|
||||
//hashMapMutex.lock();
|
||||
endgameHashMap.clear();
|
||||
//hashMapMutex.unlock();
|
||||
}
|
||||
|
||||
void Thread::recordEndgameHashMapToFile()
|
||||
void Thread::saveEndgameHashMapToFile()
|
||||
{
|
||||
const string filename = "endgame.txt";
|
||||
endgameHashMap.dump(filename);
|
||||
|
|
|
@ -94,10 +94,10 @@ public:
|
|||
#endif
|
||||
|
||||
#ifdef ENDGAME_LEARNING
|
||||
static bool findEndgameHash(Key key, Endgame &endgame);
|
||||
static int recordEndgameHash(Key key, const Endgame &endgame);
|
||||
static bool probeEndgameHash(Key key, Endgame &endgame);
|
||||
static int saveEndgameHash(Key key, const Endgame &endgame);
|
||||
void clearEndgameHashMap();
|
||||
static void recordEndgameHashMapToFile();
|
||||
static void saveEndgameHashMapToFile();
|
||||
static void loadEndgameFileToHashMap();
|
||||
#endif // ENDGAME_LEARNING
|
||||
|
||||
|
|
|
@ -106,8 +106,8 @@ Game::Game(
|
|||
#endif // NET_FIGHT_SUPPORT
|
||||
|
||||
#ifdef ENDGAME_LEARNING_FORCE
|
||||
if (gameOptions.getLearnEndgameEnabled()) {
|
||||
AIAlgorithm::loadEndgameFileToHashMap();
|
||||
if (gameOptions.isEndgameLearningEnabled()) {
|
||||
Thread::loadEndgameFileToHashMap();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -129,8 +129,8 @@ Game::~Game()
|
|||
deleteAiThreads();
|
||||
|
||||
#ifdef ENDGAME_LEARNING
|
||||
if (gameOptions.getLearnEndgameEnabled()) {
|
||||
Thread::recordEndgameHashMapToFile();
|
||||
if (gameOptions.isEndgameLearningEnabled()) {
|
||||
Thread::saveEndgameHashMapToFile();
|
||||
}
|
||||
#endif /* ENDGAME_LEARNING */
|
||||
|
||||
|
@ -286,18 +286,18 @@ void Game::gameReset()
|
|||
emit statusBarChanged(message);
|
||||
|
||||
// 更新比分 LCD 显示
|
||||
emit nGamesPlayedChanged(QString::number(position.nPlayed, 10));
|
||||
emit nGamesPlayedChanged(QString::number(position.gamesPlayedCount, 10));
|
||||
emit score1Changed(QString::number(position.score[BLACK], 10));
|
||||
emit score2Changed(QString::number(position.score[WHITE], 10));
|
||||
emit scoreDrawChanged(QString::number(position.score_draw, 10));
|
||||
|
||||
// 更新胜率 LCD 显示
|
||||
position.nPlayed = position.score[BLACK] + position.score[WHITE] + position.score_draw;
|
||||
position.gamesPlayedCount = position.score[BLACK] + position.score[WHITE] + position.score_draw;
|
||||
int winningRate_1 = 0, winningRate_2 = 0, winningRate_draw = 0;
|
||||
if (position.nPlayed != 0) {
|
||||
winningRate_1 = position.score[BLACK] * 10000 / position.nPlayed;
|
||||
winningRate_2 = position.score[WHITE] * 10000 / position.nPlayed;
|
||||
winningRate_draw = position.score_draw * 10000 / position.nPlayed;
|
||||
if (position.gamesPlayedCount != 0) {
|
||||
winningRate_1 = position.score[BLACK] * 10000 / position.gamesPlayedCount;
|
||||
winningRate_2 = position.score[WHITE] * 10000 / position.gamesPlayedCount;
|
||||
winningRate_draw = position.score_draw * 10000 / position.gamesPlayedCount;
|
||||
}
|
||||
|
||||
emit winningRate1Changed(QString::number(winningRate_1, 10));
|
||||
|
@ -559,7 +559,7 @@ void Game::setLearnEndgame(bool enabled)
|
|||
gameOptions.setLearnEndgameEnabled(enabled);
|
||||
|
||||
#ifdef ENDGAME_LEARNING
|
||||
if (gameOptions.getLearnEndgameEnabled()) {
|
||||
if (gameOptions.isEndgameLearningEnabled()) {
|
||||
Thread::loadEndgameFileToHashMap();
|
||||
}
|
||||
#endif
|
||||
|
@ -1364,12 +1364,12 @@ bool Game::updateScence(Position &p)
|
|||
emit scoreDrawChanged(QString::number(p.score_draw, 10));
|
||||
|
||||
// 更新胜率 LCD 显示
|
||||
position.nPlayed = position.score[BLACK] + position.score[WHITE] + position.score_draw;
|
||||
position.gamesPlayedCount = position.score[BLACK] + position.score[WHITE] + position.score_draw;
|
||||
int winningRate_1 = 0, winningRate_2 = 0, winningRate_draw = 0;
|
||||
if (position.nPlayed != 0) {
|
||||
winningRate_1 = position.score[BLACK] * 10000 / position.nPlayed;
|
||||
winningRate_2 = position.score[WHITE] * 10000 / position.nPlayed;
|
||||
winningRate_draw = position.score_draw * 10000 / position.nPlayed;
|
||||
if (position.gamesPlayedCount != 0) {
|
||||
winningRate_1 = position.score[BLACK] * 10000 / position.gamesPlayedCount;
|
||||
winningRate_2 = position.score[WHITE] * 10000 / position.gamesPlayedCount;
|
||||
winningRate_draw = position.score_draw * 10000 / position.gamesPlayedCount;
|
||||
}
|
||||
|
||||
emit winningRate1Changed(QString::number(winningRate_1, 10));
|
||||
|
@ -1450,16 +1450,16 @@ void Game::saveScore()
|
|||
|
||||
textStream << "" << endl;
|
||||
|
||||
position.nPlayed = position.score[BLACK] + position.score[WHITE] + position.score_draw;
|
||||
position.gamesPlayedCount = position.score[BLACK] + position.score[WHITE] + position.score_draw;
|
||||
|
||||
if (position.nPlayed == 0) {
|
||||
if (position.gamesPlayedCount == 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
textStream << "Sum\t" + QString::number(position.nPlayed) << endl;
|
||||
textStream << "Black\t" + QString::number(position.score[BLACK]) + "\t" + QString::number(position.score[BLACK] * 10000 / position.nPlayed) << endl;
|
||||
textStream << "White\t" + QString::number(position.score[WHITE]) + "\t" + QString::number(position.score[WHITE] * 10000 / position.nPlayed) << endl;
|
||||
textStream << "Draw\t" + QString::number(position.score_draw) + "\t" + QString::number(position.score_draw * 10000 / position.nPlayed) << endl;
|
||||
textStream << "Sum\t" + QString::number(position.gamesPlayedCount) << endl;
|
||||
textStream << "Black\t" + QString::number(position.score[BLACK]) + "\t" + QString::number(position.score[BLACK] * 10000 / position.gamesPlayedCount) << endl;
|
||||
textStream << "White\t" + QString::number(position.score[WHITE]) + "\t" + QString::number(position.score[WHITE] * 10000 / position.gamesPlayedCount) << endl;
|
||||
textStream << "Draw\t" + QString::number(position.score_draw) + "\t" + QString::number(position.score_draw * 10000 / position.gamesPlayedCount) << endl;
|
||||
|
||||
out:
|
||||
file.flush();
|
||||
|
|
Loading…
Reference in New Issue