diff --git a/src/game/GameState.cpp b/src/game/GameState.cpp index 38e5146..82b3ea6 100644 --- a/src/game/GameState.cpp +++ b/src/game/GameState.cpp @@ -46,6 +46,11 @@ namespace UNO::GAME { return card; } + void PlayerState::clear() + { + this->remainingCardCount_ = 0; + } + ClientPlayerState::ClientPlayerState(std::string name, size_t remainingCardCount, bool isUno) : PlayerState(std::move(name), remainingCardCount, isUno) { @@ -84,16 +89,48 @@ namespace UNO::GAME { return this->handCard_.isEmpty(); } - ClientGameState::ClientGameState(std::string name) : player_(std::move(name)) {} + void ServerPlayerState::clear() + { + PlayerState::clear(); + this->handCard_.clear(); + } + + ClientGameState::ClientGameState(std::string name) : player_(std::move(name)), clientGameStage_(ClientGameStage::PENDING_CONNECTION) {} + + void ClientGameState::nextPlayer() + { + GameState::nextPlayer(); + if (this->self_ == this->currentPlayer_) { + this->clientGameStage_ = ClientGameStage::ACTIVE; + } + else { + this->clientGameStage_ = ClientGameStage::IDLE; + } + } + const std::multiset &ClientGameState::getCards() const { return this->player_.getCards(); } - void ClientGameState::init(DiscardPile discardPile) + void ClientGameState::init(const std::vector &players, + const DiscardPile &discardPile, + const std::multiset &handCard, + const size_t ¤tPlayerIndex, + const size_t &selfIndex) { - this->discardPile_ = std::move(discardPile); + this->players_ = players; + this->discardPile_ = discardPile; + player_.draw(std::vector(handCard.begin(), handCard.end())); + this->currentPlayer_ = this->players_.begin() + static_cast(currentPlayerIndex); + this->self_ = this->players_.begin() + static_cast(selfIndex); + if (this->self_ == this->currentPlayer_) { + this->clientGameStage_ = ClientGameStage::ACTIVE; + } + else { + this->clientGameStage_ = ClientGameStage::IDLE; + } } @@ -117,26 +154,32 @@ namespace UNO::GAME { return this->player_.isEmpty(); } - ServerGameState::ServerGameState() = default; + ClientGameStage ClientGameState::getClientGameStage() const + { + return this->clientGameStage_; + } + + void ClientGameState::endGame() + { + this->clientGameStage_ = ClientGameStage::PRE_GAME; + this->player_.clear(); + } + + ServerGameState::ServerGameState() : serverGameStage_(ServerGameStage::PRE_GAME) {} void ServerGameState::init() { - deck_.clear(), discardPile_.clear(); while (discardPile_.isEmpty() || discardPile_.getFront().getType() > CardType::NUM9) { discardPile_.add(deck_.draw()); } - for (auto &player : this->players_) { - while (player.isEmpty() == false) { - player.play(*player.getCards().begin()); - } - } - for (size_t i = 0; i < 7; i++) { for (auto &player : this->players_) { player.draw(1, this->deck_.draw(1)); } } + + this->serverGameStage_ = ServerGameStage::IN_GAME; } std::vector ServerGameState::updateStateByDraw() @@ -151,18 +194,16 @@ namespace UNO::GAME { return cards; } - void ServerGameState::reset() + ServerGameStage ServerGameState::getServerGameStage() const { - discardPile_.clear(); - isReversed_ = false; - drawCount_ = 0; + return this->serverGameStage_; + } - for (auto &player : players_) { - while (!player.isEmpty()) { - player.play(*player.getCards().begin()); - } - } + void ServerGameState::endGame() + { + this->serverGameStage_ = ServerGameStage::PRE_GAME; + deck_.clear(); - currentPlayer_ = players_.begin(); + GameState::endGame(); } } // namespace UNO::GAME \ No newline at end of file diff --git a/src/game/GameState.h b/src/game/GameState.h index a333d9b..f87cde7 100644 --- a/src/game/GameState.h +++ b/src/game/GameState.h @@ -60,6 +60,11 @@ namespace UNO::GAME { * 出一张牌 */ Card virtual play(const Card &card); + + /** + * 清空手牌 + */ + void virtual clear(); }; /** @@ -112,6 +117,8 @@ namespace UNO::GAME { * @return 手牌是否为空 */ [[nodiscard]] bool isEmpty() const; + + void clear() override; }; /** @@ -142,7 +149,7 @@ namespace UNO::GAME { /** * 下一个玩家 */ - void nextPlayer(); + void virtual nextPlayer(); public: virtual ~GameState() = default; @@ -189,6 +196,8 @@ namespace UNO::GAME { * 由于用户摸牌而改变状态 */ std::vector virtual updateStateByDraw(); + + void virtual endGame(); }; template @@ -300,9 +309,26 @@ namespace UNO::GAME { return {}; } + template + void GameState::endGame() + { + discardPile_.clear(); + for (auto &player : this->players_) { + player.clear(); + } + } + + + enum class ClientGameStage { PENDING_CONNECTION, PRE_GAME, ACTIVE, IDLE }; + class ClientGameState final : public GameState { private: Player player_; + std::vector::const_iterator self_; + ClientGameStage clientGameStage_; + + private: + void nextPlayer() override; public: explicit ClientGameState(std::string name); @@ -316,7 +342,11 @@ namespace UNO::GAME { /** * 初始化客户端状态 */ - void init(DiscardPile discardPile); + void init(const std::vector &players, + const DiscardPile &discardPile, + const std::multiset &handCard, + const size_t ¤tPlayerIndex, + const size_t &selfIndex); /** * 摸一张牌 @@ -340,11 +370,25 @@ namespace UNO::GAME { * @return 手牌是否为空 */ [[nodiscard]] bool isEmpty() const; + + /** + * 获取游戏阶段 + * @return 游戏阶段 + */ + [[nodiscard]] ClientGameStage getClientGameStage() const; + + /** + * 结束当前局 + */ + void endGame() override; }; + enum class ServerGameStage { PRE_GAME, IN_GAME }; + class ServerGameState final : public GameState { private: Deck deck_; + ServerGameStage serverGameStage_; public: ServerGameState(); @@ -360,9 +404,15 @@ namespace UNO::GAME { std::vector updateStateByDraw() override; /** - * 重置游戏状态(用于重新开始) + * 获取游戏阶段 + * @return 游戏阶段 */ - void reset(); + [[nodiscard]] ServerGameStage getServerGameStage() const; + + /** + * 结束当前局 + */ + void endGame() override; }; } // namespace UNO::GAME diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 321127f..08125bd 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -54,6 +54,11 @@ namespace UNO::GAME { return cards_.empty(); } + void HandCard::clear() + { + this->cards_.clear(); + } + Player::Player(std::string name) : name_(std::move(name)) {} const std::string &Player::getName() const @@ -86,5 +91,8 @@ namespace UNO::GAME { return this->handCard_.play(card); } + void Player::clear() + { + this->handCard_.clear(); } } // namespace UNO::GAME diff --git a/src/game/Player.h b/src/game/Player.h index ba89daf..55160a4 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -59,6 +59,11 @@ namespace UNO::GAME { * @return 手牌是否为空 */ [[nodiscard]] bool isEmpty() const; + + /** + * 清空手牌 + */ + void clear(); }; /** @@ -105,6 +110,11 @@ namespace UNO::GAME { * @return 手牌是否为空 */ [[nodiscard]] bool isEmpty() const; + + /** + * 清空手牌 + */ + void clear(); }; } // namespace UNO::GAME