mirror of
https://github.com/kierankihn/uno-game.git
synced 2025-12-27 02:13:18 +08:00
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:
@@ -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 ¤tPlayerIndex,
|
||||
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;
|
||||
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
|
||||
@@ -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 ¤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<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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user