feat(server): add game reset and end game handling

- Introduced `reset` method in `ServerGameState` to allow game state reinitialization.
- Added `handleEndGame` in `UnoServer` to detect and process game conclusion.
This commit is contained in:
Kieran Kihn
2025-12-04 13:28:36 +08:00
parent 535e62c852
commit 766e9f9a21
4 changed files with 55 additions and 0 deletions

View File

@@ -157,4 +157,19 @@ namespace UNO::GAME {
this->nextPlayer(); this->nextPlayer();
return cards; return cards;
} }
void ServerGameState::reset()
{
discardPile_.clear();
isReversed_ = false;
drawCount_ = 0;
for (auto &player : players_) {
while (!player.isEmpty()) {
player.play(*player.getCards().begin());
}
}
currentPlayer_ = players_.begin();
}
} // namespace UNO::GAME } // namespace UNO::GAME

View File

@@ -359,6 +359,11 @@ namespace UNO::GAME {
* 由于用户摸牌而改变状态 * 由于用户摸牌而改变状态
*/ */
std::vector<Card> updateStateByDraw() override; std::vector<Card> updateStateByDraw() override;
/**
* 重置游戏状态(用于重新开始)
*/
void reset();
}; };
} // namespace UNO::GAME } // namespace UNO::GAME

View File

@@ -90,11 +90,41 @@ namespace UNO::SERVER {
void UnoServer::handlePlayCard(size_t playerId, GAME::Card card) void UnoServer::handlePlayCard(size_t playerId, GAME::Card card)
{ {
this->serverGameState_.updateStateByCard(card); this->serverGameState_.updateStateByCard(card);
// 检查是否有玩家获胜(手牌为空)
bool gameEnded = false;
for (const auto &player : this->serverGameState_.getPlayers()) {
if (player.isEmpty()) {
gameEnded = true;
break;
}
}
NETWORK::PlayCardPayload payload = {card}; NETWORK::PlayCardPayload payload = {card};
auto message = NETWORK::MessageSerializer::serialize({NETWORK::MessageStatus::OK, NETWORK::MessagePayloadType::PLAY_CARD, payload}); auto message = NETWORK::MessageSerializer::serialize({NETWORK::MessageStatus::OK, NETWORK::MessagePayloadType::PLAY_CARD, payload});
for (size_t i = 0; i < playerCount; i++) { for (size_t i = 0; i < playerCount; i++) {
this->networkServer_.send(gameIdToNetworkId.at(i), message); this->networkServer_.send(gameIdToNetworkId.at(i), message);
} }
if (gameEnded) {
this->handleEndGame();
}
}
void UnoServer::handleEndGame()
{
NETWORK::EndGamePayload payload{};
auto message = NETWORK::MessageSerializer::serialize({NETWORK::MessageStatus::OK, NETWORK::MessagePayloadType::END_GAME, payload});
for (size_t i = 0; i < playerCount; i++) {
this->networkServer_.send(gameIdToNetworkId.at(i), message);
}
this->serverGameState_.reset();
for (size_t i = 0; i < playerCount; i++) {
this->isReadyToStart[i] = false;
}
} }
void UnoServer::run() void UnoServer::run()

View File

@@ -46,6 +46,11 @@ namespace UNO::SERVER {
*/ */
void handlePlayCard(size_t playerId, GAME::Card card); void handlePlayCard(size_t playerId, GAME::Card card);
/**
* 处理游戏结束事件
*/
void handleEndGame();
public: public:
explicit UnoServer(uint16_t port = 10001); explicit UnoServer(uint16_t port = 10001);