mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-10 06:14:08 +08:00
Refined the core interfaces of the game
This commit is contained in:
@@ -122,6 +122,10 @@ std::unordered_set<int> Board::getAllPlayerComponent(PlayerID ID) const {
|
||||
return PlayerComponentIDs;
|
||||
}
|
||||
|
||||
std::unordered_map<int, int> 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);
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
void printBoard();
|
||||
//获取相同玩家棋子的所有棋子块的根节点
|
||||
std::unordered_set<int> getAllPlayerComponent(PlayerID ID) const;
|
||||
//获取棋子ID到组件ID的映射
|
||||
std::unordered_map<int, int> getALLPiecetoComponent() const;
|
||||
// 获取坐标对应的块的ID
|
||||
int getComponentID(int row, int col) const;
|
||||
// 获取组件ID对应的组件
|
||||
|
||||
@@ -269,6 +269,10 @@ std:: unordered_map<int, std::unordered_set<int>> ComponentManager::getAllCompon
|
||||
|
||||
}
|
||||
|
||||
std::unordered_map<int, int> ComponentManager::getAllPiecetoComponent() const {
|
||||
return m_pieceToComponent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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<int, std::unordered_set<int>> getAllComponents() const;
|
||||
|
||||
//获取棋子ID到组件ID的映射
|
||||
std::unordered_map<int, int> getAllPiecetoComponent() const;
|
||||
|
||||
};
|
||||
@@ -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<int ,int> 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;
|
||||
}
|
||||
@@ -14,10 +14,13 @@ private:
|
||||
std::unique_ptr<Board> m_board;
|
||||
PlayerID m_currentPlayer = PlayerID::P1;
|
||||
ActionType m_currentActionType = ActionType::GROW;
|
||||
std::optional<std::pair<int, int>> m_seletedPiece; //表示“可能有值,也可能没有值”
|
||||
std::optional<std::pair<int, int>> m_seletedPiece = std::nullopt; //表示“可能有值,也可能没有值”
|
||||
std::unordered_set<int> m_actionableComponents;;
|
||||
// 保存旧的componentid与pieceid的对应关系
|
||||
std::unordered_map<int, int> 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);
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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<ActionType>(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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user