From 21809d5ddaece581de95048cd1983cf0ae37f238 Mon Sep 17 00:00:00 2001 From: CalciteM Team Date: Sat, 31 Aug 2019 12:27:45 +0800 Subject: [PATCH] refactor ninechess.cpp etc --- NineChess/src/aithread.cpp | 7 +- NineChess/src/gamecontroller.cpp | 88 ++++++------ NineChess/src/gamecontroller.h | 6 +- NineChess/src/ninechess.cpp | 239 ++++++++++++++++--------------- NineChess/src/ninechess.h | 12 +- 5 files changed, 179 insertions(+), 173 deletions(-) diff --git a/NineChess/src/aithread.cpp b/NineChess/src/aithread.cpp index a0c749de..d7d3d812 100644 --- a/NineChess/src/aithread.cpp +++ b/NineChess/src/aithread.cpp @@ -108,12 +108,7 @@ void AiThread::run() while (!isInterruptionRequested()) { mutex.lock(); - if (chess_->whosTurn() == NineChess::PLAYER1) - i = 1; - else if (chess_->whosTurn() == NineChess::PLAYER2) - i = 2; - else - i = 0; + i = NineChess::playerToId(chess_->whosTurn()); if (i != id || waiting_) { pauseCondition.wait(&mutex); diff --git a/NineChess/src/gamecontroller.cpp b/NineChess/src/gamecontroller.cpp index b0409c4e..92381862 100644 --- a/NineChess/src/gamecontroller.cpp +++ b/NineChess/src/gamecontroller.cpp @@ -45,8 +45,8 @@ GameController::GameController(GameScene & scene, QObject * parent) : currentRow(-1), isEditing(false), isInverted(false), - isEngine1(false), - isEngine2(false), + isAiPlayer1(false), + isAiPlayer2(false), hasAnimation(true), durationTime(500), hasSound(true), @@ -146,8 +146,8 @@ void GameController::gameReset() // 停掉线程 ai1.stop(); ai2.stop(); - isEngine1 = false; - isEngine2 = false; + isAiPlayer1 = false; + isAiPlayer2 = false; // 清除棋子 qDeleteAll(pieceList); @@ -278,7 +278,7 @@ void GameController::setRule(int ruleNo, NineChess::step_t stepLimited /*= -1*/, void GameController::setEngine1(bool arg) { - isEngine1 = arg; + isAiPlayer1 = arg; if (arg) { ai1.setAi(chess_); if (ai1.isRunning()) @@ -292,7 +292,7 @@ void GameController::setEngine1(bool arg) void GameController::setEngine2(bool arg) { - isEngine2 = arg; + isAiPlayer2 = arg; if (arg) { ai2.setAi(chess_); if (ai2.isRunning()) @@ -306,11 +306,11 @@ void GameController::setEngine2(bool arg) void GameController::setAiDepthTime(NineChessAi_ab::depth_t depth1, int time1, NineChessAi_ab::depth_t depth2, int time2) { - if (isEngine1) { + if (isAiPlayer1) { ai1.stop(); ai1.wait(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.stop(); ai2.wait(); } @@ -318,10 +318,10 @@ void GameController::setAiDepthTime(NineChessAi_ab::depth_t depth1, int time1, N ai1.setAi(chess_, depth1, time1); ai2.setAi(chess_, depth2, time2); - if (isEngine1) { + if (isAiPlayer1) { ai1.start(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.start(); } } @@ -364,11 +364,11 @@ void GameController::playSound(const QString &soundPath) // 上下翻转 void GameController::flip() { - if (isEngine1) { + if (isAiPlayer1) { ai1.stop(); ai1.wait(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.stop(); ai2.wait(); } @@ -392,11 +392,11 @@ void GameController::flip() ai1.setAi(chess_); ai2.setAi(chess_); - if (isEngine1) { + if (isAiPlayer1) { ai1.start(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.start(); } } @@ -404,11 +404,11 @@ void GameController::flip() // 左右镜像 void GameController::mirror() { - if (isEngine1) { + if (isAiPlayer1) { ai1.stop(); ai1.wait(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.stop(); ai2.wait(); } @@ -434,11 +434,11 @@ void GameController::mirror() ai1.setAi(chess_); ai2.setAi(chess_); - if (isEngine1) { + if (isAiPlayer1) { ai1.start(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.start(); } } @@ -446,11 +446,11 @@ void GameController::mirror() // 视图须时针旋转90° void GameController::turnRight() { - if (isEngine1) { + if (isAiPlayer1) { ai1.stop(); ai1.wait(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.stop(); ai2.wait(); } @@ -474,11 +474,11 @@ void GameController::turnRight() ai1.setAi(chess_); ai2.setAi(chess_); - if (isEngine1) { + if (isAiPlayer1) { ai1.start(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.start(); } } @@ -486,11 +486,11 @@ void GameController::turnRight() // 视图逆时针旋转90° void GameController::turnLeft() { - if (isEngine1) { + if (isAiPlayer1) { ai1.stop(); ai1.wait(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.stop(); ai2.wait(); } @@ -509,10 +509,10 @@ void GameController::turnLeft() ai1.setAi(chess_); ai2.setAi(chess_); - if (isEngine1) { + if (isAiPlayer1) { ai1.start(); } - if (isEngine2) { + if (isAiPlayer2) { ai2.start(); } } @@ -584,6 +584,12 @@ void GameController::timerEvent(QTimerEvent *event) #endif } +bool GameController::isAIsTurn() +{ + return ((chess_.whosTurn() == NineChess::PLAYER1 && isAiPlayer1) || + (chess_.whosTurn() == NineChess::PLAYER2 && isAiPlayer2)); +} + // 关键槽函数,根据QGraphicsScene的信号和状态来执行选子、落子或去子 bool GameController::actionPiece(QPointF pos) { @@ -594,11 +600,9 @@ bool GameController::actionPiece(QPointF pos) } // 电脑走棋时,点击无效 - if (chess_.whosTurn() == NineChess::PLAYER1 && isEngine1) - return false; - - if (chess_.whosTurn() == NineChess::PLAYER2 && isEngine2) + if (isAIsTurn()) { return false; + } // 在浏览历史记录时点击棋盘,则认为是悔棋 if (currentRow != manualListModel.rowCount() - 1) { @@ -722,15 +726,15 @@ bool GameController::actionPiece(QPointF pos) // 如果还未决出胜负 if (chess_.whoWin() == NineChess::NOBODY) { if (chess_.whosTurn() == NineChess::PLAYER1) { - if (isEngine1) { + if (isAiPlayer1) { ai1.resume(); } - if (isEngine2) + if (isAiPlayer2) ai2.pause(); } else { - if (isEngine1) + if (isAiPlayer1) ai1.pause(); - if (isEngine2) { + if (isAiPlayer2) { ai2.resume(); } } @@ -790,10 +794,10 @@ bool GameController::command(const QString &cmd, bool update /* = true */) Q_UNUSED(hasSound) // 防止接收滞后结束的线程发送的指令 - if (sender() == &ai1 && !isEngine1) + if (sender() == &ai1 && !isAiPlayer1) return false; - if (sender() == &ai2 && !isEngine2) + if (sender() == &ai2 && !isAiPlayer2) return false; // 声音 @@ -867,15 +871,15 @@ bool GameController::command(const QString &cmd, bool update /* = true */) // 如果还未决出胜负 if (chess_.whoWin() == NineChess::NOBODY) { if (chess_.whosTurn() == NineChess::PLAYER1) { - if (isEngine1) { + if (isAiPlayer1) { ai1.resume(); } - if (isEngine2) + if (isAiPlayer2) ai2.pause(); } else { - if (isEngine1) + if (isAiPlayer1) ai1.pause(); - if (isEngine2) { + if (isAiPlayer2) { ai2.resume(); } } @@ -894,11 +898,11 @@ bool GameController::command(const QString &cmd, bool update /* = true */) } // 网络: 将着法放到服务器的发送列表中 - if (isEngine1) + if (isAiPlayer1) { ai1.getServer()->setAction(cmd); qDebug() << "isEngine1: AI(1) set Action: " << cmd; - } else if (isEngine2) { + } else if (isAiPlayer2) { ai1.getServer()->setAction(cmd); // 注意: 同样是AI1 qDebug() << "isEngine2: AI(1) set Action: " << cmd; } diff --git a/NineChess/src/gamecontroller.h b/NineChess/src/gamecontroller.h index fc3e9710..3aa87cb7 100644 --- a/NineChess/src/gamecontroller.h +++ b/NineChess/src/gamecontroller.h @@ -157,6 +157,8 @@ public slots: // 视图逆时针旋转90° void turnLeft(); + bool isAIsTurn(); + // 根据QGraphicsScene的信号和状态来执行选子、落子或去子 bool actionPiece(QPointF p); @@ -213,10 +215,10 @@ private: bool isInverted; // 是否电脑执先手 - bool isEngine1; + bool isAiPlayer1; // 是否电脑执后手 - bool isEngine2; + bool isAiPlayer2; // 是否有落子动画 bool hasAnimation; diff --git a/NineChess/src/ninechess.cpp b/NineChess/src/ninechess.cpp index 889ac14a..373060fe 100644 --- a/NineChess/src/ninechess.cpp +++ b/NineChess/src/ninechess.cpp @@ -152,6 +152,8 @@ NineChess::NineChess() score_1 = score_2 = score_draw = 0; } +NineChess::~NineChess() = default; + NineChess::NineChess(const NineChess &chess) { *this = chess; @@ -177,11 +179,19 @@ NineChess &NineChess::operator = (const NineChess &chess) memcpy(cmdline, chess.cmdline, sizeof(cmdline)); cmdlist = chess.cmdlist; tips = chess.tips; + return *this; } +int NineChess::playerToId(enum Player player) +{ + if (player == NineChess::PLAYER1) + return 1; + else if (player == NineChess::PLAYER2) + return 2; -NineChess::~NineChess() = default; + return 0; +} NineChess::Player NineChess::getOpponent(NineChess::Player player) { @@ -323,121 +333,106 @@ bool NineChess::setContext(const struct Rule *rule, step_t maxStepsLedToDraw, in this->currentRule.maxTimeLedToLose = maxTimeLedToLose; // 设置棋局数据 - { - // 设置步数 - this->currentStep = initialStep; - this->moveStep = initialStep; - // 局面阶段标识 - if (flags & GAME_NOTSTARTED) { - context.stage = GAME_NOTSTARTED; - } - else if (flags & GAME_PLACING) { - context.stage = GAME_PLACING; - } - else if (flags & GAME_MOVING) { - context.stage = GAME_MOVING; - //context.hash ^= // TODO - } - else if (flags & GAME_OVER) { - context.stage = GAME_OVER; - } - else { - return false; - } + // 设置步数 + this->currentStep = initialStep; + this->moveStep = initialStep; - // 轮流状态标识 - if (flags & PLAYER1) { -// if (context.turn == PLAYER2) { -// context.hash ^= player2sTurnHash; -// } - context.turn = PLAYER1; - } - else if (flags & PLAYER2) { -// if (context.turn == PLAYER1) { -// context.hash ^= player2sTurnHash; -// } - context.turn = PLAYER2; - } - else { - return false; - } + // 局面阶段标识 + if (flags & GAME_NOTSTARTED) { + context.stage = GAME_NOTSTARTED; + } else if (flags & GAME_PLACING) { + context.stage = GAME_PLACING; + } else if (flags & GAME_MOVING) { + context.stage = GAME_MOVING; + } else if (flags & GAME_OVER) { + context.stage = GAME_OVER; + } else { + return false; + } - // 动作状态标识 - if (flags & ACTION_CHOOSE) - context.action = ACTION_CHOOSE; - else if (flags & ACTION_PLACE) - context.action = ACTION_PLACE; - else if (flags & ACTION_CAPTURE) - context.action = ACTION_CAPTURE; - else - return false; + // 轮流状态标识 + if (flags & PLAYER1) { + context.turn = PLAYER1; + } else if (flags & PLAYER2) { + context.turn = PLAYER2; + } else { + return false; + } - // 当前棋局(3×8) - if (board == nullptr) { - memset(context.board, 0, sizeof(context.board)); + // 动作状态标识 + if (flags & ACTION_CHOOSE) { + context.action = ACTION_CHOOSE; + } else if (flags & ACTION_PLACE) { + context.action = ACTION_PLACE; + } else if (flags & ACTION_CAPTURE) { + context.action = ACTION_CAPTURE; + } else { + return false; + } + + // 当前棋局(3×8) + if (board == nullptr) { + memset(context.board, 0, sizeof(context.board)); #if ((defined HASH_MAP_ENABLE) || (defined BOOK_LEARNING) || (defined THREEFOLD_REPETITION)) - context.hash = 0; + context.hash = 0; #endif - } else { - memcpy(context.board, board, sizeof(context.board)); - } + } else { + memcpy(context.board, board, sizeof(context.board)); + } - // 计算盘面子数 - // 棋局,抽象为一个(5×8)的数组,上下两行留空 - /* - 0x00 代表无棋子 - 0x0F 代表禁点 - 0x11~0x1C 代表先手第 1~12 子 - 0x21~0x2C 代表后手第 1~12 子 - 判断棋子是先手的用 (board[i] & 0x10) - 判断棋子是后手的用 (board[i] & 0x20) - */ - context.nPiecesOnBoard_1 = context.nPiecesOnBoard_2 = 0; - for (int r = 1; r < N_RINGS + 2; r++) { - for (int s = 0; s < N_SEATS; s++) { - int pos = r * N_SEATS + s; - if (context.board[pos] & '\x10') { - context.nPiecesOnBoard_1++; - } - else if (context.board[pos] & '\x20') { - context.nPiecesOnBoard_2++; - } - else if (context.board[pos] & '\x0F') { - // 不计算盘面子数 - } + // 计算盘面子数 + // 棋局,抽象为一个(5×8)的数组,上下两行留空 + /* + 0x00 代表无棋子 + 0x0F 代表禁点 + 0x11~0x1C 代表先手第 1~12 子 + 0x21~0x2C 代表后手第 1~12 子 + 判断棋子是先手的用 (board[i] & 0x10) + 判断棋子是后手的用 (board[i] & 0x20) + */ + context.nPiecesOnBoard_1 = context.nPiecesOnBoard_2 = 0; - //updateHash(pos); + for (int r = 1; r < N_RINGS + 2; r++) { + for (int s = 0; s < N_SEATS; s++) { + int pos = r * N_SEATS + s; + if (context.board[pos] & 0x10) { + context.nPiecesOnBoard_1++; + } else if (context.board[pos] & 0x20) { + context.nPiecesOnBoard_2++; + } else if (context.board[pos] & 0x0F) { + // 不计算盘面子数 } } - - // 设置玩家盘面剩余子数和未放置子数 - if (context.nPiecesOnBoard_1 > rule->nTotalPiecesEachSide || - context.nPiecesOnBoard_2 > rule->nTotalPiecesEachSide) { - return false; - } - - if (nPiecesInHand_1 < 0 || nPiecesInHand_2 < 0) { - return false; - } - - context.nPiecesInHand_1 = rule->nTotalPiecesEachSide - context.nPiecesOnBoard_1; - context.nPiecesInHand_2 = rule->nTotalPiecesEachSide - context.nPiecesOnBoard_2; - context.nPiecesInHand_1 = std::min(nPiecesInHand_1, context.nPiecesInHand_1); - context.nPiecesInHand_2 = std::min(nPiecesInHand_2, context.nPiecesInHand_2); - - // 设置去子状态时的剩余尚待去除子数 - if (flags & ACTION_CAPTURE) { - if (0 <= nPiecesNeedRemove && nPiecesNeedRemove < 3) - context.nPiecesNeedRemove = nPiecesNeedRemove; - } else { - context.nPiecesNeedRemove = 0; - } - - // 清空成三记录 - context.millList.clear(); } + // 设置玩家盘面剩余子数和未放置子数 + if (context.nPiecesOnBoard_1 > rule->nTotalPiecesEachSide || + context.nPiecesOnBoard_2 > rule->nTotalPiecesEachSide) { + return false; + } + + if (nPiecesInHand_1 < 0 || nPiecesInHand_2 < 0) { + return false; + } + + context.nPiecesInHand_1 = rule->nTotalPiecesEachSide - context.nPiecesOnBoard_1; + context.nPiecesInHand_2 = rule->nTotalPiecesEachSide - context.nPiecesOnBoard_2; + context.nPiecesInHand_1 = std::min(nPiecesInHand_1, context.nPiecesInHand_1); + context.nPiecesInHand_2 = std::min(nPiecesInHand_2, context.nPiecesInHand_2); + + // 设置去子状态时的剩余尚待去除子数 + if (flags & ACTION_CAPTURE) { + if (0 <= nPiecesNeedRemove && nPiecesNeedRemove < 3) { + context.nPiecesNeedRemove = nPiecesNeedRemove; + } + } else { + context.nPiecesNeedRemove = 0; + } + + // 清空成三记录 + context.millList.clear(); + // 胜负标识 winner = NOBODY; @@ -480,7 +475,7 @@ void NineChess::getContext(struct Rule &rule, step_t &step, int &flags, rule = this->currentRule; step = this->currentStep; flags = context.stage | context.turn | context.action; - this->board_ = board; + board_ = board; nPiecesInHand_1 = context.nPiecesInHand_1; nPiecesInHand_2 = context.nPiecesInHand_2; nPiecesNeedRemove = context.nPiecesNeedRemove; @@ -488,8 +483,10 @@ void NineChess::getContext(struct Rule &rule, step_t &step, int &flags, bool NineChess::reset() { - if (context.stage == GAME_NOTSTARTED && elapsedSeconds_1 == elapsedSeconds_2 == 0) + if (context.stage == GAME_NOTSTARTED && + elapsedSeconds_1 == elapsedSeconds_2 == 0) { return true; + } // 步数归零 currentStep = 0; @@ -546,7 +543,8 @@ bool NineChess::reset() break; } - if (sprintf(cmdline, "r%1u s%03u t%02u", i + 1, currentRule.maxStepsLedToDraw, currentRule.maxTimeLedToLose) > 0) { + if (sprintf(cmdline, "r%1u s%03u t%02u", + i + 1, currentRule.maxStepsLedToDraw, currentRule.maxTimeLedToLose) > 0) { cmdlist.emplace_back(string(cmdline)); return true; } @@ -579,16 +577,18 @@ bool NineChess::start() } } +// Unused bool NineChess::getPieceCP(const Player &player, const int &number, int &c, int &p) { int piece; - if (player == PLAYER1) + if (player == PLAYER1) { piece = 0x10; - else if (player == PLAYER2) + } else if (player == PLAYER2) { piece = 0x20; - else + } else { return false; + } if (number > 0 && number <= currentRule.nTotalPiecesEachSide) piece &= number; @@ -611,14 +611,17 @@ bool NineChess::getCurrentPiece(Player &player, int &number) if (!onBoard[currentPos]) return false; - if (board_[currentPos] & 0x10) { + int p = board_[currentPos]; + + if (p & 0x10) { player = PLAYER1; - number = board_[currentPos] - 0x10; - } else if (board_[currentPos] & 0x20) { + number = p - 0x10; + } else if (p & 0x20) { player = PLAYER2; - number = board_[currentPos] - 0x20; - } else + number = p - 0x20; + } else { return false; + } return true; } @@ -1427,12 +1430,12 @@ bool NineChess::isAllInMills(char ch) bool NineChess::isAllInMills(enum Player player) { - char ch = '\x00'; + char ch = 0x00; if (player == PLAYER1) - ch = '\x10'; + ch = 0x10; else if (player == PLAYER2) - ch = '\x20'; + ch = 0x20; else return true; diff --git a/NineChess/src/ninechess.h b/NineChess/src/ninechess.h index 296d4fae..29c2e0e1 100644 --- a/NineChess/src/ninechess.h +++ b/NineChess/src/ninechess.h @@ -166,14 +166,16 @@ public: } // 玩家标识, 轮流状态, 胜负标识 - enum Player : uint16_t + enum Player : uint8_t { - PLAYER1 = 0x0010, // 玩家1 - PLAYER2 = 0x0020, // 玩家2 - DRAW = 0x0040, // 双方和棋 - NOBODY = 0x0080 // 胜负未分 + PLAYER1 = 0x10, // 玩家1 + PLAYER2 = 0x20, // 玩家2 + DRAW = 0x40, // 双方和棋 + NOBODY = 0x80 // 胜负未分 }; + static int playerToId(enum Player player); + static Player getOpponent(enum Player player); // 动作状态标识