mirror of
https://github.com/kierankihn/uno-game.git
synced 2025-12-27 02:13:18 +08:00
feat(network): add PlayerPublicState to InitGamePayload
- Introduced `PlayerPublicState` structure to represent player state. - Updated `InitGamePayload` to include `PlayerPublicState` for all players. - Enhanced `MessageSerializer` to handle serialization and deserialization of `PlayerPublicState`.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace UNO::NETWORK {
|
||||
@@ -29,12 +30,19 @@ namespace UNO::NETWORK {
|
||||
std::vector<GAME::Card> cards;
|
||||
};
|
||||
|
||||
struct PlayerPublicState {
|
||||
std::string name;
|
||||
size_t remainingCardCount;
|
||||
bool isUno;
|
||||
};
|
||||
|
||||
struct PlayCardPayload {
|
||||
GAME::Card card;
|
||||
};
|
||||
|
||||
struct InitGamePayload {
|
||||
size_t playerId;
|
||||
std::vector<PlayerPublicState> players;
|
||||
GAME::DiscardPile discardPile;
|
||||
std::multiset<GAME::Card> handCard;
|
||||
size_t currentPlayerIndex;
|
||||
|
||||
@@ -28,6 +28,20 @@ namespace UNO::NETWORK {
|
||||
return serializeCards(cards.begin(), cards.end());
|
||||
}
|
||||
|
||||
nlohmann::json MessageSerializer::serializePlayerPublicState(const PlayerPublicState &state)
|
||||
{
|
||||
return {{"name", state.name}, {"remaining_cards", state.remainingCardCount}, {"is_uno", state.isUno}};
|
||||
}
|
||||
|
||||
nlohmann::json MessageSerializer::serializePlayerPublicStates(const std::vector<PlayerPublicState> &states)
|
||||
{
|
||||
nlohmann::json result = nlohmann::json::array();
|
||||
for (const auto &state : states) {
|
||||
result.push_back(serializePlayerPublicState(state));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nlohmann::json MessageSerializer::serializePayload(const std::monostate &payload)
|
||||
{
|
||||
return nullptr;
|
||||
@@ -56,6 +70,7 @@ namespace UNO::NETWORK {
|
||||
nlohmann::json MessageSerializer::serializePayload(const InitGamePayload &payload)
|
||||
{
|
||||
return {{"player_id", payload.playerId},
|
||||
{"players", serializePlayerPublicStates(payload.players)},
|
||||
{"discard_pile", serializeDiscardPile(payload.discardPile)},
|
||||
{"hand_card", serializeCards(payload.handCard.begin(), payload.handCard.end())},
|
||||
{"current_player", payload.currentPlayerIndex}};
|
||||
@@ -215,6 +230,41 @@ namespace UNO::NETWORK {
|
||||
return res;
|
||||
}
|
||||
|
||||
PlayerPublicState MessageSerializer::deserializePlayerPublicState(const nlohmann::json &payload)
|
||||
{
|
||||
try {
|
||||
if (payload.is_object() == false) {
|
||||
throw std::invalid_argument("Invalid player public state: expected JSON object");
|
||||
}
|
||||
if (payload.at("name").is_string() == false) {
|
||||
throw std::invalid_argument("Invalid 'name' field in player public state: expected string");
|
||||
}
|
||||
if (payload.at("remaining_cards").is_number_unsigned() == false) {
|
||||
throw std::invalid_argument("Invalid 'remaining_cards' field in player public state: expected unsigned integer");
|
||||
}
|
||||
if (payload.at("is_uno").is_boolean() == false) {
|
||||
throw std::invalid_argument("Invalid 'is_uno' field in player public state: expected boolean");
|
||||
}
|
||||
return {payload.at("name"), payload.at("remaining_cards"), payload.at("is_uno")};
|
||||
}
|
||||
catch (const nlohmann::json::out_of_range &) {
|
||||
throw std::invalid_argument("Missing required field in player public state: expected 'name', 'remaining_cards', 'is_uno'");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PlayerPublicState> MessageSerializer::deserializePlayerPublicStates(const nlohmann::json &payload)
|
||||
{
|
||||
if (payload.is_array() == false) {
|
||||
throw std::invalid_argument("Invalid players field in INIT_GAME payload: expected JSON array");
|
||||
}
|
||||
|
||||
std::vector<PlayerPublicState> players;
|
||||
for (const auto &entry : payload) {
|
||||
players.push_back(deserializePlayerPublicState(entry));
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
std::monostate MessageSerializer::deserializeEmptyPayload(const nlohmann::json &payload)
|
||||
{
|
||||
if (payload.is_null() == false) {
|
||||
@@ -299,13 +349,14 @@ namespace UNO::NETWORK {
|
||||
throw std::invalid_argument("Invalid 'current_player' field in INIT_GAME payload: expected unsigned integer");
|
||||
}
|
||||
return {payload.at("player_id"),
|
||||
deserializePlayerPublicStates(payload.at("players")),
|
||||
deserializeDiscardPile(payload.at("discard_pile")),
|
||||
deserializeHandCard(payload.at("hand_card")),
|
||||
payload.at("current_player")};
|
||||
}
|
||||
catch (const nlohmann::json::out_of_range &) {
|
||||
throw std::invalid_argument(
|
||||
"Missing required field in INIT_GAME payload: expected 'discard_pile', 'hand_card', and 'current_player'");
|
||||
"Missing required field in INIT_GAME payload: expected 'players', 'discard_pile', 'hand_card', and 'current_player'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace UNO::NETWORK {
|
||||
static nlohmann::json serializeCards(Iterator begin, Iterator end);
|
||||
|
||||
static nlohmann::json serializeDiscardPile(const GAME::DiscardPile &discardPile);
|
||||
static nlohmann::json serializePlayerPublicState(const PlayerPublicState &state);
|
||||
static nlohmann::json serializePlayerPublicStates(const std::vector<PlayerPublicState> &states);
|
||||
|
||||
static nlohmann::json serializePayload(const std::monostate &payload);
|
||||
static nlohmann::json serializePayload(const JoinGamePayload &payload);
|
||||
@@ -43,6 +45,8 @@ namespace UNO::NETWORK {
|
||||
static GAME::Card deserializeCard(const nlohmann::json &card);
|
||||
static GAME::DiscardPile deserializeDiscardPile(const nlohmann::json &discardPile);
|
||||
static std::multiset<GAME::Card> deserializeHandCard(const nlohmann::json &handCard);
|
||||
static PlayerPublicState deserializePlayerPublicState(const nlohmann::json &payload);
|
||||
static std::vector<PlayerPublicState> deserializePlayerPublicStates(const nlohmann::json &payload);
|
||||
|
||||
static std::monostate deserializeEmptyPayload(const nlohmann::json &payload);
|
||||
static JoinGamePayload deserializeJoinGamePayload(const nlohmann::json &payload);
|
||||
|
||||
@@ -61,8 +61,15 @@ namespace UNO::SERVER {
|
||||
void UnoServer::handleStartGame()
|
||||
{
|
||||
serverGameState_.init();
|
||||
std::vector<NETWORK::PlayerPublicState> players;
|
||||
players.reserve(serverGameState_.getPlayers().size());
|
||||
for (const auto &player : serverGameState_.getPlayers()) {
|
||||
players.push_back({player.getName(), player.getRemainingCardCount(), player.getIsUno()});
|
||||
}
|
||||
size_t currentPlayerIndex = static_cast<size_t>(serverGameState_.getCurrentPlayer() - serverGameState_.getPlayers().begin());
|
||||
for (size_t i = 0; i < playerCount; i++) {
|
||||
NETWORK::InitGamePayload payload = {i, serverGameState_.getDiscardPile(), serverGameState_.getPlayers()[i].getCards(), 0};
|
||||
NETWORK::InitGamePayload payload = {
|
||||
i, players, serverGameState_.getDiscardPile(), serverGameState_.getPlayers()[i].getCards(), currentPlayerIndex};
|
||||
this->networkServer_.send(
|
||||
gameIdToNetworkId.at(i),
|
||||
NETWORK::MessageSerializer::serialize({NETWORK::MessageStatus::OK, NETWORK::MessagePayloadType::INIT_GAME, payload}));
|
||||
|
||||
Reference in New Issue
Block a user