From e78741bd9d532f7d27089e386df7eb6f695c6f2b Mon Sep 17 00:00:00 2001 From: Kieran Kihn <114803508+kierankihn@users.noreply.github.com> Date: Tue, 18 Nov 2025 17:15:07 +0800 Subject: [PATCH] refactor(game): encapsulate `Player` and `ClientGameState` state management - Replaced public `Player::handCard` pointer with private `HandCard` member. - Introduced `draw`, `play`, and `getCards` methods in `Player` and `ClientGameState`. - Modified `ClientGameState` constructor to accept player name instead of `Player` object. - Updated tests to reflect new `Player` and `ClientGameState` structure. --- src/game/GameState.cpp | 27 ++++++++++++++++++++++- src/game/GameState.h | 37 +++++++++++++++++++++++++++++--- src/game/Player.cpp | 27 ++++++++++++++++++++++- src/game/Player.h | 33 ++++++++++++++++++++++++++-- test/unit/game/GameStateTest.cpp | 6 +----- 5 files changed, 118 insertions(+), 12 deletions(-) diff --git a/src/game/GameState.cpp b/src/game/GameState.cpp index 615f39e..8829746 100644 --- a/src/game/GameState.cpp +++ b/src/game/GameState.cpp @@ -97,7 +97,32 @@ namespace UNO::GAME { return this->handCard_.isEmpty(); } - ClientGameState::ClientGameState(GameStatus gameStatus, Player player) : GameState(gameStatus), player(std::move(player)) {} + ClientGameState::ClientGameState(GameStatus gameStatus, std::string name) : GameState(gameStatus), player_(std::move(name)) {} + + const std::multiset &ClientGameState::getCards() const + { + return this->player_.getCards(); + } + + void ClientGameState::draw(const Card &card) + { + this->player_.draw(card); + } + + void ClientGameState::draw(const std::vector &cards) + { + this->player_.draw(cards); + } + + Card ClientGameState::play(const std::multiset::iterator &it) + { + return this->player_.play(it); + } + + bool ClientGameState::isEmpty() const + { + return this->player_.isEmpty(); + } ServerGameState::ServerGameState() : GameState(GameStatus::WAITING_PLAYERS_TO_JOIN) {} diff --git a/src/game/GameState.h b/src/game/GameState.h index 398b946..3002233 100644 --- a/src/game/GameState.h +++ b/src/game/GameState.h @@ -317,10 +317,41 @@ namespace UNO::GAME { } class ClientGameState final : public GameState { - public: - Player player; + private: + Player player_; - ClientGameState(GameStatus gameStatus, Player player); + public: + ClientGameState(GameStatus gameStatus, std::string name); + + /** + * 获得当前手牌 + * @return 当前手牌的集合 + */ + [[nodiscard]] const std::multiset &getCards() const; + + /** + * 摸一张牌 + * @param card 摸的牌 + */ + void draw(const Card &card); + + /** + * 摸多张牌 + * @param cards 摸的牌 + */ + void draw(const std::vector &cards); + + /** + * 打出一张牌 + * @param it 要打出的手牌的迭代器 + * @return 打出的手牌 + */ + Card play(const std::multiset::iterator &it); + + /** + * @return 手牌是否为空 + */ + [[nodiscard]] bool isEmpty() const; }; class ServerGameState final : public GameState { diff --git a/src/game/Player.cpp b/src/game/Player.cpp index e48c4ad..27eab8d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -40,10 +40,35 @@ namespace UNO::GAME { return cards_.empty(); } - Player::Player(std::string name) : name_(std::move(name)), handCard(nullptr) {} + Player::Player(std::string name) : name_(std::move(name)) {} const std::string &Player::getName() const { return this->name_; } + + const std::multiset &Player::getCards() const + { + return this->handCard_.getCards(); + } + + void Player::draw(const Card &card) + { + this->handCard_.draw(card); + } + + void Player::draw(const std::vector &cards) + { + this->handCard_.draw(cards); + } + + bool Player::isEmpty() const + { + return this->handCard_.isEmpty(); + } + + Card Player::play(const std::multiset::iterator &it) + { + return this->handCard_.play(it); + } } // namespace UNO::GAME diff --git a/src/game/Player.h b/src/game/Player.h index f94fbc4..d1ea3a6 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -62,16 +62,45 @@ namespace UNO::GAME { class Player { private: std::string name_; + HandCard handCard_; public: - HandCard *handCard; - explicit Player(std::string name); /** * @return 返回玩家名字 */ [[nodiscard]] const std::string &getName() const; + + /** + * 获得当前手牌 + * @return 当前手牌的集合 + */ + [[nodiscard]] const std::multiset &getCards() const; + + /** + * 摸一张牌 + * @param card 摸的牌 + */ + void draw(const Card &card); + + /** + * 摸多张牌 + * @param cards 摸的牌 + */ + void draw(const std::vector &cards); + + /** + * 打出一张牌 + * @param it 要打出的手牌的迭代器 + * @return 打出的手牌 + */ + Card play(const std::multiset::iterator &it); + + /** + * @return 手牌是否为空 + */ + [[nodiscard]] bool isEmpty() const; }; } // namespace UNO::GAME diff --git a/test/unit/game/GameStateTest.cpp b/test/unit/game/GameStateTest.cpp index 553ee5f..8fb02d0 100644 --- a/test/unit/game/GameStateTest.cpp +++ b/test/unit/game/GameStateTest.cpp @@ -13,11 +13,7 @@ TEST(game_state_test, game_state_test_1) { - UNO::GAME::HandCard handCard; - UNO::GAME::Player player(std::string("lzh")); - player.handCard = &handCard; - - UNO::GAME::ClientGameState clientGameState(UNO::GAME::GameStatus::WAITING_PLAYERS_TO_NEXT_TURN, player); + UNO::GAME::ClientGameState clientGameState(UNO::GAME::GameStatus::WAITING_PLAYERS_TO_NEXT_TURN, std::string("lzh")); UNO::GAME::ClientPlayerState playerState1("pkq", 100, false); UNO::GAME::ClientPlayerState playerState2("kpq", 100, false);