diff --git a/src/client/GameController.cpp b/src/client/GameController.cpp index 2d2a2ac391f59a9772bf3e553fcf83e3b22d7ce5..d040d52bf81add764986e6ef61d71b7efb0dc1c4 100644 --- a/src/client/GameController.cpp +++ b/src/client/GameController.cpp @@ -170,6 +170,12 @@ 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); +} + void GameController::estimateTricks(int nof_tricks) { estimate_tricks_request request = estimate_tricks_request(GameController::_currentGameState->get_id(), GameController::_me->get_id(), nof_tricks); ClientNetworkManager::sendRequest(request); @@ -180,12 +186,6 @@ void GameController::playCard(card* cardToPlay) { ClientNetworkManager::sendRequest(request); } -void GameController::leaveGame() -{ - leave_game_request request = leave_game_request(GameController::_me->get_id(), GameController::_me->get_player_name()); - ClientNetworkManager::sendRequest(request); -} - // TODO: estimate trick request, here message box with entry void GameController::estimateTrick() { @@ -285,13 +285,11 @@ void GameController::showTrickOverMessage(const player* winner) dialog->ShowModal(); } - void GameController::showGameOverMessage() { std::string title = "Game Over!"; std::string message = "Final score:\n"; std::string buttonLabel = "Close Game"; - // TODO: change logic to determine winner because now we have vector of scores // sort players by score std::vector<player*> players = GameController::_currentGameState->get_players(); std::sort(players.begin(), players.end(), [](const player* a, const player* b) -> bool { @@ -329,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 27a4bcc42d03bdccca16ba6ff41f5ec060f2a81f..4494b483e086491bfac383404b86a8be0b1d4675 100644 --- a/src/client/GameController.h +++ b/src/client/GameController.h @@ -18,8 +18,8 @@ public: static void connectToServer(); static void updateGameState(game_state* newGameState); static void startGame(); - static void estimateTricks(int nof_cards); static void leaveGame(); + static void estimateTricks(int nof_cards); static void playCard(card* cardToPlay); static void estimateTrick(); @@ -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/network/ResponseListenerThread.cpp b/src/client/network/ResponseListenerThread.cpp index 6614d6d24c35f7c570332af12501847c8a0703fc..95f5565e8f411e2c0d1121672e7dd699571baf4c 100644 --- a/src/client/network/ResponseListenerThread.cpp +++ b/src/client/network/ResponseListenerThread.cpp @@ -65,6 +65,7 @@ wxThread::ExitCode ResponseListenerThread::Entry() { } } + // took out check to not have this error at the end of the game when one player leaves if (count <= 0) { this->outputError("Network error", "Read error [" + std::to_string(this->_connection->last_error()) + "]: " + this->_connection->last_error_str()); } diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp index a5ccd39d18a8af4cab390322f24b864c3d8ac17b..8aa0f928c0efa9000425ebc7f6f8dfc16a6c35af 100644 --- a/src/client/panels/MainGamePanelWizard.cpp +++ b/src/client/panels/MainGamePanelWizard.cpp @@ -101,7 +101,13 @@ void MainGamePanelWizard::buildGameState(game_state* gameState, player* me) if (it < players.end()) { me = *it; myPosition = it - players.begin(); - } else { + } + else if (me->has_left_game() == true) + { + GameController::closeGameWindow(); + return; + } + else { GameController::showError("Game state error", "Could not find this player among players of server game."); return; } @@ -157,35 +163,69 @@ void MainGamePanelWizard::buildGameState(game_state* gameState, player* me) this->buildOtherPlayers(sizer, gameState, me, myPosition); // show button to display score board - this->buildScoreBoardButton(sizer, gameState); + this->buildScoreLeaveButtons(sizer, gameState); // update Layout this->Layout(); } -void MainGamePanelWizard::buildScoreBoardButton(wxGridBagSizer *sizer, game_state* gameState) { +void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_state* gameState) { wxGBSizerItem* item = sizer->FindItemAtPosition(wxGBPosition(3,3)); wxPanel* panel = dynamic_cast<wxPanel*>(item->GetWindow()); - if (gameState->is_started()) { - wxBoxSizer *sizer_vert = new wxBoxSizer(wxVERTICAL); - panel->SetSizer(sizer_vert); + wxBoxSizer *sizer_vert = new wxBoxSizer(wxVERTICAL); + panel->SetSizer(sizer_vert); + auto sizer_hor = new wxBoxSizer(wxHORIZONTAL); + sizer_vert->Add(sizer_hor, 1, wxALIGN_LEFT); + + if (gameState->is_started()) + { + wxButton *scoreBoardButton = new wxButton(panel, wxID_ANY, "ScoreBoard"); + scoreBoardButton->SetMinSize(wxSize(110, 43)); //90 , 35 + sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); - wxButton* scoreBoardButton = new wxButton(panel, wxID_ANY, "Scoreboard", wxDefaultPosition, wxSize(110, 43));//size wxSize(110, 43)) for 10 characters; - // wxButton* startGameButton = new wxButton(mePanel, wxID_ANY, "Start Game!", wxDefaultPosition, wxSize(110, 43)); scoreBoardButton->SetFont(magicalFont); scoreBoardButton->SetForegroundColour(wxColour(225, 225, 225)); // Set button text color scoreBoardButton->SetBackgroundColour(wxColour(50, 0, 51)); //same shade of purple as start game button and estimation panel - sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); scoreBoardButton->Bind(wxEVT_BUTTON, [gameState](wxCommandEvent &event) { ScoreBoardDialog scoreBoard(nullptr, "ScoreBoard", "Here will be the scoreboard", gameState); scoreBoard.ShowModal(); }); } + wxButton *leaveGameButton = new wxButton(panel, wxID_ANY, "Leave Game"); + leaveGameButton->SetMinSize(wxSize(110, 43)); + sizer_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); + + leaveGameButton->SetFont(magicalFont); + leaveGameButton->SetBackgroundColour(wxColour(50,0,51)); // Set background color to blue + leaveGameButton->SetForegroundColour(*wxWHITE); + leaveGameButton->Bind(wxEVT_BUTTON, [gameState](wxCommandEvent &event) { + GameController::leaveGame(); + }); } +/* +void MainGamePanelWizard::buildLeaveGameButton(wxGridBagSizer *sizer, game_state* gameState) { + wxGBSizerItem* item = sizer->FindItemAtPosition(wxGBPosition(3,3)); + wxPanel* panel = dynamic_cast<wxPanel*>(item->GetWindow()); + + if (gameState->is_started()) { + wxSizer* sizer_vert = panel->GetSizer(); + // wxBoxSizer *sizer_vert = new wxBoxSizer(wxVERTICAL); + // panel->SetSizer(sizer_vert); + + wxButton *leaveGameButton = new wxButton(panel, wxID_ANY, "Leave Game"); + sizer_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 1); + + leaveGameButton->Bind(wxEVT_BUTTON, [gameState](wxCommandEvent &event) { + GameController::leaveGame(); + }); + } + +} +*/ void MainGamePanelWizard::buildOtherPlayers(wxGridBagSizer* sizer, game_state* gameState, player* me, int myPosition) { std::vector<player*> players = gameState->get_players(); @@ -274,7 +314,6 @@ void MainGamePanelWizard::buildTrumpCard(wxGridBagSizer* sizer, game_state* game int trumpCardValue = gameState->get_trump_card_value(); std::string cardImage = "assets/card_" + std::to_string(trumpCardValue) + "_" + std::to_string(trumpColor)+".png"; - std::cout << cardImage << std::endl; ImagePanel* cardPanel = new ImagePanel(trumpPanel, cardImage, wxBITMAP_TYPE_ANY, wxDefaultPosition, MainGamePanelWizard::cardSize); diff --git a/src/client/panels/MainGamePanelWizard.h b/src/client/panels/MainGamePanelWizard.h index 696a26a56c1c65e6ab3eef8e406ca145ced6684a..d9e8e888eebaf1764e4a321a239f9eb5601f771f 100644 --- a/src/client/panels/MainGamePanelWizard.h +++ b/src/client/panels/MainGamePanelWizard.h @@ -20,7 +20,7 @@ private: void buildTrickPile(wxGridBagSizer* sizer, game_state* gameState, player *me); void buildTrumpCard(wxGridBagSizer* sizer, game_state* gameState); - void buildScoreBoardButton(wxGridBagSizer* sizer, game_state* gameState); + void buildScoreLeaveButtons(wxGridBagSizer* sizer, game_state* gameState); wxSize const panelSize = wxSize(960, 680); // also set in the constructor implementation wxSize const cardSize = wxSize(70, 108); diff --git a/src/client/panels/TrickEstimationPanel.cpp b/src/client/panels/TrickEstimationPanel.cpp index ded9a91218cb7aa913a18cfd24aafa779bafe7b0..c5c88ea3f4fbf47003921a950d12ece001841e1e 100644 --- a/src/client/panels/TrickEstimationPanel.cpp +++ b/src/client/panels/TrickEstimationPanel.cpp @@ -103,31 +103,46 @@ void TrickEstimationPanel::buildGameState(game_state* gameState, player* me) this->buildTrumpColor(sizer, gameState); - this->buildScoreBoardButton(sizer, gameState); + this->buildScoreLeaveButtons(sizer, gameState); this->Layout(); } -void TrickEstimationPanel::buildScoreBoardButton(wxGridBagSizer *sizer, game_state* gameState) { +void TrickEstimationPanel::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_state* gameState) { wxGBSizerItem* item = sizer->FindItemAtPosition(wxGBPosition(2,2)); wxPanel* panel = dynamic_cast<wxPanel*>(item->GetWindow()); wxBoxSizer* sizer_vert = new wxBoxSizer(wxVERTICAL); panel->SetSizer(sizer_vert); + auto sizer_hor = new wxBoxSizer(wxHORIZONTAL); + sizer_vert->Add(sizer_hor, 1, wxALIGN_CENTER); - wxButton* scoreBoardButton = new wxButton(panel, wxID_ANY, "Scoreboard", wxDefaultPosition, wxSize(110, 43)); + wxButton* scoreBoardButton = new wxButton(panel, wxID_ANY, "ScoreBoard"); + scoreBoardButton->SetMinSize(wxSize(110, 43)); //90 35 + + sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); scoreBoardButton->SetFont(magicalFontTrick); scoreBoardButton->SetForegroundColour(wxColour(225, 225, 225)); // Set button text color scoreBoardButton->SetBackgroundColour(wxColour(50, 0, 51)); //make button same purple as estimation panel once clickable - sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); - scoreBoardButton->Bind(wxEVT_BUTTON, [gameState](wxCommandEvent& event) { ScoreBoardDialog scoreBoard(nullptr, "ScoreBoard", "Here will be the scoreboard", gameState); scoreBoard.ShowModal(); }); + wxButton *leaveGameButton = new wxButton(panel, wxID_ANY, "Leave Game"); + leaveGameButton->SetMinSize(wxSize(110, 43)); + sizer_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); + + leaveGameButton->SetFont(magicalFontTrick); + leaveGameButton->SetBackgroundColour(wxColour(50,0,51)); // Set background color to blue + leaveGameButton->SetForegroundColour(*wxWHITE); + + leaveGameButton->Bind(wxEVT_BUTTON, [gameState](wxCommandEvent &event) { + GameController::leaveGame(); + }); + } @@ -145,7 +160,6 @@ void TrickEstimationPanel::buildTrumpColor(wxGridBagSizer *sizer, game_state *ga int trumpCardValue = gameState->get_trump_card_value(); std::string cardImage = "assets/card_" + std::to_string(trumpCardValue) + "_" + std::to_string(trumpColor)+".png"; - std::cout << cardImage << std::endl; ImagePanel* cardPanel = new ImagePanel(trumpPanel, cardImage, wxBITMAP_TYPE_ANY, wxDefaultPosition, TrickEstimationPanel::cardSize); diff --git a/src/client/panels/TrickEstimationPanel.h b/src/client/panels/TrickEstimationPanel.h index f8d9ef67b3c5cf286c97ca2ffa874360a5a54538..bd42b4f8e16bd403b5febeafc3cd1e3e62b3109c 100644 --- a/src/client/panels/TrickEstimationPanel.h +++ b/src/client/panels/TrickEstimationPanel.h @@ -27,7 +27,7 @@ private: void buildThisPlayer(wxGridBagSizer* sizer, game_state* gameState, player* me); void buildOtherPlayers(wxGridBagSizer* sizer, game_state* gameState, int myPosition); - void buildScoreBoardButton(wxGridBagSizer* sizer, game_state* gameState); + void buildScoreLeaveButtons(wxGridBagSizer* sizer, game_state* gameState); InputField* _trickEstimateField; }; diff --git a/src/common/game_state/game_state.cpp b/src/common/game_state/game_state.cpp index db93d9011d9ee28556d35f8e2a766cd4900f084a..625c5f804d74c8c5a2b9bad04459c391a93d8266 100644 --- a/src/common/game_state/game_state.cpp +++ b/src/common/game_state/game_state.cpp @@ -195,6 +195,7 @@ int game_state::get_trick_estimate_sum() const unsigned int game_state::get_max_round_number() const { + //return 1; return 60 / _players.size(); } @@ -444,22 +445,22 @@ bool game_state::play_card(player* player, const std::string& card_id, std::stri bool game_state::remove_player(player *player_ptr, std::string &err) { if (const int idx = get_player_index(player_ptr); idx != -1) { + // Case 1: Game has not been started yet. if (_is_started->get_value() == false) { if (idx < _current_player_idx->get_value()) { // 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 { - finish_game(err); - return true; + return finish_game(err); } } else { err = "Could not leave game, as the requested player was not found in that game."; return false; } - return false; } bool game_state::add_player(player* player_, std::string& err) @@ -509,7 +510,6 @@ bool game_state::add_player(player* player_, std::string& err) bool game_state::finish_game(std::string &err) const { _is_finished->set_value(true); - // TODO: part to determine winner of the game, it is done in game controller right now and could stay there. return true; } #endif @@ -579,7 +579,7 @@ void game_state::write_into_json(rapidjson::Value &json, rapidjson::Value trick_estimate_sum_val(rapidjson::kObjectType); _trick_estimate_sum->write_into_json(trick_estimate_sum_val, allocator); - json.AddMember("trick_estimate_sum_val", trick_estimate_sum_val, allocator); + json.AddMember("trick_estimate_sum", trick_estimate_sum_val, allocator); } @@ -601,7 +601,7 @@ game_state* game_state::from_json(const rapidjson::Value &json) { && json.HasMember("current_player_idx") && json.HasMember("trump_color") && json.HasMember("trump_card_value") - && json.HasMember("trick_estimate_sum_val")) + && json.HasMember("trick_estimate_sum")) { std::vector<player*> deserialized_players; for (auto &serialized_player : json["players"].GetArray()) { @@ -624,7 +624,7 @@ game_state* game_state::from_json(const rapidjson::Value &json) { serializable_value<int>::from_json(json["current_player_idx"].GetObject()), serializable_value<int>::from_json(json["trump_color"].GetObject()), serializable_value<int>::from_json(json["trump_card_value"].GetObject()), - serializable_value<int>::from_json(json["trick_estimate_sum_val"].GetObject())); + serializable_value<int>::from_json(json["trick_estimate_sum"].GetObject())); } throw WizardException("Failed to deserialize game_state. Required entries were missing."); } \ No newline at end of file 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. diff --git a/src/server/game_instance.cpp b/src/server/game_instance.cpp index bcae14517d8f4b809a2ecf216d7c558b525cdc79..38d1ad651f7697b170f816d8c8ee83560cad0119 100644 --- a/src/server/game_instance.cpp +++ b/src/server/game_instance.cpp @@ -75,14 +75,31 @@ bool game_instance::start_game(player* player, std::string &err) { bool game_instance::try_remove_player(player *player, std::string &err) { modification_lock.lock(); - if (_game_state->remove_player(player, err)) { - player->set_game_id(""); - // send state update to all other players + if(_game_state->remove_player(player, err)) + { + // player->set_game_id(""); full_state_response state_update_msg = full_state_response(this->get_id(), *_game_state); server_network_manager::broadcast_message(state_update_msg, _game_state->get_players(), player); modification_lock.unlock(); return true; } + /* + if (_game_state->is_started()) { + // send state update to all other players + _game_state->finish_game(err); + full_state_response state_update_msg = full_state_response(this->get_id(), *_game_state); + server_network_manager::broadcast_message(state_update_msg, _game_state->get_players(), player); + modification_lock.unlock(); + return true; + */ + //}// else if (_game_state->remove_player(player, err)){ + // player->set_game_id(""); + // send state update to all other players + // full_state_response state_update_msg = full_state_response(this->get_id(), *_game_state); + //server_network_manager::broadcast_message(state_update_msg, _game_state->get_players(), player); + //modification_lock.unlock(); + //return true; + //} modification_lock.unlock(); return false; } diff --git a/src/server/request_handler.cpp b/src/server/request_handler.cpp index 2056ca28a52460218ceb0b9748dbdfbf1a729732..081e78c901f0926ed53a945a12ec252b12fe8e3c 100644 --- a/src/server/request_handler.cpp +++ b/src/server/request_handler.cpp @@ -129,24 +129,24 @@ request_response* request_handler::handle_request(const client_request* const re // ##################### LEAVE GAME ##################### // case RequestType::leave_game: { - //get player name - std::string player_name = ((leave_game_request *) req)->get_player_name(); // Case 1: player is in a game //remove player from game via game instance manager -> game instance -> game state - if (game_instance_manager::try_remove_player(player, game_id, err)) - { - //remove player from list of active players (delete from LUT table) - if (player_manager::remove_player(player_id, player)){ - return new request_response(game_instance_ptr->get_id(), req_id, true, - game_instance_ptr->get_game_state()->to_json(), err); - } - // Case 2: player is already in player_LUT of player_manager but not yet in a game - player_manager::remove_player(player_id, player); + if (game_instance_manager::try_get_player_and_game_instance(player_id, player, game_instance_ptr, err)) { + if (game_instance_manager::try_remove_player(player, game_id, err)) { + std::cout << "Player successfully removed from the game " << std::endl; + if (player_manager::remove_player(player_id, player)){ + return new request_response(game_instance_ptr->get_id(), req_id, true, + game_instance_ptr->get_game_state()->to_json(), err); + } - //Case 3: player either couldn't be removed from game or player LUT + } + } // Case 2: player not in game yet but already in LUT + else if(player_manager::remove_player(player_id, player)) { + return new request_response(game_instance_ptr->get_id(), req_id, true, + game_instance_ptr->get_game_state()->to_json(), err); + } else { + err = "Player or game instance were not found."; return new request_response("", req_id, false, nullptr, err); - - } } // ##################### UNKNOWN REQUEST ##################### // diff --git a/unit-tests/game_state.cpp b/unit-tests/game_state.cpp index 6954e44fc3541c7f17b9ffbe99297914705b5aef..c5032b8e1c4fa2be25fe8a04ed8f26a1ba3ea4f3 100644 --- a/unit-tests/game_state.cpp +++ b/unit-tests/game_state.cpp @@ -320,7 +320,8 @@ void create_json(rapidjson::Value &json, rapidjson::MemoryPoolAllocator<rapidjso serializable_value<bool>* test_is_estimation_phase, serializable_value<int>* test_round_number, serializable_value<int>* test_trick_number, serializable_value<int>* test_starting_player_idx, serializable_value<int>* test_trick_starting_player_idx, serializable_value<int>* test_current_player_idx, - serializable_value<int>* test_trump_color, serializable_value<int>* test_trick_estimate_sum) + serializable_value<int>* test_trump_color, serializable_value<int>* test_trump_card_value, + serializable_value<int>* test_trick_estimate_sum) { // id json.AddMember("id", "4f38hvid20dj", allocator); @@ -388,10 +389,15 @@ void create_json(rapidjson::Value &json, rapidjson::MemoryPoolAllocator<rapidjso test_trump_color->write_into_json(trump_color_val, allocator); json.AddMember("trump_color", trump_color_val, allocator); + // trump card value + rapidjson::Value trump_card_value_val(rapidjson::kObjectType); + test_trump_card_value->write_into_json(trump_card_value_val, allocator); + json.AddMember("trump_card_value", trump_card_value_val, allocator); + // trick estimate sum rapidjson::Value trick_estimate_sum_val(rapidjson::kObjectType); test_trick_estimate_sum->write_into_json(trick_estimate_sum_val, allocator); - json.AddMember("trick_estimate_sum_val", trick_estimate_sum_val, allocator); + json.AddMember("trick_estimate_sum", trick_estimate_sum_val, allocator); } @@ -410,13 +416,15 @@ TEST(GameStateJson, CreateJson) const auto test_trick_starting_player_idx = new serializable_value<int>(0); const auto test_current_player_idx = new serializable_value<int>(0); const auto test_trump_color = new serializable_value<int>(0); + const auto test_trump_card_value = new serializable_value<int>(0); const auto test_trick_estimate_sum = new serializable_value<int>(0); auto* json = new rapidjson::Document(); json->SetObject(); create_json(*json, json->GetAllocator(), test_players, test_deck, test_trick, test_last_trick, test_is_finished, test_is_started, test_is_estimation_phase, test_round_number, test_trick_number, test_starting_player_idx, - test_trick_starting_player_idx, test_current_player_idx, test_trump_color, test_trick_estimate_sum); + test_trick_starting_player_idx, test_current_player_idx, test_trump_color, test_trump_card_value, + test_trick_estimate_sum); const std::string message = json_utils::to_string(json); delete json; @@ -449,6 +457,7 @@ TEST(GameStateUpdateCurrentPlayerTest, UpatePLayerEstimation) const auto test_trick_starting_player_idx = new serializable_value<int>(2); // depends on who won last trick const auto test_current_player_idx = new serializable_value<int>(2); // first one to estimate const auto test_trump_color = new serializable_value<int>(2); + const auto test_trump_card_value = new serializable_value<int>(2); const auto test_trick_estimate_sum = new serializable_value<int>(0); auto* json = new rapidjson::Document(); @@ -456,7 +465,7 @@ TEST(GameStateUpdateCurrentPlayerTest, UpatePLayerEstimation) create_json(*json, json->GetAllocator(), test_players, test_deck, test_trick, test_last_trick, test_is_finished, test_is_started, test_is_estimation_phase, test_round_number, test_trick_number, test_starting_player_idx, test_trick_starting_player_idx, test_current_player_idx, test_trump_color, - test_trick_estimate_sum); + test_trump_card_value, test_trick_estimate_sum); const std::string message = json_utils::to_string(json); delete json; @@ -491,6 +500,7 @@ TEST(GameStateUpdateCurrentPlayerTest, UpatePLayerEstimationToPlaying) const auto test_trick_starting_player_idx = new serializable_value<int>(0); // round starter starts const auto test_current_player_idx = new serializable_value<int>(3); // last one to estimate const auto test_trump_color = new serializable_value<int>(2); + const auto test_trump_card_value = new serializable_value<int>(2); const auto test_trick_estimate_sum = new serializable_value<int>(4); auto* json = new rapidjson::Document(); @@ -498,7 +508,7 @@ TEST(GameStateUpdateCurrentPlayerTest, UpatePLayerEstimationToPlaying) create_json(*json, json->GetAllocator(), test_players, test_deck, test_trick, test_last_trick, test_is_finished, test_is_started, test_is_estimation_phase, test_round_number, test_trick_number, test_starting_player_idx, test_trick_starting_player_idx, test_current_player_idx, test_trump_color, - test_trick_estimate_sum); + test_trump_card_value, test_trick_estimate_sum); const std::string message = json_utils::to_string(json); delete json; @@ -534,6 +544,7 @@ TEST(GameStateUpdateCurrentPlayerTest, UpatePLayerPlayingToNextRound) const auto test_trick_starting_player_idx = new serializable_value<int>(2); // depends on last trick const auto test_current_player_idx = new serializable_value<int>(1); // last one to play const auto test_trump_color = new serializable_value<int>(2); + const auto test_trump_card_value = new serializable_value<int>(2); const auto test_trick_estimate_sum = new serializable_value<int>(4); auto* json = new rapidjson::Document(); @@ -541,7 +552,7 @@ TEST(GameStateUpdateCurrentPlayerTest, UpatePLayerPlayingToNextRound) create_json(*json, json->GetAllocator(), test_players, test_deck, test_trick, test_last_trick, test_is_finished, test_is_started, test_is_estimation_phase, test_round_number, test_trick_number, test_starting_player_idx, test_trick_starting_player_idx, test_current_player_idx, test_trump_color, - test_trick_estimate_sum); + test_trump_card_value, test_trick_estimate_sum); const std::string message = json_utils::to_string(json); delete json; @@ -604,6 +615,7 @@ TEST(GameStateFinishGameTest, FinishGame) const auto test_trick_starting_player_idx = new serializable_value<int>(2); // depends on last trick const auto test_current_player_idx = new serializable_value<int>(1); // last one to play const auto test_trump_color = new serializable_value<int>(2); + const auto test_trump_card_value = new serializable_value<int>(2); const auto test_trick_estimate_sum = new serializable_value<int>(12); auto* json = new rapidjson::Document(); @@ -611,7 +623,7 @@ TEST(GameStateFinishGameTest, FinishGame) create_json(*json, json->GetAllocator(), test_players, test_deck, test_trick, test_last_trick, test_is_finished, test_is_started, test_is_estimation_phase, test_round_number, test_trick_number, test_starting_player_idx, test_trick_starting_player_idx, test_current_player_idx, test_trump_color, - test_trick_estimate_sum); + test_trump_card_value, test_trick_estimate_sum); const std::string message = json_utils::to_string(json); delete json;