diff --git a/src/client/GameController.cpp b/src/client/GameController.cpp index 40522af6976bc1a28e5293cf0a57a99042e9d11d..d040d52bf81add764986e6ef61d71b7efb0dc1c4 100644 --- a/src/client/GameController.cpp +++ b/src/client/GameController.cpp @@ -171,6 +171,7 @@ void GameController::startGame() { } void GameController::leaveGame() { + _me->set_has_left_game(true); leave_game_request request = leave_game_request(GameController::_currentGameState->get_id(), GameController::_me->get_id(), _me->get_player_name()); ClientNetworkManager::sendRequest(request); } @@ -284,7 +285,6 @@ void GameController::showTrickOverMessage(const player* winner) dialog->ShowModal(); } - void GameController::showGameOverMessage() { std::string title = "Game Over!"; std::string message = "Final score:\n"; @@ -327,3 +327,8 @@ void GameController::showGameOverMessage() { GameController::_gameWindow->Close(); } } + +void GameController::closeGameWindow() +{ + GameController::_gameWindow->Close(); +} diff --git a/src/client/GameController.h b/src/client/GameController.h index 90310f6f17e6ef7cf53157b04f88bb75b1bd63bc..4494b483e086491bfac383404b86a8be0b1d4675 100644 --- a/src/client/GameController.h +++ b/src/client/GameController.h @@ -29,6 +29,7 @@ public: static void showNewRoundMessage(game_state* oldGameState, game_state* newGameState); static void showTrickOverMessage(const player* winner); static void showGameOverMessage(); + static void closeGameWindow(); private: static GameWindow* _gameWindow; diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp index 03c600637865455919996b1c3aa88414c3f8817f..f9b2eac6c2ef819cc956f7c7fc87971f92b70c88 100644 --- a/src/client/panels/MainGamePanelWizard.cpp +++ b/src/client/panels/MainGamePanelWizard.cpp @@ -98,10 +98,18 @@ void MainGamePanelWizard::buildGameState(game_state* gameState, player* me) std::vector<player*>::iterator it = std::find_if(players.begin(), players.end(), [me](const player* x) { return x->get_id() == me->get_id(); }); + std::cout << me->has_left_game() << std::endl; if (it < players.end()) { me = *it; myPosition = it - players.begin(); - } else { + } + else if (me->has_left_game() == true) + { + //GameController::showError("Left Game", "You have left the game."); + GameController::closeGameWindow(); + return; + } + else { GameController::showError("Game state error", "Could not find this player among players of server game."); return; } @@ -176,7 +184,7 @@ void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_sta { wxButton *scoreBoardButton = new wxButton(panel, wxID_ANY, "ScoreBoard"); scoreBoardButton->SetMinSize(wxSize(110, 43)); //90 , 35 - sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3); + sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); scoreBoardButton->SetFont(magicalFont); scoreBoardButton->SetForegroundColour(wxColour(225, 225, 225)); // Set button text color @@ -189,7 +197,7 @@ void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_sta } wxButton *leaveGameButton = new wxButton(panel, wxID_ANY, "Leave Game"); leaveGameButton->SetMinSize(wxSize(110, 43)); - sizer_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3); + sizer_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); leaveGameButton->SetFont(magicalFont); leaveGameButton->SetBackgroundColour(wxColour(50,0,51)); // Set background color to blue diff --git a/src/common/game_state/game_state.cpp b/src/common/game_state/game_state.cpp index 845f15781274075902bc53a8ba4f07643dbdcd3b..e2295a1d1ad11d3f92a3e42c1bc10d7c83820f25 100644 --- a/src/common/game_state/game_state.cpp +++ b/src/common/game_state/game_state.cpp @@ -451,6 +451,7 @@ bool game_state::remove_player(player *player_ptr, std::string &err) // reduce current_player_idx if the player who left had a lower index _current_player_idx->set_value(_current_player_idx->get_value() - 1); } + player_ptr->set_has_left_game(true); _players.erase(_players.begin() + idx); return true; } else { diff --git a/src/common/game_state/player/player.cpp b/src/common/game_state/player/player.cpp index 2efef60fb69299dd3d84775c1eac903826a4460e..c33546fb5039df82c9b77e2ae553564e885724e9 100644 --- a/src/common/game_state/player/player.cpp +++ b/src/common/game_state/player/player.cpp @@ -8,20 +8,22 @@ player::player(const std::string& name) : unique_serializable() { this->_nof_predicted = new serializable_value<int>(-1); this->_nof_tricks = new serializable_value<int>(0); this->_scores = std::vector<serializable_value<int>*>(0); + this->_has_left_game = new serializable_value<bool>(false); this->_hand = new hand(); - } // deserialization constructor player::player(const std::string& id, serializable_value<std::string>* name, serializable_value<int>* nof_tricks, serializable_value<int>* nof_predicted, - const std::vector<serializable_value<int>*>& scores, hand *hand) : + const std::vector<serializable_value<int>*>& scores, + serializable_value<bool>* player_has_left_game, hand *hand) : unique_serializable(id), _player_name(name), _nof_tricks(nof_tricks), _nof_predicted(nof_predicted), _scores(scores), + _has_left_game(player_has_left_game), _hand(hand) { } @@ -32,11 +34,13 @@ player::~player() { delete _player_name; delete _nof_predicted; delete _nof_tricks; + delete _has_left_game; _hand = nullptr; _player_name = nullptr; _nof_predicted = nullptr; _nof_tricks = nullptr; + _has_left_game = nullptr; } } @@ -50,6 +54,7 @@ player::player(const std::string& id, const std::string& name) : this->_hand = new hand(); this->_nof_predicted = new serializable_value<int>(-1); this->_nof_tricks = new serializable_value<int>(0); + this->_has_left_game = new serializable_value<bool>(false); } // server accessors @@ -87,6 +92,16 @@ void player::set_nof_tricks(const int nof_tricks) const _nof_tricks->set_value(nof_tricks); } +bool player::has_left_game() const +{ + return _has_left_game->get_value(); +} + +void player::set_has_left_game(bool has_left_game) +{ + _has_left_game->set_value(has_left_game); +} + // getter and setter for number of predicted tricks int player::get_nof_predicted() const noexcept @@ -175,6 +190,10 @@ void player::write_into_json(rapidjson::Value& json, rapidjson::Document::Alloca json.AddMember("scores", vector_utils::serialize_vector(_scores, allocator), allocator); + rapidjson::Value has_left_game_val(rapidjson::kObjectType); + _has_left_game->write_into_json(has_left_game_val, allocator); + json.AddMember("has_left_game", has_left_game_val, allocator); + rapidjson::Value hand_val(rapidjson::kObjectType); _hand->write_into_json(hand_val, allocator); json.AddMember("hand", hand_val, allocator); @@ -186,6 +205,7 @@ player* player::from_json(const rapidjson::Value &json) { && json.HasMember("nof_tricks") && json.HasMember("player_name") && json.HasMember("scores") + && json.HasMember("has_left_game") && json.HasMember("hand")) { std::vector<serializable_value<int>*> deserialized_scores; @@ -198,6 +218,7 @@ player* player::from_json(const rapidjson::Value &json) { serializable_value<int>::from_json(json["nof_tricks"].GetObject()), serializable_value<int>::from_json(json["nof_predicted"].GetObject()), deserialized_scores, + serializable_value<bool>::from_json(json["has_left_game"].GetObject()), hand::from_json(json["hand"].GetObject())); } else { throw WizardException("Failed to deserialize player from json. Required json entries were missing."); diff --git a/src/common/game_state/player/player.h b/src/common/game_state/player/player.h index 1eb41bde7cb0d4741d76bbc93656aaaf6343ccda..3a1f1592c10b2894e61ee9c66a6d4a34f377127d 100644 --- a/src/common/game_state/player/player.h +++ b/src/common/game_state/player/player.h @@ -22,6 +22,7 @@ private: serializable_value<int>* _nof_tricks; ///< The number of tricks won in the current round. serializable_value<int>* _nof_predicted; ///< The number of predicted tricks in the current round. std::vector<serializable_value<int>*> _scores; ///< The scores of the player (total game score, current and past ones). + serializable_value<bool>* _has_left_game; ///< Boolean whether player has left the game. hand* _hand; ///< The player's hand holding the player's cards. #ifdef WIZARD_SERVER @@ -35,6 +36,7 @@ private: * @param nof_tricks The number of tricks won by the player in the current round. * @param nof_predicted The number of tricks predicted to be won by the player in the current round. * @param scores The player's scores. + * @param has_left_game Boolean whether player has left the game. * @param hand The player's hand. */ player(const std::string& id, @@ -42,6 +44,7 @@ private: serializable_value<int>* nof_tricks, serializable_value<int>* nof_predicted, const std::vector<serializable_value<int>*>& scores, + serializable_value<bool>* has_left_game, hand* hand); public: @@ -106,6 +109,18 @@ public: */ void set_nof_tricks(int nof_tricks) const; + /** + * @brief State whether player has left the game. + * @return Boolean stating whether player has left the game. + */ + [[nodiscard]] bool has_left_game() const; + + /** + * @brief Sets the players game to left when he leaves the game + * @param has_left_game Boolean whether player has left game + */ + void set_has_left_game(bool has_left_game); + /** * @brief Gets the number of tricks predicted to be won by the player in the current round. * @return The number of tricks predicted to be won by the player in the current round. @@ -127,6 +142,7 @@ public: */ [[nodiscard]] unsigned int get_nof_cards() const noexcept; + /** * @brief Gets the player's hand. * @return The player's hand.