refractor(game): enhance state management with clear and endGame methods

- Added `clear` methods to `PlayerState`, `ServerPlayerState`, and `HandCard`.
- Introduced `endGame` methods to `GameState`, `ClientGameState`, and `ServerGameState`.
- Improved `init` and `nextPlayer` logic in `ClientGameState`.
- Added `getClientGameStage` and `getServerGameStage` methods to retrieve game stages.
This commit is contained in:
Kieran Kihn
2025-12-07 19:03:13 +08:00
parent ebb49a02ef
commit 0802d989f8
4 changed files with 134 additions and 25 deletions

View File

@@ -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<Card> &ClientGameState::getCards() const
{
return this->player_.getCards();
}
void ClientGameState::init(DiscardPile discardPile)
void ClientGameState::init(const std::vector<ClientPlayerState> &players,
const DiscardPile &discardPile,
const std::multiset<Card> &handCard,
const size_t &currentPlayerIndex,
const size_t &selfIndex)
{
this->discardPile_ = std::move(discardPile);
this->players_ = players;
this->discardPile_ = discardPile;
player_.draw(std::vector<Card>(handCard.begin(), handCard.end()));
this->currentPlayer_ = this->players_.begin() + static_cast<int>(currentPlayerIndex);
this->self_ = this->players_.begin() + static_cast<int>(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<Card> ServerGameState::updateStateByDraw()
@@ -151,18 +194,16 @@ namespace UNO::GAME {
return cards;
}
void ServerGameState::reset()
ServerGameStage ServerGameState::getServerGameStage() const
{
discardPile_.clear();
isReversed_ = false;
drawCount_ = 0;
for (auto &player : players_) {
while (!player.isEmpty()) {
player.play(*player.getCards().begin());
}
return this->serverGameStage_;
}
currentPlayer_ = players_.begin();
void ServerGameState::endGame()
{
this->serverGameStage_ = ServerGameStage::PRE_GAME;
deck_.clear();
GameState::endGame();
}
} // namespace UNO::GAME

View File

@@ -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<Card> virtual updateStateByDraw();
void virtual endGame();
};
template<PlayerStateTypeConcept PlayerStateType>
@@ -300,9 +309,26 @@ namespace UNO::GAME {
return {};
}
template<PlayerStateTypeConcept PlayerStateType>
void GameState<PlayerStateType>::endGame()
{
discardPile_.clear();
for (auto &player : this->players_) {
player.clear();
}
}
enum class ClientGameStage { PENDING_CONNECTION, PRE_GAME, ACTIVE, IDLE };
class ClientGameState final : public GameState<ClientPlayerState> {
private:
Player player_;
std::vector<ClientPlayerState>::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<ClientPlayerState> &players,
const DiscardPile &discardPile,
const std::multiset<Card> &handCard,
const size_t &currentPlayerIndex,
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<ServerPlayerState> {
private:
Deck deck_;
ServerGameStage serverGameStage_;
public:
ServerGameState();
@@ -360,9 +404,15 @@ namespace UNO::GAME {
std::vector<Card> updateStateByDraw() override;
/**
* 重置游戏状态(用于重新开始)
* 获取游戏阶段
* @return 游戏阶段
*/
void reset();
[[nodiscard]] ServerGameStage getServerGameStage() const;
/**
* 结束当前局
*/
void endGame() override;
};
} // namespace UNO::GAME

View File

@@ -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

View File

@@ -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