diff --git a/gamewindow.qrc b/gamewindow.qrc index 818b5fd1..44382f4c 100644 --- a/gamewindow.qrc +++ b/gamewindow.qrc @@ -56,7 +56,7 @@ resources/icon/ic_visibility_black_48dp.png - resources/sound/choose.wav + resources/sound/Select.wav resources/sound/drog.wav resources/sound/forbidden.wav resources/sound/loss.wav @@ -66,8 +66,8 @@ resources/sound/warning.wav resources/sound/BlockMill_B.wav resources/sound/BlockMill_W.wav - resources/sound/Capture_B.wav - resources/sound/Capture_W.wav + resources/sound/Remove_B.wav + resources/sound/Remove_W.wav resources/sound/Draw.wav resources/sound/GameStart.wav resources/sound/Mill_B.wav diff --git a/include/config.h b/include/config.h index 7e3436a7..863b7a99 100644 --- a/include/config.h +++ b/include/config.h @@ -140,7 +140,7 @@ //#define DONOT_PLAY_WIN_SOUND // 摆棋阶段在叉下面显示被吃的子 -//#define GAME_PLACING_SHOW_CAPTURED_PIECES +//#define GAME_PLACING_SHOW_REMOVED_PIECES // 启动时窗口最大化 //#define SHOW_MAXIMIZED_ON_LOAD diff --git a/millgame.vcxproj.filters b/millgame.vcxproj.filters index eb821035..899f2824 100644 --- a/millgame.vcxproj.filters +++ b/millgame.vcxproj.filters @@ -455,7 +455,7 @@ - + Resource Files @@ -485,10 +485,10 @@ Resource Files - + Resource Files - + Resource Files diff --git a/resources/sound/Capture_B.wav b/resources/sound/Remove_B.wav similarity index 100% rename from resources/sound/Capture_B.wav rename to resources/sound/Remove_B.wav diff --git a/resources/sound/Capture_W.wav b/resources/sound/Remove_W.wav similarity index 100% rename from resources/sound/Capture_W.wav rename to resources/sound/Remove_W.wav diff --git a/resources/sound/choose.wav b/resources/sound/Select.wav similarity index 100% rename from resources/sound/choose.wav rename to resources/sound/Select.wav diff --git a/src/ai/evaluate.cpp b/src/ai/evaluate.cpp index e50a11c1..b9808421 100644 --- a/src/ai/evaluate.cpp +++ b/src/ai/evaluate.cpp @@ -44,12 +44,12 @@ value_t Evaluation::getValue(Position *position) switch (position->action) { // 选子和落子使用相同的评价方法 - case ACTION_CHOOSE: + case ACTION_SELECT: case ACTION_PLACE: break; // 如果形成去子状态,每有一个可去的子,算100分 - case ACTION_CAPTURE: + case ACTION_REMOVE: nPiecesNeedRemove = (position->sideToMove == PLAYER_BLACK) ? position->nPiecesNeedRemove : -(position->nPiecesNeedRemove); value += nPiecesNeedRemove * VALUE_EACH_PIECE_PLACING_NEEDREMOVE; @@ -72,12 +72,12 @@ value_t Evaluation::getValue(Position *position) switch (position->action) { // 选子和落子使用相同的评价方法 - case ACTION_CHOOSE: + case ACTION_SELECT: case ACTION_PLACE: break; // 如果形成去子状态,每有一个可去的子,算128分 - case ACTION_CAPTURE: + case ACTION_REMOVE: nPiecesNeedRemove = (position->sideToMove == PLAYER_BLACK) ? position->nPiecesNeedRemove : -(position->nPiecesNeedRemove); value += nPiecesNeedRemove * VALUE_EACH_PIECE_MOVING_NEEDREMOVE; @@ -101,7 +101,7 @@ value_t Evaluation::getValue(Position *position) } // 走棋阶段被闷判断 - else if (position->action == ACTION_CHOOSE && + else if (position->action == ACTION_SELECT && position->board.isAllSurrounded(position->sideId, position->nPiecesOnBoard, position->sideToMove) && rule.isLoseWhenNoWay) { // 规则要求被“闷”判负,则对手获胜 diff --git a/src/ai/movegen.cpp b/src/ai/movegen.cpp index 079e8317..490d1108 100644 --- a/src/ai/movegen.cpp +++ b/src/ai/movegen.cpp @@ -308,7 +308,7 @@ ExtMove *generate(/* TODO: const */ Position *position, ExtMove *moveList) // 列出所有合法的下一招 switch (position->action) { // 对于选子和落子动作 - case ACTION_CHOOSE: + case ACTION_SELECT: case ACTION_PLACE: // 对于摆子阶段 if (position->phase & (PHASE_PLACING | PHASE_READY)) { @@ -348,7 +348,7 @@ ExtMove *generate(/* TODO: const */ Position *position, ExtMove *moveList) for (int i = Board::MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) { oldSquare = static_cast(MoveList::movePriorityTable[i]); - if (!position->choose(oldSquare)) { + if (!position->selectPiece(oldSquare)) { continue; } @@ -377,7 +377,7 @@ ExtMove *generate(/* TODO: const */ Position *position, ExtMove *moveList) break; // 对于吃子动作 - case ACTION_CAPTURE: + case ACTION_REMOVE: opponent = Player::getOpponent(position->sideToMove); if (position->board.isAllInMills(opponent)) { diff --git a/src/ai/movepick.cpp b/src/ai/movepick.cpp index 3713de91..9ebfa3fc 100644 --- a/src/ai/movepick.cpp +++ b/src/ai/movepick.cpp @@ -60,7 +60,7 @@ void MovePicker::score() #ifdef SORT_MOVE_WITH_HUMAN_KNOWLEDGES // TODO: rule.allowRemoveMultiPieces Լ ֮ - if (type_of(m) != MOVETYPE_CAPTURE) { + if (type_of(m) != MOVETYPE_REMOVE) { // κν׶, ӵǷʹñ if (nMills > 0) { #ifdef ALPHABETA_AI @@ -108,7 +108,7 @@ void MovePicker::score() cur->rating += RATING_STAR_SQUARE; } #endif - } else { // Capture + } else { // Remove int nPlayerPiece = 0; int nOpponentPiece = 0; int nForbidden = 0; @@ -120,7 +120,7 @@ void MovePicker::score() #ifdef ALPHABETA_AI if (nMills > 0) { // ӵ㴦ҷ - //newNode->rating += static_cast(RATING_CAPTURE_ONE_MILL * nMills); + //newNode->rating += static_cast(RATING_REMOVE_ONE_MILL * nMills); if (nOpponentPiece == 0) { // ӵԱûжԷȿ @@ -203,7 +203,7 @@ void MovePicker::clearHistoryScore() { #ifndef HOSTORY_HEURISTIC_ACTION_MOVE_ONLY memset(placeHistory, 0, sizeof(placeHistory)); - memset(captureHistory, 0, sizeof(captureHistory)); + memset(removeHistory, 0, sizeof(removeHistory)); #endif memset(moveHistory, 0, sizeof(moveHistory)); } diff --git a/src/ai/movepick.h b/src/ai/movepick.h index 2e5a554e..1893d6e8 100644 --- a/src/ai/movepick.h +++ b/src/ai/movepick.h @@ -46,7 +46,7 @@ public: #ifdef HOSTORY_HEURISTIC // TODO: Fix size score_t placeHistory[64]; - score_t captureHistory[64]; + score_t removeHistory[64]; score_t moveHistory[10240]; score_t getHistoryScore(move_t move); diff --git a/src/ai/search.cpp b/src/ai/search.cpp index 4721af90..fddce676 100644 --- a/src/ai/search.cpp +++ b/src/ai/search.cpp @@ -619,7 +619,7 @@ const char* AIAlgorithm::nextMove() return moveToCommand(bestMove); #if 0 - char charChoose = '*'; + char charSelect = '*'; Board::printBoard(); @@ -629,9 +629,9 @@ const char* AIAlgorithm::nextMove() int cs = root->childrenSize; for (int i = 0; i < cs; i++) { if (root->children[i]->move != bestMove) { - charChoose = ' '; + charSelect = ' '; } else { - charChoose = '*'; + charSelect = '*'; foundBest = true; } @@ -645,7 +645,7 @@ const char* AIAlgorithm::nextMove() #else 0, #endif - charChoose); + charSelect); moveIndex++; } @@ -698,13 +698,15 @@ const char* AIAlgorithm::nextMove() const char *AIAlgorithm::moveToCommand(move_t move) { - int rto, sto; + ring_t rto; + seat_t sto; Board::squareToPolar(to_sq(move), rto, sto); if (move < 0) { sprintf(cmdline, "-(%1u,%1u)", rto, sto); } else if (move & 0x7f00) { - int rfrom, sfrom; + ring_t rfrom; + seat_t sfrom; Board::squareToPolar(from_sq(move), rfrom, sfrom); sprintf(cmdline, "(%1u,%1u)->(%1u,%1u)", rfrom, sfrom, rto, sto); } else { diff --git a/src/game/board.cpp b/src/game/board.cpp index 09650bf7..4905aedd 100644 --- a/src/game/board.cpp +++ b/src/game/board.cpp @@ -184,15 +184,15 @@ void Board::createMillTable() #endif /* DEBUG_MODE */ } -void Board::squareToPolar(const square_t square, int &r, int &s) +void Board::squareToPolar(const square_t square, ring_t &r, seat_t &s) { //r = square / N_SEATS; //s = square % N_SEATS + 1; - r = square >> 3; - s = (square & 0x07) + 1; + r = ring_t(square >> 3); + s = seat_t((square & 0x07) + 1); } -square_t Board::polarToSquare(int r, int s) +square_t Board::polarToSquare(ring_t r, seat_t s) { assert(!(r < 1 || r > N_RINGS || s < 1 || s > N_SEATS)); @@ -204,7 +204,7 @@ player_t Board::locationToPlayer(square_t square) return player_t(locations[square] & 0x30); } -int Board::inHowManyMills(square_t square, player_t player, square_t squareChoose) +int Board::inHowManyMills(square_t square, player_t player, square_t squareSelected) { int n = 0; location_t locbak = SQ_0; @@ -213,9 +213,9 @@ int Board::inHowManyMills(square_t square, player_t player, square_t squareChoos player = locationToPlayer(square); } - if (squareChoose != SQ_0) { - locbak = locations[squareChoose]; - locations[squareChoose] = 0; + if (squareSelected != SQ_0) { + locbak = locations[squareSelected]; + locations[squareSelected] = 0; } for (int l = 0; l < LINE_TYPES_COUNT; l++) { @@ -226,8 +226,8 @@ int Board::inHowManyMills(square_t square, player_t player, square_t squareChoos } } - if (squareChoose != SQ_0) { - locations[squareChoose] = locbak; + if (squareSelected != SQ_0) { + locations[squareSelected] = locbak; } return n; diff --git a/src/game/board.h b/src/game/board.h index 10a8a874..dcfc288b 100644 --- a/src/game/board.h +++ b/src/game/board.h @@ -69,7 +69,7 @@ public: void rotate(int degrees, vector &cmdlist, char *cmdline, int32_t move_, square_t square, bool cmdChange = true); // 判断棋盘 square 处的棋子处于几个“三连”中 - int inHowManyMills(square_t square, player_t player, square_t squareChoose = SQ_0); + int inHowManyMills(square_t square, player_t player, square_t squareSelected = SQ_0); // 判断玩家的所有棋子是否都处于“三连”状态 bool isAllInMills(player_t); @@ -87,10 +87,10 @@ public: int addMills(square_t square); // 将棋盘下标形式转化为第r圈,第s位,r和s下标都从1开始 - static void squareToPolar(square_t square, int &r, int &s); + static void squareToPolar(square_t square, ring_t &r, seat_t &s); // 将第c圈,第p位转化为棋盘下标形式,r和s下标都从1开始 - static square_t polarToSquare(int r, int s); + static square_t polarToSquare(ring_t r, seat_t s); static void printBoard(); diff --git a/src/game/position.cpp b/src/game/position.cpp index dd035ae2..e79a6d2d 100644 --- a/src/game/position.cpp +++ b/src/game/position.cpp @@ -225,7 +225,7 @@ bool Position::setPosition(const struct Rule *newRule, countPiecesInHand(); // 设置去子状态时的剩余尚待去除子数 - if (action == ACTION_CAPTURE) { + if (action == ACTION_REMOVE) { if (0 <= piecesNeedRemove && piecesNeedRemove < 3) { nPiecesNeedRemove = piecesNeedRemove; } @@ -372,7 +372,7 @@ bool Position::start() } } -bool Position::place(square_t square, int8_t updateCmdlist) +bool Position::placePiece(square_t square, bool updateCmdlist) { // 如果局面为“结局”,返回false if (phase == PHASE_GAMEOVER) @@ -391,8 +391,8 @@ bool Position::place(square_t square, int8_t updateCmdlist) return false; // 格式转换 - int r = 0; - int s = 0; + ring_t r; + seat_t s; Board::squareToPolar(square, r, s); // 时间的临时变量 @@ -441,7 +441,7 @@ bool Position::place(square_t square, int8_t updateCmdlist) phase = PHASE_MOVING; // 进入选子状态 - action = ACTION_CHOOSE; + action = ACTION_SELECT; // 清除禁点 cleanForbiddenLocations(); @@ -470,7 +470,7 @@ bool Position::place(square_t square, int8_t updateCmdlist) nPiecesNeedRemove = rule.allowRemoveMultiPieces ? n : 1; // 进入去子状态 - action = ACTION_CAPTURE; + action = ACTION_REMOVE; } goto out; @@ -523,7 +523,7 @@ bool Position::place(square_t square, int8_t updateCmdlist) // 中局阶段未成三 if (n == 0) { // 进入选子状态 - action = ACTION_CHOOSE; + action = ACTION_SELECT; // 设置轮到谁走 changeSideToMove(); @@ -539,7 +539,7 @@ bool Position::place(square_t square, int8_t updateCmdlist) nPiecesNeedRemove = rule.allowRemoveMultiPieces ? n : 1; // 进入去子状态 - action = ACTION_CAPTURE; + action = ACTION_REMOVE; } out: @@ -550,30 +550,30 @@ out: return true; } -bool Position::_place(int r, int s) +bool Position::_placePiece(ring_t r, seat_t s) { // 转换为 square square_t square = Board::polarToSquare(r, s); - return place(square, true); + return placePiece(square, true); } -bool Position::_capture(int r, int s) +bool Position::_removePiece(ring_t r, seat_t s) { // 转换为 square square_t square = Board::polarToSquare(r, s); - return capture(square, 1); + return removePiece(square, 1); } -bool Position::capture(square_t square, int8_t updateCmdlist) +bool Position::removePiece(square_t square, bool updateCmdlist) { // 如果局面为"未开局"或“结局”,返回false if (phase & PHASE_NOTPLAYING) return false; // 如非“去子”状态,返回false - if (action != ACTION_CAPTURE) + if (action != ACTION_REMOVE) return false; // 如果去子完成,返回false @@ -581,8 +581,8 @@ bool Position::capture(square_t square, int8_t updateCmdlist) return false; // 格式转换 - int r = 0; - int s = 0; + ring_t r; + seat_t s; Board::squareToPolar(square, r, s); // 时间的临时变量 @@ -649,7 +649,7 @@ bool Position::capture(square_t square, int8_t updateCmdlist) phase = PHASE_MOVING; // 进入选子状态 - action = ACTION_CHOOSE; + action = ACTION_SELECT; // 清除禁点 cleanForbiddenLocations(); @@ -683,7 +683,7 @@ bool Position::capture(square_t square, int8_t updateCmdlist) // 中局阶段 else { // 进入选子状态 - action = ACTION_CHOOSE; + action = ACTION_SELECT; // 设置轮到谁走 changeSideToMove(); @@ -702,14 +702,14 @@ out: return true; } -bool Position::choose(square_t square) +bool Position::selectPiece(square_t square) { // 如果局面不是"中局”,返回false if (phase != PHASE_MOVING) return false; // 如非“选子”或“落子”状态,返回false - if (action != ACTION_CHOOSE && action != ACTION_PLACE) + if (action != ACTION_SELECT && action != ACTION_PLACE) return false; // 判断选子是否可选 @@ -726,9 +726,9 @@ bool Position::choose(square_t square) return false; } -bool Position::choose(int r, int s) +bool Position::selectPiece(ring_t r, seat_t s) { - return choose(Board::polarToSquare(r, s)); + return selectPiece(Board::polarToSquare(r, s)); } bool Position::giveup(player_t loser) @@ -760,7 +760,8 @@ bool Position::command(const char *cmd) int r; unsigned t; step_t s; - int r1, s1, r2, s2; + ring_t r1, r2; + seat_t s1, s2; int args = 0; int mm = 0, ss = 0; @@ -782,8 +783,8 @@ bool Position::command(const char *cmd) tm = mm * 60 + ss; } - if (choose(r1, s1)) { - return _place(r2, s2); + if (selectPiece(r1, s1)) { + return _placePiece(r2, s2); } return false; @@ -796,7 +797,7 @@ bool Position::command(const char *cmd) if (mm >= 0 && ss >= 0) tm = mm * 60 + ss; } - return _capture(r1, s1); + return _removePiece(r1, s1); } // 落子 @@ -806,7 +807,7 @@ bool Position::command(const char *cmd) if (mm >= 0 && ss >= 0) tm = mm * 60 + ss; } - return _place(r1, s1); + return _placePiece(r1, s1); } // 认输 @@ -840,14 +841,14 @@ bool Position::doMove(move_t m) movetype_t mt = type_of(m); switch (mt) { - case MOVETYPE_CAPTURE: - return capture(static_cast(-m)); + case MOVETYPE_REMOVE: + return removePiece(static_cast(-m)); case MOVETYPE_MOVE: - if (choose(from_sq(m))) { - return place(to_sq(m)); + if (selectPiece(from_sq(m))) { + return placePiece(to_sq(m)); } case MOVETYPE_PLACE: - return place(to_sq(m)); + return placePiece(to_sq(m)); default: break; } @@ -995,7 +996,7 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist) } // 如果中局被“闷” - if (phase == PHASE_MOVING && action == ACTION_CHOOSE && board.isAllSurrounded(sideId, nPiecesOnBoard, sideToMove)) { + if (phase == PHASE_MOVING && action == ACTION_SELECT && board.isAllSurrounded(sideId, nPiecesOnBoard, sideToMove)) { // 规则要求被“闷”判负,则对手获胜 // TODO: 应该转移到下面的分支中 phase = PHASE_GAMEOVER; @@ -1116,15 +1117,15 @@ void Position::setTips() case PHASE_PLACING: if (action == ACTION_PLACE) { tips = "轮到玩家" + turnStr + "落子,剩余" + std::to_string(nPiecesInHand[sideId]) + "子"; - } else if (action == ACTION_CAPTURE) { + } else if (action == ACTION_REMOVE) { tips = "成三!轮到玩家" + turnStr + "去子,需去" + std::to_string(nPiecesNeedRemove) + "子"; } break; case PHASE_MOVING: - if (action == ACTION_PLACE || action == ACTION_CHOOSE) { + if (action == ACTION_PLACE || action == ACTION_SELECT) { tips = "轮到玩家" + turnStr + "选子移动"; - } else if (action == ACTION_CAPTURE) { + } else if (action == ACTION_REMOVE) { tips = "成三!轮到玩家" + turnStr + "去子,需去" + std::to_string(nPiecesNeedRemove) + "子"; } break; @@ -1204,7 +1205,7 @@ hash_t Position::updateHashMisc() hi |= 1U; } - if (action == ACTION_CAPTURE) { + if (action == ACTION_REMOVE) { hi |= 1U << 1; } @@ -1222,7 +1223,7 @@ hash_t Position::getNextMainHash(move_t m) square_t sq = static_cast(to_sq(m));; movetype_t mt = type_of(m); - if (mt == MOVETYPE_CAPTURE) { + if (mt == MOVETYPE_REMOVE) { int pieceType = Player::getOpponentById(Player::toId(sideToMove)); nextMainHash ^= zobrist[sq][pieceType]; diff --git a/src/game/position.h b/src/game/position.h index f2f8b5ea..0c82a0a3 100644 --- a/src/game/position.h +++ b/src/game/position.h @@ -191,15 +191,6 @@ public: // 游戏开始 bool start(); - // 选子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始 - bool choose(int r, int s); - - // 落子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始 - bool _place(int r, int s); - - // 去子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始 - bool _capture(int r, int s); - // 认输 bool giveup(player_t loser); @@ -236,11 +227,20 @@ public: // 判断胜负 player_t getWinner() const; + // 选子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始 + bool selectPiece(ring_t r, seat_t s); + + // 落子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始 + bool _placePiece(ring_t r, seat_t s); + + // 去子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始 + bool _removePiece(ring_t r, seat_t s); + // 下面几个函数没有算法无关判断和无关操作,节约算法时间 bool doMove(move_t move); - bool choose(square_t square); - bool place(square_t square, int8_t cp = 0); - bool capture(square_t square, int8_t cp = 0); + bool selectPiece(square_t square); + bool placePiece(square_t square, bool updateCmdlist = false); + bool removePiece(square_t square, bool updateCmdlist = false); // hash 相关 hash_t getPosKey(); diff --git a/src/game/types.h b/src/game/types.h index cd4e9882..89e2247d 100644 --- a/src/game/types.h +++ b/src/game/types.h @@ -45,7 +45,7 @@ enum movetype_t { MOVETYPE_PLACE, MOVETYPE_MOVE, - MOVETYPE_CAPTURE + MOVETYPE_REMOVE }; constexpr int MAX_MOVES = 40; @@ -177,13 +177,13 @@ enum rating_t : int8_t RATING_BLOCK_THREE_MILLS = RATING_BLOCK_ONE_MILL * 3, RATING_THREE_MILLS = RATING_ONE_MILL * 3, - RATING_CAPTURE_ONE_MILL = RATING_ONE_MILL, - RATING_CAPTURE_TWO_MILLS = RATING_TWO_MILLS, - RATING_CAPTURE_THREE_MILLS = RATING_THREE_MILLS, + RATING_REMOVE_ONE_MILL = RATING_ONE_MILL, + RATING_REMOVE_TWO_MILLS = RATING_TWO_MILLS, + RATING_REMOVE_THREE_MILLS = RATING_THREE_MILLS, - RATING_CAPTURE_OPPONENT_ONE_MILL = -RATING_CAPTURE_ONE_MILL, - RATING_CAPTURE_OPPONENT_TWO_MILLS = -RATING_CAPTURE_TWO_MILLS, - RATING_CAPTURE_OPPONENT_THREE_MILLS = -RATING_CAPTURE_THREE_MILLS, + RATING_REMOVE_OPPONENT_ONE_MILL = -RATING_REMOVE_ONE_MILL, + RATING_REMOVE_OPPONENT_TWO_MILLS = -RATING_REMOVE_TWO_MILLS, + RATING_REMOVE_OPPONENT_THREE_MILLS = -RATING_REMOVE_THREE_MILLS, RATING_TT = 100, RATING_MAX = std::numeric_limits::max(), @@ -243,9 +243,9 @@ enum piece_t enum action_t : uint16_t { ACTION_NONE = 0x0000, - ACTION_CHOOSE = 0x0100, // 选子 + ACTION_SELECT = 0x0100, // 选子 ACTION_PLACE = 0x0200, // 落子 - ACTION_CAPTURE = 0x0400 // 提子 + ACTION_REMOVE = 0x0400 // 提子 }; #define ENABLE_BASE_OPERATORS_ON(T) \ @@ -339,7 +339,7 @@ inline const square_t to_sq(move_t m) inline const movetype_t type_of(move_t m) { if (m < 0) { - return MOVETYPE_CAPTURE; + return MOVETYPE_REMOVE; } else if (m & 0x1f00) { return MOVETYPE_MOVE; } diff --git a/src/ui/qt/boarditem.cpp b/src/ui/qt/boarditem.cpp index f1999ccb..675a66a1 100644 --- a/src/ui/qt/boarditem.cpp +++ b/src/ui/qt/boarditem.cpp @@ -20,6 +20,7 @@ #include "boarditem.h" #include "graphicsconst.h" #include +#include "types.h" BoardItem::BoardItem(QGraphicsItem *parent) : size(BOARD_SIZE) @@ -169,19 +170,19 @@ QPointF BoardItem::nearestPosition(QPointF const pos) return nearestPos; } -QPointF BoardItem::rs2pos(int r, int s) +QPointF BoardItem::rs2pos(ring_t r, seat_t s) { - return position[(r - 1) * N_SEATS + s - 1]; // TODO: 为什么是 r - 1 和算法部分不一样? + return position[((int)r - 1) * N_SEATS + (int)s - 1]; // TODO: 为什么是 r - 1 和算法部分不一样? } -bool BoardItem::pos2rs(QPointF pos, int &r, int &s) +bool BoardItem::pos2rs(QPointF pos, ring_t &r, seat_t &s) { // 寻找最近的落子点 for (int i = 0; i < N_RINGS * N_SEATS; i++) { // 如果pos点在落子点附近 if (QLineF(pos, position[i]).length() < PIECE_SIZE / 6) { - r = i / N_SEATS + 1; - s = i % N_SEATS + 1; + r = ring_t(i / N_SEATS + 1); + s = seat_t(i % N_SEATS + 1); return true; } } diff --git a/src/ui/qt/boarditem.h b/src/ui/qt/boarditem.h index 4a0bf028..10959dde 100644 --- a/src/ui/qt/boarditem.h +++ b/src/ui/qt/boarditem.h @@ -23,6 +23,7 @@ #include #include "config.h" +#include "types.h" class BoardItem : public QGraphicsItem { @@ -56,10 +57,10 @@ public: QPointF nearestPosition(QPointF pos); // 将模型的圈、位转化为落子点坐标 - QPointF rs2pos(int r, int s); + QPointF rs2pos(ring_t r, seat_t s); // 将落子点坐标转化为模型用的圈、位 - bool pos2rs(QPointF pos, int &r, int &s); + bool pos2rs(QPointF pos, ring_t &r, seat_t &s); // 3圈,禁止修改! static const uint8_t N_RINGS = 3; diff --git a/src/ui/qt/gamecontroller.cpp b/src/ui/qt/gamecontroller.cpp index 3227ef1f..08da2c78 100644 --- a/src/ui/qt/gamecontroller.cpp +++ b/src/ui/qt/gamecontroller.cpp @@ -408,11 +408,11 @@ void GameController::playSound(sound_t soundType, player_t player) case GAME_SOUND_BLOCK_MILL: filename = "BlockMill_" + sideStr + ".wav"; break; - case GAME_SOUND_CAPTURE: - filename = "Capture_" + oppenentStr + ".wav"; + case GAME_SOUND_REMOVE: + filename = "Remove_" + oppenentStr + ".wav"; break; - case GAME_SOUND_CHOOSE: - filename = "choose.wav"; + case GAME_SOUND_SELECT: + filename = "Select.wav"; break; case GAME_SOUND_DRAW: filename = "Draw.wav"; @@ -450,9 +450,6 @@ void GameController::playSound(sound_t soundType, player_t player) case GAME_SOUND_OBVIOUS: filename = "Obvious.wav"; break; - case GAME_SOUND_REMOVE: - filename = "remove.wav"; - break; case GAME_SOUND_REPEAT_THREE_DRAW: filename = "RepeatThreeDraw.wav"; break; @@ -738,7 +735,9 @@ bool GameController::actionPiece(QPointF pos) { #ifndef TRAINING_MODE // 点击非落子点,不执行 - int r, s; + ring_t r; + seat_t s; + if (!scene.pos2rs(pos, r, s)) { return false; } @@ -795,8 +794,8 @@ bool GameController::actionPiece(QPointF pos) switch (state.position->getAction()) { case ACTION_PLACE: - if (state.position->_place(r, s)) { - if (state.position->getAction() == ACTION_CAPTURE) { + if (state.position->_placePiece(r, s)) { + if (state.position->getAction() == ACTION_REMOVE) { // 播放成三音效 playSound(GAME_SOUND_MILL, state.position->getSideToMove()); } else { @@ -810,13 +809,13 @@ bool GameController::actionPiece(QPointF pos) // 如果移子不成功,尝试重新选子,这里不break [[fallthrough]]; - case ACTION_CHOOSE: + case ACTION_SELECT: piece = qgraphicsitem_cast(item); if (!piece) break; - if (state.position->choose(r, s)) { + if (state.position->selectPiece(r, s)) { // 播放选子音效 - playSound(GAME_SOUND_CHOOSE, state.position->getSideToMove()); + playSound(GAME_SOUND_SELECT, state.position->getSideToMove()); result = true; } else { // 播放禁止音效 @@ -824,10 +823,10 @@ bool GameController::actionPiece(QPointF pos) } break; - case ACTION_CAPTURE: - if (state.position->_capture(r, s)) { + case ACTION_REMOVE: + if (state.position->_removePiece(r, s)) { // 播放音效 - playSound(GAME_SOUND_CAPTURE, state.position->getSideToMove()); + playSound(GAME_SOUND_REMOVE, state.position->getSideToMove()); result = true; } else { // 播放禁止音效 @@ -935,12 +934,12 @@ bool GameController::command(const QString &cmd, bool update /* = true */) sound_t soundType = GAME_SOUND_NONE; switch (state.position->getAction()) { - case ACTION_CHOOSE: + case ACTION_SELECT: case ACTION_PLACE: soundType = GAME_SOUND_DROG; break; - case ACTION_CAPTURE: - soundType = GAME_SOUND_CAPTURE; + case ACTION_REMOVE: + soundType = GAME_SOUND_REMOVE; break; default: break; @@ -956,7 +955,7 @@ bool GameController::command(const QString &cmd, bool update /* = true */) return false; #ifndef TRAINING_MODE - if (soundType == GAME_SOUND_DROG && state.position->getAction() == ACTION_CAPTURE) { + if (soundType == GAME_SOUND_DROG && state.position->getAction() == ACTION_REMOVE) { soundType = GAME_SOUND_MILL; } @@ -1167,7 +1166,7 @@ bool GameController::updateScence(StateInfo &g) // 遍历棋盘,查找并放置棋盘上的棋子 for (j = SQ_BEGIN; j < SQ_END; j++) { if (board[j] == key) { - pos = scene.rs2pos(j / Board::N_SEATS, j % Board::N_SEATS + 1); + pos = scene.rs2pos(ring_t(j / Board::N_SEATS), seat_t(j % Board::N_SEATS + 1)); if (piece->pos() != pos) { // 让移动的棋子位于顶层 @@ -1203,7 +1202,7 @@ bool GameController::updateScence(StateInfo &g) // 为了对最近移除的棋子置为选择状态作准备 deletedPiece = piece; -#ifdef GAME_PLACING_SHOW_CAPTURED_PIECES +#ifdef GAME_PLACING_SHOW_REMOVED_PIECES if (state.position->getPhase() == PHASE_MOVING) { #endif QPropertyAnimation *animation = new QPropertyAnimation(piece, "pos"); @@ -1212,7 +1211,7 @@ bool GameController::updateScence(StateInfo &g) animation->setEndValue(pos); animation->setEasingCurve(QEasingCurve::InOutQuad); animationGroup->addAnimation(animation); -#ifdef GAME_PLACING_SHOW_CAPTURED_PIECES +#ifdef GAME_PLACING_SHOW_REMOVED_PIECES } #endif } @@ -1225,7 +1224,7 @@ bool GameController::updateScence(StateInfo &g) if (rule.hasForbiddenLocations && g.position->getPhase() == PHASE_PLACING) { for (int j = SQ_BEGIN; j < SQ_END; j++) { if (board[j] == PIECE_FORBIDDEN) { - pos = scene.rs2pos(j / Board::N_SEATS, j % Board::N_SEATS + 1); + pos = scene.rs2pos(ring_t(j / Board::N_SEATS), seat_t(j % Board::N_SEATS + 1)); if (nTotalPieces < static_cast(pieceList.size())) { pieceList.at(static_cast(nTotalPieces++))->setPos(pos); } else { diff --git a/src/ui/qt/gamecontroller.h b/src/ui/qt/gamecontroller.h index 9b4c6134..5771dd3e 100644 --- a/src/ui/qt/gamecontroller.h +++ b/src/ui/qt/gamecontroller.h @@ -50,8 +50,8 @@ enum sound_t { GAME_SOUND_NONE, GAME_SOUND_BLOCK_MILL, - GAME_SOUND_CAPTURE, - GAME_SOUND_CHOOSE, + GAME_SOUND_REMOVE, + GAME_SOUND_SELECT, GAME_SOUND_DRAW, GAME_SOUND_DROG, GAME_SOUND_FORBIDDEN, @@ -64,7 +64,6 @@ enum sound_t GAME_SOUND_NEW_GAME, GAME_SOUND_NEXT_MILL, GAME_SOUND_OBVIOUS, - GAME_SOUND_REMOVE, GAME_SOUND_REPEAT_THREE_DRAW, GAME_SOUND_SIDE, GAME_SOUND_STAR, diff --git a/src/ui/qt/gamescene.cpp b/src/ui/qt/gamescene.cpp index e3af2f27..7eac5259 100644 --- a/src/ui/qt/gamescene.cpp +++ b/src/ui/qt/gamescene.cpp @@ -26,6 +26,7 @@ #include "pieceitem.h" #include "boarditem.h" #include "graphicsconst.h" +#include "types.h" GameScene::GameScene(QObject *parent) : QGraphicsScene(parent), @@ -112,12 +113,12 @@ void GameScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) //QGraphicsScene::mouseReleaseEvent(mouseEvent); } -QPointF GameScene::rs2pos(int r, int s) +QPointF GameScene::rs2pos(ring_t r, seat_t s) { return board->rs2pos(r, s); } -bool GameScene::pos2rs(QPointF pos, int &r, int &s) +bool GameScene::pos2rs(QPointF pos, ring_t &r, seat_t &s) { return board->pos2rs(pos, r, s); } diff --git a/src/ui/qt/gamescene.h b/src/ui/qt/gamescene.h index 7051f341..90203367 100644 --- a/src/ui/qt/gamescene.h +++ b/src/ui/qt/gamescene.h @@ -23,6 +23,7 @@ #include #include "config.h" +#include "types.h" class BoardItem; @@ -34,10 +35,10 @@ public: ~GameScene() override; // 将模型的圈、位转化为落子点坐标 - QPointF rs2pos(int r, int s); + QPointF rs2pos(ring_t r, seat_t s); // 将落子点坐标转化为模型用的圈、位 - bool pos2rs(QPointF pos, int &r, int &s); + bool pos2rs(QPointF pos, ring_t &r, seat_t &s); // 设置棋盘斜线 void setDiagonal(bool arg = true); diff --git a/src/ui/qt/pieceitem.cpp b/src/ui/qt/pieceitem.cpp index 9f61a289..7e80b4e2 100644 --- a/src/ui/qt/pieceitem.cpp +++ b/src/ui/qt/pieceitem.cpp @@ -53,16 +53,16 @@ PieceItem::PieceItem(QGraphicsItem *parent) : size = PIECE_SIZE; // 选中子标识线宽度 - chooseLineWeight = LINE_WEIGHT; + selectLineWeight = LINE_WEIGHT; // 删除线宽度 removeLineWeight = LINE_WEIGHT * 5; // 选中线为黄色 #ifdef MOBILE_APP_UI - chooseLineColor = Qt::gray; + selectLineColor = Qt::gray; #else - chooseLineColor = Qt::darkYellow; + selectLineColor = Qt::darkYellow; #endif /* MOBILE_APP_UI */ // 删除线颜色 @@ -145,9 +145,9 @@ void PieceItem::paint(QPainter *painter, // 如果模型为选中状态,则画上四个小直角 if (isSelected()) { - QPen pen(chooseLineColor, chooseLineWeight, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin); + QPen pen(selectLineColor, selectLineWeight, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin); painter->setPen(pen); - int xy = (size - chooseLineWeight) / 2; + int xy = (size - selectLineWeight) / 2; painter->drawLine(-xy, -xy, -xy, -xy / 2); painter->drawLine(-xy, -xy, -xy / 2, -xy); diff --git a/src/ui/qt/pieceitem.h b/src/ui/qt/pieceitem.h index c4dafd41..516bdce8 100644 --- a/src/ui/qt/pieceitem.h +++ b/src/ui/qt/pieceitem.h @@ -127,13 +127,13 @@ private: bool showNum {false}; // 选中子标识线宽度 - int chooseLineWeight; + int selectLineWeight; // 删除线宽度 int removeLineWeight; // 选中线颜色 - QColor chooseLineColor; + QColor selectLineColor; // 删除线颜色 QColor removeLineColor;