diff --git a/src/ai/evaluate.cpp b/src/ai/evaluate.cpp index 7533c954..f77a5215 100644 --- a/src/ai/evaluate.cpp +++ b/src/ai/evaluate.cpp @@ -21,7 +21,7 @@ #include "evaluate.h" -value_t Evaluation::getValue(Game &dummyPosition, PositionContext *positionContext, MillGameAi_ab::Node *node) +value_t Evaluation::getValue(Game &dummyGame, PositionContext *positionContext, MillGameAi_ab::Node *node) { // 初始评估值为0,对先手有利则增大,对后手有利则减小 value_t value = VALUE_ZERO; @@ -83,7 +83,7 @@ value_t Evaluation::getValue(Game &dummyPosition, PositionContext *positionConte #ifdef EVALUATE_MOBILITY // 按棋子活动能力计分 - value += dummyPosition.getMobilityDiff(positionContext->turn, dummyPosition.currentRule, positionContext->nPiecesInHand[1], positionContext->nPiecesInHand[2], false) * 10; + value += dummyGame.getMobilityDiff(positionContext->turn, dummyGame.currentRule, positionContext->nPiecesInHand[1], positionContext->nPiecesInHand[2], false) * 10; #endif /* EVALUATE_MOBILITY */ switch (positionContext->action) { @@ -112,7 +112,7 @@ value_t Evaluation::getValue(Game &dummyPosition, PositionContext *positionConte // 布局阶段闷棋判断 if (positionContext->nPiecesOnBoard[1] + positionContext->nPiecesOnBoard[2] >= Board::N_SEATS * Board::N_RINGS) { - if (dummyPosition.getRule()->isStartingPlayerLoseWhenBoardFull) { + if (dummyGame.getRule()->isStartingPlayerLoseWhenBoardFull) { value -= VALUE_WIN; } else { value = VALUE_DRAW; @@ -121,17 +121,17 @@ value_t Evaluation::getValue(Game &dummyPosition, PositionContext *positionConte // 走棋阶段被闷判断 if (positionContext->action == ACTION_CHOOSE && - dummyPosition.context.board.isAllSurrounded(positionContext->turn, dummyPosition.currentRule, positionContext->nPiecesOnBoard, positionContext->turn) && - dummyPosition.getRule()->isLoseWhenNoWay) { + dummyGame.context.board.isAllSurrounded(positionContext->turn, dummyGame.currentRule, positionContext->nPiecesOnBoard, positionContext->turn) && + dummyGame.getRule()->isLoseWhenNoWay) { // 规则要求被“闷”判负,则对手获胜 value_t delta = positionContext->turn == PLAYER_1 ? -VALUE_WIN : VALUE_WIN; value += delta; } // 剩余棋子个数判断 - if (positionContext->nPiecesOnBoard[1] < dummyPosition.getRule()->nPiecesAtLeast) { + if (positionContext->nPiecesOnBoard[1] < dummyGame.getRule()->nPiecesAtLeast) { value -= VALUE_WIN; - } else if (positionContext->nPiecesOnBoard[2] < dummyPosition.getRule()->nPiecesAtLeast) { + } else if (positionContext->nPiecesOnBoard[2] < dummyGame.getRule()->nPiecesAtLeast) { value += VALUE_WIN; } diff --git a/src/ai/evaluate.h b/src/ai/evaluate.h index c96ccc5b..98d14c16 100644 --- a/src/ai/evaluate.h +++ b/src/ai/evaluate.h @@ -34,7 +34,7 @@ public: Evaluation &operator=(const Evaluation &) = delete; - static value_t getValue(Game &dummyPosition, PositionContext *positionContext, MillGameAi_ab::Node *node); + static value_t getValue(Game &dummyGame, PositionContext *positionContext, MillGameAi_ab::Node *node); // 评估子力 #ifdef EVALUATE_ENABLE diff --git a/src/ai/movegen.cpp b/src/ai/movegen.cpp index d974ec96..5e41b929 100644 --- a/src/ai/movegen.cpp +++ b/src/ai/movegen.cpp @@ -25,7 +25,7 @@ #include "player.h" #include "misc.h" -void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyPosition, +void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame, MillGameAi_ab::Node *node, MillGameAi_ab::Node *rootNode, move_t bestMove) { @@ -34,17 +34,17 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyPosition, size_t newCapacity = 24; // 留足余量空间避免多次重新分配,此动作本身也占用 CPU/内存 开销 - switch (dummyPosition.getPhase()) { + switch (dummyGame.getPhase()) { case PHASE_PLACING: - if (dummyPosition.getAction() == ACTION_CAPTURE) { - newCapacity = static_cast(dummyPosition.getPiecesOnBoardCount(dummyPosition.context.opponentId)); + if (dummyGame.getAction() == ACTION_CAPTURE) { + newCapacity = static_cast(dummyGame.getPiecesOnBoardCount(dummyGame.context.opponentId)); } else { - newCapacity = static_cast(dummyPosition.getPiecesInHandCount(1) + dummyPosition.getPiecesInHandCount(2)); + newCapacity = static_cast(dummyGame.getPiecesInHandCount(1) + dummyGame.getPiecesInHandCount(2)); } break; case PHASE_MOVING: - if (dummyPosition.getAction() == ACTION_CAPTURE) { - newCapacity = static_cast(dummyPosition.getPiecesOnBoardCount(dummyPosition.context.opponentId)); + if (dummyGame.getAction() == ACTION_CAPTURE) { + newCapacity = static_cast(dummyGame.getPiecesOnBoardCount(dummyGame.context.opponentId)); } else { newCapacity = 6; } @@ -65,28 +65,28 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyPosition, } // 对手 - player_t opponent = Player::getOpponent(dummyPosition.context.turn); + player_t opponent = Player::getOpponent(dummyGame.context.turn); // 列出所有合法的下一招 - switch (dummyPosition.context.action) { + switch (dummyGame.context.action) { // 对于选子和落子动作 case ACTION_CHOOSE: case ACTION_PLACE: // 对于摆子阶段 - if (dummyPosition.context.phase & (PHASE_PLACING | PHASE_NOTSTARTED)) { + if (dummyGame.context.phase & (PHASE_PLACING | PHASE_NOTSTARTED)) { for (move_t i : movePriorityTable) { location = i; - if (dummyPosition.boardLocations[location]) { + if (dummyGame.boardLocations[location]) { continue; } - if (dummyPosition.context.phase != PHASE_NOTSTARTED || node != rootNode) { - ai_ab.addNode(node, VALUE_ZERO, (move_t)location, bestMove, dummyPosition.context.turn); + if (dummyGame.context.phase != PHASE_NOTSTARTED || node != rootNode) { + ai_ab.addNode(node, VALUE_ZERO, (move_t)location, bestMove, dummyGame.context.turn); } else { // 若为先手,则抢占星位 if (Board::isStarLocation(location)) { - ai_ab.addNode(node, VALUE_INFINITE, (move_t)location, bestMove, dummyPosition.context.turn); + ai_ab.addNode(node, VALUE_INFINITE, (move_t)location, bestMove, dummyGame.context.turn); } } } @@ -94,34 +94,34 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyPosition, } // 对于移子阶段 - if (dummyPosition.context.phase & PHASE_MOVING) { + if (dummyGame.context.phase & PHASE_MOVING) { int newLocation, oldLocation; // 尽量走理论上较差的位置的棋子 for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) { oldLocation = movePriorityTable[i]; - if (!dummyPosition.choose(oldLocation)) { + if (!dummyGame.choose(oldLocation)) { continue; } - if (dummyPosition.context.nPiecesOnBoard[dummyPosition.context.turnId] > dummyPosition.currentRule.nPiecesAtLeast || - !dummyPosition.currentRule.allowFlyWhenRemainThreePieces) { + if (dummyGame.context.nPiecesOnBoard[dummyGame.context.turnId] > dummyGame.currentRule.nPiecesAtLeast || + !dummyGame.currentRule.allowFlyWhenRemainThreePieces) { // 对于棋盘上还有3个子以上,或不允许飞子的情况,要求必须在着法表中 for (int direction = DIRECTION_CLOCKWISE; direction <= DIRECTION_OUTWARD; direction++) { // 对于原有位置,遍历四个方向的着法,如果棋盘上为空位就加到结点列表中 newLocation = moveTable[oldLocation][direction]; - if (newLocation && !dummyPosition.boardLocations[newLocation]) { + if (newLocation && !dummyGame.boardLocations[newLocation]) { move_t move = move_t((oldLocation << 8) + newLocation); - ai_ab.addNode(node, VALUE_ZERO, move, bestMove, dummyPosition.context.turn); // (12%) + ai_ab.addNode(node, VALUE_ZERO, move, bestMove, dummyGame.context.turn); // (12%) } } } else { // 对于棋盘上还有不到3个字,但允许飞子的情况,不要求在着法表中,是空位就行 for (newLocation = Board::LOCATION_BEGIN; newLocation < Board::LOCATION_END; newLocation++) { - if (!dummyPosition.boardLocations[newLocation]) { + if (!dummyGame.boardLocations[newLocation]) { move_t move = move_t((oldLocation << 8) + newLocation); - ai_ab.addNode(node, VALUE_ZERO, move, bestMove, dummyPosition.context.turn); + ai_ab.addNode(node, VALUE_ZERO, move, bestMove, dummyGame.context.turn); } } } @@ -131,12 +131,12 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyPosition, // 对于吃子动作 case ACTION_CAPTURE: - if (dummyPosition.context.board.isAllInMills(opponent)) { + if (dummyGame.context.board.isAllInMills(opponent)) { // 全成三的情况 for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) { location = movePriorityTable[i]; - if (dummyPosition.boardLocations[location] & opponent) { - ai_ab.addNode(node, VALUE_ZERO, (move_t)-location, bestMove, dummyPosition.context.turn); + if (dummyGame.boardLocations[location] & opponent) { + ai_ab.addNode(node, VALUE_ZERO, (move_t)-location, bestMove, dummyGame.context.turn); } } break; @@ -145,9 +145,9 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyPosition, // 不是全成三的情况 for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) { location = movePriorityTable[i]; - if (dummyPosition.boardLocations[location] & opponent) { - if (dummyPosition.getRule()->allowRemoveMill || !dummyPosition.context.board.inHowManyMills(location)) { - ai_ab.addNode(node, VALUE_ZERO, (move_t)-location, bestMove, dummyPosition.context.turn); + if (dummyGame.boardLocations[location] & opponent) { + if (dummyGame.getRule()->allowRemoveMill || !dummyGame.context.board.inHowManyMills(location)) { + ai_ab.addNode(node, VALUE_ZERO, (move_t)-location, bestMove, dummyGame.context.turn); } } } diff --git a/src/ai/movegen.h b/src/ai/movegen.h index b0639586..6939c861 100644 --- a/src/ai/movegen.h +++ b/src/ai/movegen.h @@ -34,7 +34,7 @@ public: MoveList &operator=(const MoveList &) = delete; // 生成所有合法的着法并建立子节点 - static void generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyPosition, + static void generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame, MillGameAi_ab::Node *node, MillGameAi_ab::Node *rootNode, move_t bestMove); diff --git a/src/ai/search.cpp b/src/ai/search.cpp index 3e2a1b14..fc44d449 100644 --- a/src/ai/search.cpp +++ b/src/ai/search.cpp @@ -57,7 +57,7 @@ depth_t MillGameAi_ab::changeDepth(depth_t originalDepth) { depth_t newDepth = originalDepth; - if ((dummyPosition.context.phase) & (PHASE_PLACING)) { + if ((dummyGame.context.phase) & (PHASE_PLACING)) { #ifdef GAME_PLACING_DYNAMIC_DEPTH #ifdef DEAL_WITH_HORIZON_EFFECT #ifdef TRANSPOSITION_TABLE_ENABLE @@ -77,7 +77,7 @@ depth_t MillGameAi_ab::changeDepth(depth_t originalDepth) depth_t depthTable[] = { 2, 13, 13, 13, 12, 11, 10, 9, 9, 8, 8, 7, 1 }; #endif #endif // DEAL_WITH_HORIZON_EFFECT - newDepth = depthTable[dummyPosition.getPiecesInHandCount(1)]; + newDepth = depthTable[dummyGame.getPiecesInHandCount(1)]; #elif defined GAME_PLACING_FIXED_DEPTH newDepth = GAME_PLACING_FIXED_DEPTH; #endif // GAME_PLACING_DYNAMIC_DEPTH @@ -85,7 +85,7 @@ depth_t MillGameAi_ab::changeDepth(depth_t originalDepth) #ifdef GAME_MOVING_FIXED_DEPTH // 走棋阶段将深度调整 - if ((dummyPosition.context.phase) & (PHASE_MOVING)) { + if ((dummyGame.context.phase) & (PHASE_MOVING)) { newDepth = GAME_MOVING_FIXED_DEPTH; } #endif /* GAME_MOVING_FIXED_DEPTH */ @@ -141,8 +141,8 @@ struct MillGameAi_ab::Node *MillGameAi_ab::addNode( #ifdef DEBUG_AB_TREE newNode->root = rootNode; - newNode->phase = dummyPosition.context.phase; - newNode->action = dummyPosition.context.action; + newNode->phase = dummyGame.context.phase; + newNode->action = dummyGame.context.action; newNode->evaluated = false; newNode->nPiecesInHandDiff = INT_MAX; newNode->nPiecesOnBoardDiff = INT_MAX; @@ -155,15 +155,15 @@ struct MillGameAi_ab::Node *MillGameAi_ab::addNode( char cmd[32] = { 0 }; if (move < 0) { - dummyPosition.context.board.locationToPolar(-move, r, s); + dummyGame.context.board.locationToPolar(-move, r, s); sprintf(cmd, "-(%1u,%1u)", r, s); } else if (move & 0x7f00) { int r1, s1; - dummyPosition.context.board.locationToPolar(move >> 8, r1, s1); - dummyPosition.context.board.locationToPolar(move & 0x00ff, r, s); + dummyGame.context.board.locationToPolar(move >> 8, r1, s1); + dummyGame.context.board.locationToPolar(move & 0x00ff, r, s); sprintf(cmd, "(%1u,%1u)->(%1u,%1u)", r1, s1, r, s); } else { - dummyPosition.context.board.locationToPolar(move & 0x007f, r, s); + dummyGame.context.board.locationToPolar(move & 0x007f, r, s); sprintf(cmd, "(%1u,%1u)", r, s); } @@ -175,7 +175,7 @@ struct MillGameAi_ab::Node *MillGameAi_ab::addNode( if (bestMove == 0 || move != bestMove) { #ifdef MILL_FIRST // 优先成三 - if (dummyPosition.getPhase() == GAME_PLACING && move > 0 && dummyPosition.context.board.isInMills(move, true)) { + if (dummyGame.getPhase() == GAME_PLACING && move > 0 && dummyGame.context.board.isInMills(move, true)) { parent->children.insert(parent->children.begin(), newNode); } else { parent->children.push_back(newNode); @@ -232,7 +232,7 @@ void MillGameAi_ab::sortLegalMoves(Node *node) { // 这个函数对效率的影响很大,排序好的话,剪枝较早,节省时间,但不能在此函数耗费太多时间 - auto cmp = dummyPosition.context.turn == PLAYER_1 ? nodeGreater : nodeLess; + auto cmp = dummyGame.context.turn == PLAYER_1 ? nodeGreater : nodeLess; std::stable_sort(node->children.begin(), node->children.end(), cmp); } @@ -275,8 +275,8 @@ void MillGameAi_ab::setPosition(const Game &position) } this->position_ = position; - dummyPosition = position; - positionContext = &(dummyPosition.context); + dummyGame = position; + positionContext = &(dummyGame.context); requiredQuit = false; deleteTree(rootNode); #ifdef MEMORY_POOL @@ -397,7 +397,7 @@ value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t alpha, value_t be enum TranspositionTable::HashType hashf = TranspositionTable::hashfALPHA; // 获取哈希值 - hash_t hash = dummyPosition.getHash(); + hash_t hash = dummyGame.getHash(); #ifdef DEBUG_AB_TREE node->hash = hash; #endif @@ -454,7 +454,7 @@ value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t alpha, value_t be // 搜索到叶子节点(决胜局面) // TODO: 对哈希进行特殊处理 if (positionContext->phase == PHASE_GAMEOVER) { // 局面评估 - node->value = Evaluation::getValue(dummyPosition, positionContext, node); + node->value = Evaluation::getValue(dummyGame, positionContext, node); evaluatedNodeCount++; // 为争取速胜,value 值 +- 深度 @@ -479,7 +479,7 @@ value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t alpha, value_t be // 搜索到第0层或需要退出 if (!depth || requiredQuit) { // 局面评估 - node->value = Evaluation::getValue(dummyPosition, positionContext, node); + node->value = Evaluation::getValue(dummyGame, positionContext, node); evaluatedNodeCount++; // 为争取速胜,value 值 +- 深度 (有必要?) @@ -511,18 +511,18 @@ value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t alpha, value_t be } // 生成子节点树,即生成每个合理的着法 - MoveList::generateLegalMoves(*this, dummyPosition, node, rootNode, bestMove); + MoveList::generateLegalMoves(*this, dummyGame, node, rootNode, bestMove); // 根据演算模型执行 MiniMax 检索,对先手,搜索 Max, 对后手,搜索 Min - minMax = dummyPosition.context.turn == PLAYER_1 ? -VALUE_INFINITE : VALUE_INFINITE; + minMax = dummyGame.context.turn == PLAYER_1 ? -VALUE_INFINITE : VALUE_INFINITE; for (auto child : node->children) { // 上下文入栈保存,以便后续撤销着法 - contextStack.push(dummyPosition.context); + contextStack.push(dummyGame.context); // 执行着法 - dummyPosition.command(child->move); + dummyGame.command(child->move); #ifdef DEAL_WITH_HORIZON_EFFECT // 克服“水平线效应”: 若遇到吃子,则搜索深度增加 @@ -543,10 +543,10 @@ value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t alpha, value_t be value = alphaBetaPruning(depth - 1 + epsilon, alpha, beta, child); // 上下文弹出栈,撤销着法 - dummyPosition.context = contextStack.top(); + dummyGame.context = contextStack.top(); contextStack.pop(); - if (dummyPosition.context.turn == PLAYER_1) { + if (dummyGame.context.turn == PLAYER_1) { // 为走棋一方的层, 局面对走棋的一方来说是以 α 为评价 // 取最大值 @@ -722,15 +722,15 @@ const char *MillGameAi_ab::move2string(move_t move) int r, s; if (move < 0) { - dummyPosition.context.board.locationToPolar(-move, r, s); + dummyGame.context.board.locationToPolar(-move, r, s); sprintf(cmdline, "-(%1u,%1u)", r, s); } else if (move & 0x7f00) { int r1, s1; - dummyPosition.context.board.locationToPolar(move >> 8, r1, s1); - dummyPosition.context.board.locationToPolar(move & 0x00ff, r, s); + dummyGame.context.board.locationToPolar(move >> 8, r1, s1); + dummyGame.context.board.locationToPolar(move & 0x00ff, r, s); sprintf(cmdline, "(%1u,%1u)->(%1u,%1u)", r1, s1, r, s); } else { - dummyPosition.context.board.locationToPolar(move & 0x007f, r, s); + dummyGame.context.board.locationToPolar(move & 0x007f, r, s); sprintf(cmdline, "(%1u,%1u)", r, s); } diff --git a/src/ai/search.h b/src/ai/search.h index 24e9144e..48404212 100644 --- a/src/ai/search.h +++ b/src/ai/search.h @@ -185,12 +185,12 @@ private: Game position_; // 演算用的模型 - Game dummyPosition; + Game dummyGame; PositionContext *positionContext {}; // hash 计算时,各种转换用的模型 - Game dummyPositionShift; + Game dummyGameShift; // 根节点 Node *rootNode {nullptr}; diff --git a/src/ai/tt.cpp b/src/ai/tt.cpp index efd84b1e..81b3d13a 100644 --- a/src/ai/tt.cpp +++ b/src/ai/tt.cpp @@ -49,17 +49,17 @@ bool TranspositionTable::findHash(hash_t hash, TranspositionTable::HashValue &ha return iter; // 变换局面,查找 hash (废弃) - dummyPositionShift = dummyPosition; + dummyGameShift = dummyGame; for (int i = 0; i < 2; i++) { if (i) - dummyPositionShift.mirror(false); + dummyGameShift.mirror(false); for (int j = 0; j < 2; j++) { if (j) - dummyPositionShift.turn(false); + dummyGameShift.turn(false); for (int k = 0; k < 4; k++) { - dummyPositionShift.rotate(k * 90, false); - iter = hashmap.find(dummyPositionShift.getHash()); + dummyGameShift.rotate(k * 90, false); + iter = hashmap.find(dummyGameShift.getHash()); if (iter != hashmap.end()) return iter; } diff --git a/src/game/position.h b/src/game/position.h index 8801776b..4d426a45 100644 --- a/src/game/position.h +++ b/src/game/position.h @@ -72,8 +72,8 @@ public: }; // 棋类(在数据模型内,玩家只分先后手,不分黑白) -// 注意:Position 类不是线程安全的! -// 所以不能跨线程修改 Position 类的静态成员变量,切记! +// 注意:Game 类不是线程安全的! +// 所以不能跨线程修改 Game 类的静态成员变量,切记! class Game { // AI友元类 diff --git a/src/ui/qt/gamecontroller.cpp b/src/ui/qt/gamecontroller.cpp index a3cba2f0..9b855569 100644 --- a/src/ui/qt/gamecontroller.cpp +++ b/src/ui/qt/gamecontroller.cpp @@ -124,7 +124,7 @@ void GameController::gameStart() { position_.configure(giveUpIfMostLose_, randomMove_); position_.start(); - dummyPosition = position_; + dummyGame = position_; // 每隔100毫秒调用一次定时器处理函数 if (timeID == 0) { @@ -150,7 +150,7 @@ void GameController::gameReset() // 重置游戏 position_.configure(giveUpIfMostLose_, randomMove_); position_.reset(); - dummyPosition = position_; + dummyGame = position_; // 停掉线程 if (!isAutoRestart) { @@ -281,7 +281,7 @@ void GameController::setRule(int ruleNo, step_t stepLimited /*= -1*/, int timeLi // 设置模型规则,重置游戏 position_.setContext(&RULES[ruleNo], stepsLimit, timeLimit); - dummyPosition = position_; + dummyGame = position_; // 重置游戏 gameReset(); @@ -400,7 +400,7 @@ void GameController::flip() position_.context.board.mirror(position_.cmdlist, position_.cmdline, position_.move_, position_.currentRule, position_.currentLocation); position_.context.board.rotate(180, position_.cmdlist, position_.cmdline, position_.move_, position_.currentRule, position_.currentLocation); - dummyPosition = position_; + dummyGame = position_; // 更新棋谱 int row = 0; @@ -439,7 +439,7 @@ void GameController::mirror() } position_.context.board.mirror(position_.cmdlist, position_.cmdline, position_.move_, position_.currentRule, position_.currentLocation); - dummyPosition = position_; + dummyGame = position_; // 更新棋谱 int row = 0; @@ -481,7 +481,7 @@ void GameController::turnRight() } position_.context.board.rotate(-90, position_.cmdlist, position_.cmdline, position_.move_, position_.currentRule, position_.currentLocation); - dummyPosition = position_; + dummyGame = position_; // 更新棋谱 int row = 0; @@ -521,7 +521,7 @@ void GameController::turnLeft() } position_.context.board.rotate(90, position_.cmdlist, position_.cmdline, position_.move_, position_.currentRule, position_.currentLocation); - dummyPosition = position_; + dummyGame = position_; // 更新棋谱 int row = 0; @@ -642,7 +642,7 @@ bool GameController::actionPiece(QPointF pos) if (QMessageBox::Ok == msgBox.exec()) { #endif /* !MOBILE_APP_UI */ - position_ = dummyPosition; + position_ = dummyGame; manualListModel.removeRows(currentRow + 1, manualListModel.rowCount() - currentRow - 1); // 如果再决出胜负后悔棋,则重新启动计时 @@ -953,14 +953,14 @@ bool GameController::phaseChange(int row, bool forceUpdate) for (int i = 0; i <= row; i++) { loggerDebug("%s\n", mlist.at(i).toStdString().c_str()); - dummyPosition.command(mlist.at(i).toStdString().c_str()); + dummyGame.command(mlist.at(i).toStdString().c_str()); } // 下面这步关键,会让悔棋者承担时间损失 - dummyPosition.setStartTime(position_.getStartTimeb()); + dummyGame.setStartTime(position_.getStartTimeb()); // 刷新棋局场景 - updateScence(dummyPosition); + updateScence(dummyGame); return true; } diff --git a/src/ui/qt/gamecontroller.h b/src/ui/qt/gamecontroller.h index 77daa2ff..9a8274ee 100644 --- a/src/ui/qt/gamecontroller.h +++ b/src/ui/qt/gamecontroller.h @@ -206,7 +206,7 @@ private: Game position_; // 棋对象的数据模型(临时) - Game dummyPosition; + Game dummyGame; // 2个AI的线程 AiThread *ai[3];