cmdlist 从 Position 移动到 GameController 里

已知问题:
棋谱中目前只加入走棋棋谱,其他的控制相关和状态相关的不见了。
This commit is contained in:
Calcitem 2020-09-09 00:51:10 +08:00
parent dbc1e56dc3
commit 51e5f22f06
6 changed files with 53 additions and 57 deletions

View File

@ -165,7 +165,6 @@ Position::Position()
score[BLACK] = score[WHITE] = score_draw = nPlayed = 0; score[BLACK] = score[WHITE] = score_draw = nPlayed = 0;
//tips.reserve(1024); //tips.reserve(1024);
cmdlist.reserve(256);
#ifdef PREFETCH_SUPPORT #ifdef PREFETCH_SUPPORT
prefetch_range(millTable, sizeof(millTable)); prefetch_range(millTable, sizeof(millTable));
@ -174,7 +173,7 @@ Position::Position()
Position::~Position() Position::~Position()
{ {
cmdlist.clear();
} }
/// Position::set() initializes the position object with the given FEN string. /// Position::set() initializes the position object with the given FEN string.
@ -501,7 +500,6 @@ bool Position::set_position(const struct Rule *newRule)
currentSquare = SQ_0; currentSquare = SQ_0;
elapsedSeconds[BLACK] = elapsedSeconds[WHITE] = 0; elapsedSeconds[BLACK] = elapsedSeconds[WHITE] = 0;
update_score(); update_score();
cmdlist.clear();
int r; int r;
for (r = 0; r < N_RULES; r++) { for (r = 0; r < N_RULES; r++) {
@ -510,7 +508,6 @@ bool Position::set_position(const struct Rule *newRule)
} }
if (sprintf(cmdline, "r%1u s%03u t%02u", r + 1, rule.maxStepsLedToDraw, rule.maxTimeLedToLose) > 0) { if (sprintf(cmdline, "r%1u s%03u t%02u", r + 1, rule.maxStepsLedToDraw, rule.maxTimeLedToLose) > 0) {
cmdlist.emplace_back(string(cmdline));
return true; return true;
} }
@ -546,7 +543,6 @@ bool Position::reset()
currentSquare = SQ_0; currentSquare = SQ_0;
elapsedSeconds[BLACK] = elapsedSeconds[WHITE] = 0; elapsedSeconds[BLACK] = elapsedSeconds[WHITE] = 0;
update_score(); update_score();
cmdlist.clear();
#ifdef ENDGAME_LEARNING #ifdef ENDGAME_LEARNING
if (gameOptions.getLearnEndgameEnabled() && nPlayed != 0 && nPlayed % 256 == 0) { if (gameOptions.getLearnEndgameEnabled() && nPlayed != 0 && nPlayed % 256 == 0) {
@ -563,7 +559,6 @@ bool Position::reset()
if (sprintf(cmdline, "r%1u s%03u t%02u", if (sprintf(cmdline, "r%1u s%03u t%02u",
i + 1, rule.maxStepsLedToDraw, rule.maxTimeLedToLose) > 0) { i + 1, rule.maxStepsLedToDraw, rule.maxTimeLedToLose) > 0) {
cmdlist.emplace_back(string(cmdline));
return true; return true;
} }
@ -637,7 +632,6 @@ bool Position::put_piece(Square s, bool updateCmdlist)
seconds = update(); seconds = update();
sprintf(cmdline, "(%1u,%1u) %02u:%02u", sprintf(cmdline, "(%1u,%1u) %02u:%02u",
file, rank, seconds / 60, seconds % 60); file, rank, seconds / 60, seconds % 60);
cmdlist.emplace_back(string(cmdline));
gamePly++; gamePly++;
} }
@ -701,7 +695,6 @@ bool Position::put_piece(Square s, bool updateCmdlist)
seconds = update(); seconds = update();
sprintf(cmdline, "(%1u,%1u)->(%1u,%1u) %02u:%02u", currentSquare / RANK_NB, currentSquare % RANK_NB + 1, sprintf(cmdline, "(%1u,%1u)->(%1u,%1u) %02u:%02u", currentSquare / RANK_NB, currentSquare % RANK_NB + 1,
file, rank, seconds / 60, seconds % 60); file, rank, seconds / 60, seconds % 60);
cmdlist.emplace_back(string(cmdline));
gamePly++; gamePly++;
st->rule50++; st->rule50++;
} }
@ -789,7 +782,6 @@ bool Position::remove_piece(Square s, bool updateCmdlist)
if (updateCmdlist) { if (updateCmdlist) {
seconds = update(); seconds = update();
sprintf(cmdline, "-(%1u,%1u) %02u:%02u", file, rank, seconds / 60, seconds % 60); sprintf(cmdline, "-(%1u,%1u) %02u:%02u", file, rank, seconds / 60, seconds % 60);
cmdlist.emplace_back(string(cmdline));
gamePly++; gamePly++;
st->rule50 = 0; st->rule50 = 0;
} }
@ -868,8 +860,6 @@ bool Position::giveup(Color loser)
sprintf(cmdline, "Player%d give up!", loser); sprintf(cmdline, "Player%d give up!", loser);
score[winner]++; score[winner]++;
cmdlist.emplace_back(string(cmdline));
return true; return true;
} }
@ -941,7 +931,6 @@ bool Position::command(const char *cmd)
score_draw++; score_draw++;
gameoverReason = DRAW_REASON_THREEFOLD_REPETITION; gameoverReason = DRAW_REASON_THREEFOLD_REPETITION;
sprintf(cmdline, "Threefold Repetition. Draw!"); sprintf(cmdline, "Threefold Repetition. Draw!");
cmdlist.emplace_back(string(cmdline));
return true; return true;
} }
#endif /* THREEFOLD_REPETITION */ #endif /* THREEFOLD_REPETITION */
@ -1007,12 +996,10 @@ bool Position::check_gameover_condition(int8_t updateCmdlist)
if (elapsedSeconds[i] > rule.maxTimeLedToLose * 60) { if (elapsedSeconds[i] > rule.maxTimeLedToLose * 60) {
elapsedSeconds[i] = rule.maxTimeLedToLose * 60; elapsedSeconds[i] = rule.maxTimeLedToLose * 60;
winner = ~Color(i); winner = ~Color(i);
gameoverReason = LOST_REASON_TIME_OVER; gameoverReason = LOSE_REASON_TIME_OVER;
sprintf(cmdline, "Time over. Player%d win!", ~Color(i)); sprintf(cmdline, "Time over. Player%d win!", ~Color(i));
} }
} }
cmdlist.emplace_back(string(cmdline));
} }
return true; return true;
@ -1023,8 +1010,8 @@ bool Position::check_gameover_condition(int8_t updateCmdlist)
winner = DRAW; winner = DRAW;
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
if (updateCmdlist) { if (updateCmdlist) {
gameoverReason = DRAW_REASON_RULE_50;
sprintf(cmdline, "Steps over. In draw!"); sprintf(cmdline, "Steps over. In draw!");
cmdlist.emplace_back(string(cmdline));
} }
return true; return true;
@ -1035,10 +1022,10 @@ bool Position::check_gameover_condition(int8_t updateCmdlist)
if (pieceCountOnBoard[i] + pieceCountInHand[i] < rule.nPiecesAtLeast) { if (pieceCountOnBoard[i] + pieceCountInHand[i] < rule.nPiecesAtLeast) {
winner = ~Color(i); winner = ~Color(i);
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
gameoverReason = LOSE_REASON_LESS_THAN_THREE;
if (updateCmdlist) { if (updateCmdlist) {
sprintf(cmdline, "Player%d win!", winner); sprintf(cmdline, "Player%d win!", winner);
cmdlist.emplace_back(string(cmdline));
} }
return true; return true;
@ -1052,7 +1039,6 @@ bool Position::check_gameover_condition(int8_t updateCmdlist)
winner = BLACK; winner = BLACK;
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
sprintf(cmdline, "Player1 win!"); sprintf(cmdline, "Player1 win!");
cmdlist.emplace_back(string(cmdline));
return true; return true;
} }
@ -1061,7 +1047,6 @@ bool Position::check_gameover_condition(int8_t updateCmdlist)
winner = WHITE; winner = WHITE;
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
sprintf(cmdline, "Player2 win!"); sprintf(cmdline, "Player2 win!");
cmdlist.emplace_back(string(cmdline));
return true; return true;
} }
@ -1073,20 +1058,18 @@ bool Position::check_gameover_condition(int8_t updateCmdlist)
if (rule.isBlackLosebutNotDrawWhenBoardFull) { if (rule.isBlackLosebutNotDrawWhenBoardFull) {
winner = WHITE; winner = WHITE;
gameoverReason = LOSE_REASON_BOARD_IS_FULL;
if (updateCmdlist) { if (updateCmdlist) {
sprintf(cmdline, "Player2 win!"); sprintf(cmdline, "Player2 win!");
} }
} else { } else {
winner = DRAW; winner = DRAW;
gameoverReason = DRAW_REASON_BOARD_IS_FULL;
if (updateCmdlist) { if (updateCmdlist) {
sprintf(cmdline, "Full. In draw!"); sprintf(cmdline, "Full. In draw!");
} }
} }
if (updateCmdlist) {
cmdlist.emplace_back(string(cmdline));
}
return true; return true;
} }
@ -1099,7 +1082,6 @@ bool Position::check_gameover_condition(int8_t updateCmdlist)
gameoverReason = LOSE_REASON_NO_WAY; gameoverReason = LOSE_REASON_NO_WAY;
winner = ~sideToMove; winner = ~sideToMove;
sprintf(cmdline, "Player%d no way to go. Player%d win!", sideToMove, winner); sprintf(cmdline, "Player%d no way to go. Player%d win!", sideToMove, winner);
cmdlist.emplace_back(string(cmdline)); // TODO: memleak
} }
return true; return true;
@ -1644,7 +1626,7 @@ bool Position::is_star_square(Square s)
s == 22); s == 22);
} }
void Position::mirror(bool cmdChange /*= true*/) void Position::mirror(vector <string> &cmdlist, bool cmdChange /*= true*/)
{ {
Piece ch; Piece ch;
int f, r; int f, r;
@ -1753,7 +1735,7 @@ void Position::mirror(bool cmdChange /*= true*/)
} }
} }
void Position::turn(bool cmdChange /*= true*/) void Position::turn(vector <string> &cmdlist, bool cmdChange /*= true*/)
{ {
Piece ch; Piece ch;
int f, r; int f, r;
@ -1916,7 +1898,7 @@ void Position::turn(bool cmdChange /*= true*/)
} }
} }
void Position::rotate(int degrees, bool cmdChange /*= true*/) void Position::rotate(vector <string> &cmdlist, int degrees, bool cmdChange /*= true*/)
{ {
degrees = degrees % 360; degrees = degrees % 360;

View File

@ -127,7 +127,6 @@ public:
enum Phase get_phase() const; enum Phase get_phase() const;
enum Action get_action() const; enum Action get_action() const;
const char *cmd_line() const; const char *cmd_line() const;
const std::vector<std::string> *cmd_list() const;
int get_mobility_diff(bool includeFobidden); int get_mobility_diff(bool includeFobidden);
@ -144,9 +143,9 @@ public:
void change_side_to_move(); void change_side_to_move();
Color get_winner() const; Color get_winner() const;
void mirror(bool cmdChange = true); void mirror(vector <string> &cmdlist, bool cmdChange = true);
void turn(bool cmdChange = true); void turn(vector <string> &cmdlist, bool cmdChange = true);
void rotate(int degrees, bool cmdChange = true); void rotate(vector <string> &cmdlist, int degrees, bool cmdChange = true);
void create_mill_table(); void create_mill_table();
int add_mills(Square s); int add_mills(Square s);
@ -209,7 +208,6 @@ public:
Square currentSquare; Square currentSquare;
int nPlayed { 0 }; int nPlayed { 0 };
std::vector <std::string> cmdlist;
char cmdline[64] { '\0' }; char cmdline[64] { '\0' };
int tm { -1 }; int tm { -1 };
@ -352,11 +350,6 @@ inline const char *Position::cmd_line() const
return cmdline; return cmdline;
} }
inline const std::vector<std::string> *Position::cmd_list() const
{
return &cmdlist;
}
inline time_t Position::start_timeb() const inline time_t Position::start_timeb() const
{ {
return startTime; return startTime;

View File

@ -575,6 +575,7 @@ string AIAlgorithm::nextMove()
if (gameOptions.getGiveUpIfMostLose() == true) { if (gameOptions.getGiveUpIfMostLose() == true) {
if (root->value <= -VALUE_MATE) { if (root->value <= -VALUE_MATE) {
gameoverReason = LOSE_REASON_GIVE_UP;
sprintf(cmdline, "Player%d give up!", position->sideToMove); sprintf(cmdline, "Player%d give up!", position->sideToMove);
return cmdline; return cmdline;
} }

View File

@ -161,11 +161,14 @@ enum Action : uint16_t
enum GameOverReason enum GameOverReason
{ {
NO_REASON, NO_REASON,
LOSE_EASON_LESS_THAN_THREE, LOSE_REASON_LESS_THAN_THREE,
LOSE_REASON_NO_WAY, LOSE_REASON_NO_WAY,
LOSE_REASON_BOARD_IS_FULL,
LOSE_REASON_GIVE_UP, LOSE_REASON_GIVE_UP,
LOST_REASON_TIME_OVER, LOSE_REASON_TIME_OVER,
DRAW_REASON_THREEFOLD_REPETITION, DRAW_REASON_THREEFOLD_REPETITION,
DRAW_REASON_RULE_50,
DRAW_REASON_BOARD_IS_FULL,
}; };
enum Bound : uint8_t enum Bound : uint8_t

View File

@ -102,6 +102,8 @@ GameController::GameController(
} }
#endif #endif
cmdlist.reserve(256);
// 安装事件过滤器监视scene的各个事件 // 安装事件过滤器监视scene的各个事件
// 由于我重载了QGraphicsScene相关事件在重载函数中已设定不必安装监视器。 // 由于我重载了QGraphicsScene相关事件在重载函数中已设定不必安装监视器。
//scene.installEventFilter(this); //scene.installEventFilter(this);
@ -122,6 +124,8 @@ GameController::~GameController()
AIAlgorithm::recordEndgameHashMapToFile(); AIAlgorithm::recordEndgameHashMapToFile();
} }
#endif /* ENDGAME_LEARNING */ #endif /* ENDGAME_LEARNING */
cmdlist.clear();
} }
const map<int, QStringList> GameController::getActions() const map<int, QStringList> GameController::getActions()
@ -180,6 +184,8 @@ void GameController::gameReset()
// 重置游戏 // 重置游戏
position.reset(); position.reset();
cmdlist.clear();
// 停掉线程 // 停掉线程
if (!gameOptions.getAutoRestart()) { if (!gameOptions.getAutoRestart()) {
stopThreads(); stopThreads();
@ -330,6 +336,8 @@ void GameController::setRule(int ruleNo, Step stepLimited /*= -1*/, int timeLimi
// 重置游戏 // 重置游戏
gameReset(); gameReset();
cmdlist.clear();
} }
void GameController::setEngine(int color, bool arg) void GameController::setEngine(int color, bool arg)
@ -551,12 +559,12 @@ void GameController::flip()
#ifndef TRAINING_MODE #ifndef TRAINING_MODE
stopAndWaitAiThreads(); stopAndWaitAiThreads();
position.mirror(); position.mirror(cmdlist);
position.rotate(180); position.rotate(cmdlist, 180);
// 更新棋谱 // 更新棋谱
int row = 0; int row = 0;
for (const auto &str : *(position.cmd_list())) { for (const auto &str : *(cmd_list())) {
manualListModel.setData(manualListModel.index(row++), str.c_str()); manualListModel.setData(manualListModel.index(row++), str.c_str());
} }
@ -577,12 +585,12 @@ void GameController::mirror()
#ifndef TRAINING_MODE #ifndef TRAINING_MODE
stopAndWaitAiThreads(); stopAndWaitAiThreads();
position.mirror(); position.mirror(cmdlist);
// 更新棋谱 // 更新棋谱
int row = 0; int row = 0;
for (const auto &str : *(position.cmd_list())) { for (const auto &str : *(cmd_list())) {
manualListModel.setData(manualListModel.index(row++), str.c_str()); manualListModel.setData(manualListModel.index(row++), str.c_str());
} }
@ -605,12 +613,12 @@ void GameController::turnRight()
#ifndef TRAINING_MODE #ifndef TRAINING_MODE
stopAndWaitAiThreads(); stopAndWaitAiThreads();
position.rotate(-90); position.rotate(cmdlist, -90);
// 更新棋谱 // 更新棋谱
int row = 0; int row = 0;
for (const auto &str : *(position.cmd_list())) { for (const auto &str : *(cmd_list())) {
manualListModel.setData(manualListModel.index(row++), str.c_str()); manualListModel.setData(manualListModel.index(row++), str.c_str());
} }
@ -631,11 +639,11 @@ void GameController::turnLeft()
#ifndef TRAINING_MODE #ifndef TRAINING_MODE
stopAndWaitAiThreads(); stopAndWaitAiThreads();
position.rotate(90); position.rotate(cmdlist, 90);
// 更新棋谱 // 更新棋谱
int row = 0; int row = 0;
for (const auto &str : *(position.cmd_list())) { for (const auto &str : *(cmd_list())) {
manualListModel.setData(manualListModel.index(row++), str.c_str()); manualListModel.setData(manualListModel.index(row++), str.c_str());
} }
@ -840,7 +848,7 @@ bool GameController::actionPiece(QPointF pos)
int k = 0; int k = 0;
// 输出命令行 // 输出命令行
for (const auto & i : *(position.cmd_list())) { for (const auto & i : *(cmd_list())) {
// 跳过已添加的因标准list容器没有下标 // 跳过已添加的因标准list容器没有下标
if (k++ <= currentRow) if (k++ <= currentRow)
continue; continue;
@ -890,7 +898,7 @@ bool GameController::giveUp()
int k = 0; int k = 0;
// 输出命令行 // 输出命令行
for (const auto & i : *(position.cmd_list())) { for (const auto & i : *(cmd_list())) {
// 跳过已添加的因标准list容器没有下标 // 跳过已添加的因标准list容器没有下标
if (k++ <= currentRow) if (k++ <= currentRow)
continue; continue;
@ -944,6 +952,8 @@ bool GameController::command(const string &cmd, bool update /* = true */)
loggerDebug("Computer: %s\n\n", cmd.c_str()); loggerDebug("Computer: %s\n\n", cmd.c_str());
cmdlist.emplace_back(cmd);
if (!position.command(cmd.c_str())) if (!position.command(cmd.c_str()))
return false; return false;
@ -962,7 +972,7 @@ bool GameController::command(const string &cmd, bool update /* = true */)
emit statusBarChanged(message); emit statusBarChanged(message);
// 对于新开局 // 对于新开局
if (position.cmd_list()->size() <= 1) { if (cmd_list()->size() <= 1) {
manualListModel.removeRows(0, manualListModel.rowCount()); manualListModel.removeRows(0, manualListModel.rowCount());
manualListModel.insertRow(0); manualListModel.insertRow(0);
manualListModel.setData(manualListModel.index(0), position.cmd_line()); manualListModel.setData(manualListModel.index(0), position.cmd_line());
@ -972,13 +982,13 @@ bool GameController::command(const string &cmd, bool update /* = true */)
else { else {
currentRow = manualListModel.rowCount() - 1; currentRow = manualListModel.rowCount() - 1;
// 跳过已添加行,迭代器不支持+运算符,只能一个个++ // 跳过已添加行,迭代器不支持+运算符,只能一个个++
auto i = (position.cmd_list()->begin()); auto i = (cmd_list()->begin());
for (int r = 0; i != (position.cmd_list())->end(); i++) { for (int r = 0; i != (cmd_list())->end(); i++) {
if (r++ > currentRow) if (r++ > currentRow)
break; break;
} }
// 将新增的棋谱行插入到ListModel // 将新增的棋谱行插入到ListModel
while (i != position.cmd_list()->end()) { while (i != cmd_list()->end()) {
manualListModel.insertRow(++currentRow); manualListModel.insertRow(++currentRow);
manualListModel.setData(manualListModel.index(currentRow), (*i++).c_str()); manualListModel.setData(manualListModel.index(currentRow), (*i++).c_str());
} }
@ -1437,7 +1447,7 @@ void GameController::setTips()
} }
switch (p.gameoverReason) { switch (p.gameoverReason) {
case LOSE_EASON_LESS_THAN_THREE: case LOSE_REASON_LESS_THAN_THREE:
break; break;
case LOSE_REASON_NO_WAY: case LOSE_REASON_NO_WAY:
reasonStr = turnStr + "无子可走被闷。"; reasonStr = turnStr + "无子可走被闷。";
@ -1445,7 +1455,7 @@ void GameController::setTips()
case LOSE_REASON_GIVE_UP: case LOSE_REASON_GIVE_UP:
reasonStr = turnStr + "投子认负。"; reasonStr = turnStr + "投子认负。";
break; break;
case LOST_REASON_TIME_OVER: case LOSE_REASON_TIME_OVER:
reasonStr = turnStr + "超时判负。"; reasonStr = turnStr + "超时判负。";
break; break;
case DRAW_REASON_THREEFOLD_REPETITION: case DRAW_REASON_THREEFOLD_REPETITION:

View File

@ -140,6 +140,11 @@ public:
std::string char_to_string(char ch); std::string char_to_string(char ch);
void setTips(); void setTips();
inline const std::vector<std::string> *cmd_list() const
{
return &cmdlist;
}
signals: signals:
// 总盘数改变的信号 // 总盘数改变的信号
@ -447,6 +452,8 @@ private:
// 提示语 // 提示语
string tips; string tips;
std::vector <std::string> cmdlist;
}; };
#endif // GAMECONTROLLER_H #endif // GAMECONTROLLER_H