From 9babca05c51fc1fd17bee5286efa5caf5220b140 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Sat, 14 Dec 2024 18:15:30 +0100
Subject: [PATCH] work in progress: leave game request. I have no idea why
 request response leads to an error.

---
 src/client/GameController.cpp                 |  1 -
 src/client/network/ResponseListenerThread.cpp |  1 +
 src/client/panels/MainGamePanelWizard.cpp     |  4 +-
 src/client/panels/TrickEstimationPanel.cpp    |  4 +-
 src/common/game_state/game_state.cpp          | 40 ++++++++++++-------
 src/server/game_instance.cpp                  | 13 ++++--
 src/server/request_handler.cpp                | 21 +++++-----
 7 files changed, 53 insertions(+), 31 deletions(-)

diff --git a/src/client/GameController.cpp b/src/client/GameController.cpp
index 1b481b6..40522af 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 6614d6d..95f5565 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 726b090..39f2d4f 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 e661ccf..79e7092 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 dbadead..458294a 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 bcae145..9c844c0 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 751773a..c28844c 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);
-- 
GitLab