diff --git a/src/client/GameController.cpp b/src/client/GameController.cpp index 1b481b627683bd54d228adf51e38f83160a2a3d6..40522af6976bc1a28e5293cf0a57a99042e9d11d 100644 --- a/src/client/GameController.cpp +++ b/src/client/GameController.cpp @@ -290,7 +290,6 @@ void GameController::showGameOverMessage() { 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 { 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 726b090ecbb1382372104a87103f56942c84d724..39f2d4f2be5bc3e739cb68954288f77b1aa4f71e 100644 --- a/src/client/panels/MainGamePanelWizard.cpp +++ b/src/client/panels/MainGamePanelWizard.cpp @@ -178,7 +178,7 @@ void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_sta wxButton *scoreBoardButton = new wxButton(panel, wxID_ANY, "ScoreBoard"); scoreBoardButton->SetMinSize(wxSize(110, 43)); //90 , 35 - sizer_hor->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); + sizer_hor->Add(scoreBoardButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3); scoreBoardButton->SetFont(magicalFont); scoreBoardButton->SetForegroundColour(wxColour(225, 225, 225)); // Set button text color @@ -191,7 +191,7 @@ void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_sta wxButton *leaveGameButton = new wxButton(panel, wxID_ANY, "Leave Game"); leaveGameButton->SetMinSize(wxSize(110, 43)); - sizer_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); + sizer_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3); leaveGameButton->SetFont(magicalFont); leaveGameButton->SetBackgroundColour(wxColour(50,0,51)); // Set background color to blue diff --git a/src/client/panels/TrickEstimationPanel.cpp b/src/client/panels/TrickEstimationPanel.cpp index e661ccfc0d78f0d73221e3a9d421a6762910709c..79e7092087ed0d5378b5681b11ac204684d5351c 100644 --- a/src/client/panels/TrickEstimationPanel.cpp +++ b/src/client/panels/TrickEstimationPanel.cpp @@ -121,7 +121,7 @@ void TrickEstimationPanel::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_st wxButton* scoreBoardButton = new wxButton(panel, wxID_ANY, "ScoreBoard"); scoreBoardButton->SetMinSize(wxSize(110, 43)); //90 35 - sizer_hor->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); + sizer_hor->Add(scoreBoardButton, 0, wxALIGN_CENTER_VERTICAL | 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 @@ -133,7 +133,7 @@ void TrickEstimationPanel::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_st wxButton *leaveGameButton = new wxButton(panel, wxID_ANY, "Leave Game"); leaveGameButton->SetMinSize(wxSize(110, 43)); - sizer_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3); + sizer_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3); leaveGameButton->SetFont(magicalFontTrick); 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 dbadead893ab62b04be85f6d36113e0ef58af288..458294a4bb5273ae1ad047cc674215780d960f4f 100644 --- a/src/common/game_state/game_state.cpp +++ b/src/common/game_state/game_state.cpp @@ -208,6 +208,7 @@ int game_state::get_trick_estimate_sum() const unsigned int game_state::get_max_round_number() const { + //return 1; return 60 / _players.size(); } @@ -452,23 +453,35 @@ 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) { - 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); - } - _players.erase(_players.begin() + idx); - return true; - } else { - finish_game(err); - return true; + // only called when game hasn't been started yet + // get pointer of leaving player by id + if(player_ptr == nullptr) + { + std::cout << "Player does not exist." << std::endl; + } + std::cout << "Player" << player_ptr->get_id() << std::endl; + player* leaving_player = nullptr; + std::cout << "Loop started" << std::endl; + for (player* p : _players){ + if (player_ptr->get_player_name() == p->get_player_name()) { + leaving_player = p; } - } else { + } + std::cout << "Loop ended" << std::endl; + + if (leaving_player == nullptr) { err = "Could not leave game, as the requested player was not found in that game."; return false; } - return false; + + const int idx = get_player_index(leaving_player); + + 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); + } + _players.erase(_players.begin() + idx); + return true; } bool game_state::add_player(player* player, std::string& err) @@ -497,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 diff --git a/src/server/game_instance.cpp b/src/server/game_instance.cpp index bcae14517d8f4b809a2ecf216d7c558b525cdc79..9c844c0284e8d3409a51813efa05a4a6fd61f579 100644 --- a/src/server/game_instance.cpp +++ b/src/server/game_instance.cpp @@ -75,14 +75,21 @@ 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(""); + 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 751773a103b1a099f0e5161e5ae71bf05afcbf39..c28844c990de5919d3e15b9da6b5fe91c07077a7 100644 --- a/src/server/request_handler.cpp +++ b/src/server/request_handler.cpp @@ -129,21 +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 + std::cout << "Leave game request reached request handler." << std::endl; 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, + std::cout << "Player successfully removed from the game " << std::endl; + return new request_response(game_instance_ptr->get_id(), req_id, true, game_instance_ptr->get_game_state()->to_json(), err); - } + + //remove player from list of active players (delete from LUT table) + //if (player_manager::remove_player(player_id, player)){ + //} } // player not in game instance yet but already in LUT - else if (player_manager::remove_player(player_id, player)) { - return new request_response("", req_id, true, nullptr, err); - } + //else if (player_manager::remove_player(player_id, player)) { + // return new request_response("", req_id, true, nullptr, err); + //} else { err = "Player was found neither in any game nor in lookup table."; return new request_response("", req_id, false, nullptr, err);