diff --git a/src/core/Board.cpp b/src/core/Board.cpp index deaee71..98387e0 100644 --- a/src/core/Board.cpp +++ b/src/core/Board.cpp @@ -122,6 +122,10 @@ std::unordered_set Board::getAllPlayerComponent(PlayerID ID) const { return PlayerComponentIDs; } +std::unordered_map Board::getALLPiecetoComponent() const { + return m_component->getAllPiecetoComponent(); +} + int Board::getComponentID(int row, int col) const{ int pieceID = getPieceID(row, col); int componentID = m_component->getComponentID(pieceID); diff --git a/src/core/Board.h b/src/core/Board.h index 84e8aee..0a51356 100644 --- a/src/core/Board.h +++ b/src/core/Board.h @@ -43,6 +43,8 @@ public: void printBoard(); //获取相同玩家棋子的所有棋子块的根节点 std::unordered_set getAllPlayerComponent(PlayerID ID) const; + //获取棋子ID到组件ID的映射 + std::unordered_map getALLPiecetoComponent() const; // 获取坐标对应的块的ID int getComponentID(int row, int col) const; // 获取组件ID对应的组件 diff --git a/src/core/ComponentManager.cpp b/src/core/ComponentManager.cpp index 9e5245b..56a2e45 100644 --- a/src/core/ComponentManager.cpp +++ b/src/core/ComponentManager.cpp @@ -269,6 +269,10 @@ std:: unordered_map> ComponentManager::getAllCompon } +std::unordered_map ComponentManager::getAllPiecetoComponent() const { + return m_pieceToComponent; +} + diff --git a/src/core/ComponentManager.h b/src/core/ComponentManager.h index 941977d..92b38c5 100644 --- a/src/core/ComponentManager.h +++ b/src/core/ComponentManager.h @@ -47,7 +47,7 @@ public: // 连接两个组件 void addConnection(int pieceID1, int pieceID2); // 断开棋子与指定邻居的连接 - bool disconnectFromNeighbor(int pieceID, int neighborID); + //bool disconnectFromNeighbor(int pieceID, int neighborID); // 将棋子完全从当前组件断开,成为独立组件 bool disconnectFromComponent(int pieceID); // 通过棋子选择整个连通片 @@ -66,9 +66,10 @@ public: bool areDirectlyConnected(int pieceID1, int pieceID2) const; // 清除选中状态 void clearSelection(); - + // 不能返回引用因为要保存旧的组件 //获取所有组件 std::unordered_map> getAllComponents() const; - + //获取棋子ID到组件ID的映射 + std::unordered_map getAllPiecetoComponent() const; }; \ No newline at end of file diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 0b1ead1..f1381da 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -24,8 +24,8 @@ bool Game::initialize() { return false; } m_board->printBoard(); - - + resetActionableComponents(); + resetOldPieceIDtoComponent(); @@ -38,15 +38,8 @@ void Game::resetActionableComponents() { m_actionableComponents = m_board->getAllPlayerComponent(m_currentPlayer); } - -bool Game::playerSelectPiece(int row, int col) { - if (Rule::canbeSelect(m_board->getPieceAt(row, col), m_currentPlayer)) { - /*if (m_seletedPiece == std::nullopt) { - m_seletedPiece = {row, col}; - }*/ - m_seletedPiece = {row, col}; - } - return true; +void Game::resetOldPieceIDtoComponent() { + m_oldPieceIDtoComponentID = m_board->getALLPiecetoComponent(); } void Game::setPlayerAction(ActionType type) { @@ -60,7 +53,7 @@ void Game::executeAction(int toRow, int toCol) { if (Rule::canGrow(m_board.get(), fromRow, fromCol, toRow, toCol, m_currentPlayer)) { m_board->placePieceAt(toRow, toCol, m_currentPlayer); // 如果执行了操作就擦除 - markComponentAsUsed(m_board->getComponentID(fromRow, fromCol)); + markComponentAsUsed(getOldComponentID(fromRow, fromCol)); return; } } @@ -70,7 +63,7 @@ void Game::executeAction(int toRow, int toCol) { m_board->removePieceAt(toRow, toCol); m_board->placePieceAt(toRow, toCol, m_currentPlayer); - markComponentAsUsed(m_board->getComponentID(fromRow, fromCol)); + markComponentAsUsed(getOldComponentID(fromRow, fromCol)); return; } } @@ -79,7 +72,7 @@ void Game::executeAction(int toRow, int toCol) { m_board->removePieceAt(fromRow, fromCol); m_board->placePieceAt(toRow, toCol, m_currentPlayer); - markComponentAsUsed(m_board->getComponentID(fromRow, fromCol)); + markComponentAsUsed(getOldComponentID(fromRow, fromCol)); return; } } @@ -87,7 +80,13 @@ void Game::executeAction(int toRow, int toCol) { } void Game::markComponentAsUsed(int componentID) { - m_actionableComponents.erase(componentID); + std::cout << "try erase the componentID is " << componentID <<"\n"; + int num = m_actionableComponents.erase(componentID); + if (num == 1) { + std::cout << "erase successful\n"; + } else { + std::cout << "erase error\n"; + } } PlayerID Game::getCurrentPlayer() const { @@ -97,3 +96,94 @@ PlayerID Game::getCurrentPlayer() const { void Game::printBoard() const { m_board->printBoard(); } + +void Game::nextTurn() { + std::cout << "switch to P2\n"; + m_seletedPiece = std::nullopt; + m_currentPlayer = (m_currentPlayer == PlayerID::P1) ? PlayerID::P2 : PlayerID::P1; + resetOldPieceIDtoComponent(); + resetActionableComponents(); + + m_currentActionType = ActionType::GROW; +} + +bool Game::handleCoordinateInput(int row, int col) { + // 如果当前没有选择棋子就选择棋子 + if (m_seletedPiece == std::nullopt) { + if (!Rule::canbeSelect(m_board->getPieceAt(row, col), m_currentPlayer)) { + std::cout << "sorry you can't select the piece\n"; + return false; + } + m_seletedPiece = {row, col}; + std::cout << "selcte piece successful\n"; + return true; + } + std::cout << "selectedpiece is " << m_seletedPiece->first << " " << m_seletedPiece->second << "\n"; + // 如果点击了选择的棋子就切换行动方式 + std::pair newSelectedPiece = {row, col}; + if (m_seletedPiece == newSelectedPiece) { + switch (m_currentActionType) + { + case ActionType::GROW: + m_currentActionType = ActionType::MOVE; + std::cout << "switch actiontype to MOVE successful\n"; + break; + case ActionType::MOVE: + m_currentActionType = ActionType::SPORE; + std::cout << "switch actiontype to SPORE successful\n"; + break; + case ActionType::SPORE: + m_currentActionType = ActionType::GROW; + std::cout << "switch actiontype to GROW successful\n"; + break; + default: + std::cout << "switch actiontype wrong\n"; + return false; + + } + + return true; + } + //如果点击了属于当前玩家且没有行动的的其它棋子,就切换选择棋子到其它棋子 + int selectComponentID = getOldComponentID(row, col); + if (m_actionableComponents.find(selectComponentID) != m_actionableComponents.end()) { + m_seletedPiece = newSelectedPiece; + std::cout << "switch the selectedpiece to " << m_seletedPiece->first << " " << m_seletedPiece->second << "\n"; + return true; + } + + // 如果点击了已经行动的棋子,则不进行处理,已行动的棋子如果是在一个单独的区域不用处理,但如果是在一个未行动的组件中欧是可以再次行动的, + //但是如果点击同一块 也无需处理,因为 在m_actionableComponents已经不存在了,直接尝试执行行动,但因为rule处理了所以不用管 + + // 其它情况则执行行动 + executeAction(row, col); + + + // 执行完之后检查是否m_actionableComponents为空, + + // m_actionableComponents只保存了ID,但是在执行棋子之后会处理组件的连通性,rule会获取到新的连通性,不过这样更符合逻辑 + + //如果不是空的这默认将m_seletedPiece切换到这个组件之中 + //如果是空的则进行下一轮切换玩家 + if (m_actionableComponents.empty()) { + nextTurn(); + return true; + } else { + for (auto leftcomponentID : m_actionableComponents) { + std::cout << "leftcomponentID is " << leftcomponentID << "\n"; + } + auto leftcomponent = m_actionableComponents.begin(); + m_seletedPiece = m_board->getCoordFromID(*leftcomponent); + std::cout << "switch the selectedpiece to " << m_seletedPiece->first << " " << m_seletedPiece->second << "\n"; + return true; + } + + +} + +int Game::getOldComponentID(int row, int col) { + int pieceID = m_board->getPieceID(row, col); + auto it = m_oldPieceIDtoComponentID.find(pieceID); + //for (auto [pieceID, y] : m_oldPieceIDtoComponentID) + return (it != m_oldPieceIDtoComponentID.end()) ? it->second : -1; +} \ No newline at end of file diff --git a/src/core/Game.h b/src/core/Game.h index 17b8586..357fd62 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -14,10 +14,13 @@ private: std::unique_ptr m_board; PlayerID m_currentPlayer = PlayerID::P1; ActionType m_currentActionType = ActionType::GROW; - std::optional> m_seletedPiece; //表示“可能有值,也可能没有值” + std::optional> m_seletedPiece = std::nullopt; //表示“可能有值,也可能没有值” std::unordered_set m_actionableComponents;; + // 保存旧的componentid与pieceid的对应关系 + std::unordered_map m_oldPieceIDtoComponentID; // 如果操作执行成功就从 void markComponentAsUsed(int componentID); + public: Game(); @@ -26,8 +29,8 @@ public: bool initialize(); //获取当前玩家的拥有的组件 void resetActionableComponents(); - // 获取用户选择的棋子 - bool playerSelectPiece(int row, int col); + //旧的componentid与pieceid的对应关系 + void resetOldPieceIDtoComponent(); // 设置行动类型 void setPlayerAction(ActionType type); // 执行玩家的行动 @@ -36,4 +39,13 @@ public: PlayerID getCurrentPlayer() const; // 打印棋盘 void printBoard() const; + // 下一个轮次 + void nextTurn(); + + // 根据当前状态自动处理坐标输入: + // - 如果尚未选中棋子 → 尝试选中 + // - 如果已选中棋子 → 尝试执行当前动作类型(GROW/MOVE/SPORE) + bool handleCoordinateInput(int row, int col); + + int getOldComponentID(int row, int col); }; \ No newline at end of file diff --git a/src/core/Rule.cpp b/src/core/Rule.cpp index fd92276..e9c3c1b 100644 --- a/src/core/Rule.cpp +++ b/src/core/Rule.cpp @@ -21,7 +21,7 @@ bool Rule::canPlacePiece(const Piece* piecePos) { } bool Rule::canbeSelect(const Piece* PieceID, PlayerID ID) { - if (PieceID->getPieceOwner() != ID) { + if (PieceID == nullptr || PieceID->getPieceOwner() != ID) { return false; } return true; diff --git a/src/core/testcore.cpp b/src/core/testcore.cpp index f386da3..e31a2e1 100644 --- a/src/core/testcore.cpp +++ b/src/core/testcore.cpp @@ -13,19 +13,12 @@ int main() { while (true) { std::cout << "Current player: " << (game.getCurrentPlayer() == PlayerID::P1 ? "P1" : "P2") << "\n"; - std::cout << "Action type (0=GROW, 1=MOVE, 2=SPORE): "; - int act; - std::cin >> act; - game.setPlayerAction(static_cast(act)); + - std::cout << "Select piece (row col): "; + std::cout << "input piece (row col): "; int r, c; std::cin >> r >> c; - game.playerSelectPiece(r, c); - - std::cout << "Target position (row col): "; - std::cin >> r >> c; - game.executeAction(r, c); + game.handleCoordinateInput(r, c); game.printBoard(); }