From 28edcc96ba7fdcccb91a6fa000b279447dd976f9 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Thu, 12 Dec 2024 15:24:39 +0100
Subject: [PATCH 01/16] work on leaveGame button

---
 src/client/GameController.cpp             | 11 +++++------
 src/client/GameController.h               |  2 +-
 src/client/panels/MainGamePanelWizard.cpp | 21 +++++++++++++++++++++
 src/client/panels/MainGamePanelWizard.h   |  1 +
 4 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/src/client/GameController.cpp b/src/client/GameController.cpp
index d732d59..bbacad9 100644
--- a/src/client/GameController.cpp
+++ b/src/client/GameController.cpp
@@ -147,6 +147,11 @@ void GameController::startGame() {
     ClientNetworkManager::sendRequest(request);
 }
 
+void GameController::leaveGame() {
+    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);
@@ -157,12 +162,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()
 {
diff --git a/src/client/GameController.h b/src/client/GameController.h
index 43c81bf..b5613b5 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();
 
diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp
index 672ba92..c74f980 100644
--- a/src/client/panels/MainGamePanelWizard.cpp
+++ b/src/client/panels/MainGamePanelWizard.cpp
@@ -144,6 +144,9 @@ void MainGamePanelWizard::buildGameState(game_state* gameState, player* me)
     // show button to display score board
     this->buildScoreBoardButton(sizer, gameState);
 
+    // show button to leave game
+    this->buildLeaveGameButton(sizer, gameState, me);
+
     // update Layout
     this->Layout();
 }
@@ -167,6 +170,24 @@ void MainGamePanelWizard::buildScoreBoardButton(wxGridBagSizer *sizer, game_stat
 
 }
 
+void MainGamePanelWizard::buildLeaveGameButton(wxGridBagSizer *sizer, game_state* gameState, player* me) {
+    wxGBSizerItem* item = sizer->FindItemAtPosition(wxGBPosition(3,4));
+    wxPanel* panel = dynamic_cast<wxPanel*>(item->GetWindow());
+
+    if (gameState->is_started()) {
+        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, 5);
+
+        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();
diff --git a/src/client/panels/MainGamePanelWizard.h b/src/client/panels/MainGamePanelWizard.h
index cd1e7cf..4febe89 100644
--- a/src/client/panels/MainGamePanelWizard.h
+++ b/src/client/panels/MainGamePanelWizard.h
@@ -21,6 +21,7 @@ private:
     void buildTrumpCard(wxGridBagSizer* sizer, game_state* gameState);
 
     void buildScoreBoardButton(wxGridBagSizer* sizer, game_state* gameState);
+    void buildLeaveGameButton(wxGridBagSizer *sizer, game_state* gameState, player* me);
 
     wxSize const panelSize = wxSize(960, 680); // also set in the constructor implementation
     wxSize const cardSize = wxSize(70, 108);
-- 
GitLab


From 4b607dcb503caa013a08d21edc5d995212c0069e Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Thu, 12 Dec 2024 15:28:24 +0100
Subject: [PATCH 02/16] fixed error that happened during merge with two many
 constructors in trick

---
 src/common/game_state/cards/trick.h | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/src/common/game_state/cards/trick.h b/src/common/game_state/cards/trick.h
index 93766b7..710b275 100644
--- a/src/common/game_state/cards/trick.h
+++ b/src/common/game_state/cards/trick.h
@@ -38,17 +38,11 @@ public:
      * @brief Constructs a new trick object.
      */
     trick();
-    explicit trick(std::string id);
-    trick(std::string id,
-        std::vector<std::pair<card*, player*>> &cards,
-        serializable_value<int>* trick_color,
-        serializable_value<int>* trump_color);
 
     /**
      * @brief Constructs a new trick object as a deep copy of another trick object.
      * @param other The trick it is copied from.
      */
-
     trick(const trick &other);
 
     /**
-- 
GitLab


From b82eafab170c28ad7f6df0848922de82ae93ece1 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Thu, 12 Dec 2024 16:02:30 +0100
Subject: [PATCH 03/16] add work on leave game button

---
 src/client/panels/MainGamePanelWizard.cpp | 2 +-
 src/client/panels/MainGamePanelWizard.h   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp
index c74f980..3afc394 100644
--- a/src/client/panels/MainGamePanelWizard.cpp
+++ b/src/client/panels/MainGamePanelWizard.cpp
@@ -170,7 +170,7 @@ void MainGamePanelWizard::buildScoreBoardButton(wxGridBagSizer *sizer, game_stat
 
 }
 
-void MainGamePanelWizard::buildLeaveGameButton(wxGridBagSizer *sizer, game_state* gameState, player* me) {
+void MainGamePanelWizard::buildLeaveGameButton(wxGridBagSizer *sizer, game_state* gameState) {
     wxGBSizerItem* item = sizer->FindItemAtPosition(wxGBPosition(3,4));
     wxPanel* panel = dynamic_cast<wxPanel*>(item->GetWindow());
 
diff --git a/src/client/panels/MainGamePanelWizard.h b/src/client/panels/MainGamePanelWizard.h
index 4febe89..2950112 100644
--- a/src/client/panels/MainGamePanelWizard.h
+++ b/src/client/panels/MainGamePanelWizard.h
@@ -21,7 +21,7 @@ private:
     void buildTrumpCard(wxGridBagSizer* sizer, game_state* gameState);
 
     void buildScoreBoardButton(wxGridBagSizer* sizer, game_state* gameState);
-    void buildLeaveGameButton(wxGridBagSizer *sizer, game_state* gameState, player* me);
+    void buildLeaveGameButton(wxGridBagSizer *sizer, game_state* gameState);
 
     wxSize const panelSize = wxSize(960, 680); // also set in the constructor implementation
     wxSize const cardSize = wxSize(70, 108);
-- 
GitLab


From 753d332d6b7f8b5eebd954b9be7e8103b16bb9b8 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Thu, 12 Dec 2024 16:14:10 +0100
Subject: [PATCH 04/16] todo: adapt request handler leave game

---
 src/server/request_handler.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/server/request_handler.cpp b/src/server/request_handler.cpp
index 2056ca2..91ad458 100644
--- a/src/server/request_handler.cpp
+++ b/src/server/request_handler.cpp
@@ -140,6 +140,7 @@ request_response* request_handler::handle_request(const client_request* const re
                         return new request_response(game_instance_ptr->get_id(), req_id, true,
                                                     game_instance_ptr->get_game_state()->to_json(), err);
                     }
+                    // TODO: I think this logic makes no sense, if the player is not in the game this should be outside the if cond it is in
                     // Case 2: player is already in player_LUT of player_manager but not yet in a game
                     player_manager::remove_player(player_id, player);
 
-- 
GitLab


From cc617a07db9f26cb8530caef5d70c7d7673cf898 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Fri, 13 Dec 2024 13:12:30 +0100
Subject: [PATCH 05/16] leave game handling in request handler corrected

---
 src/server/request_handler.cpp | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/src/server/request_handler.cpp b/src/server/request_handler.cpp
index 91ad458..751773a 100644
--- a/src/server/request_handler.cpp
+++ b/src/server/request_handler.cpp
@@ -133,21 +133,20 @@ request_response* request_handler::handle_request(const client_request* const re
                 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))
-                {
+                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);
                     }
-                    // TODO: I think this logic makes no sense, if the player is not in the game this should be outside the if cond it is in
-                    // Case 2: player is already in player_LUT of player_manager but not yet in a game
-                    player_manager::remove_player(player_id, player);
-
-                    //Case 3: player either couldn't be removed from game or player LUT
+                }
+                // 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 {
+                    err = "Player was found neither in any game nor in lookup table.";
                     return new request_response("", req_id, false, nullptr, err);
-
-
                 }
             }
         // ##################### UNKNOWN REQUEST ##################### //
-- 
GitLab


From 78465f7fa02818ac7d29b2a2f5115cf1bec89ebe Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Fri, 13 Dec 2024 16:02:21 +0100
Subject: [PATCH 06/16] error correcrted in leave game request

---
 src/client/panels/MainGamePanelWizard.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp
index 3afc394..1e20c66 100644
--- a/src/client/panels/MainGamePanelWizard.cpp
+++ b/src/client/panels/MainGamePanelWizard.cpp
@@ -145,7 +145,7 @@ void MainGamePanelWizard::buildGameState(game_state* gameState, player* me)
     this->buildScoreBoardButton(sizer, gameState);
 
     // show button to leave game
-    this->buildLeaveGameButton(sizer, gameState, me);
+    this->buildLeaveGameButton(sizer, gameState);
 
     // update Layout
     this->Layout();
-- 
GitLab


From 8629aa29aad5105298a6bde00682e84a3280e6c5 Mon Sep 17 00:00:00 2001
From: hwinter <hwinter@student.ethz.ch>
Date: Fri, 13 Dec 2024 17:03:15 +0100
Subject: [PATCH 07/16] buttons

---
 src/client/panels/MainGamePanelWizard.cpp  | 37 ++++++++++++++++------
 src/client/panels/MainGamePanelWizard.h    |  3 +-
 src/client/panels/TrickEstimationPanel.cpp | 25 +++++++++++++--
 src/client/panels/TrickEstimationPanel.h   |  2 +-
 4 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp
index 1e20c66..ced27ad 100644
--- a/src/client/panels/MainGamePanelWizard.cpp
+++ b/src/client/panels/MainGamePanelWizard.cpp
@@ -142,44 +142,63 @@ 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);
 
     // show button to leave game
-    this->buildLeaveGameButton(sizer, gameState);
+    // this->buildLeaveGameButton(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);
+        auto sizer_hor = new wxBoxSizer(wxHORIZONTAL);
+        sizer_vert->Add(sizer_hor, 1, wxALIGN_LEFT);
 
         wxButton *scoreBoardButton = new wxButton(panel, wxID_ANY, "ScoreBoard");
-        sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+        scoreBoardButton->SetMinSize(wxSize(90, 35));
+        sizer_hor->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3);
+
+        scoreBoardButton->SetBackgroundColour(wxColour(50,0,51));  // Set background color to blue
+        scoreBoardButton->SetForegroundColour(*wxWHITE);
 
         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(90, 35));
+        sizer_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3);
+
+        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,4));
+    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);
+        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, 5);
+        sizer_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 1);
 
         leaveGameButton->Bind(wxEVT_BUTTON, [gameState](wxCommandEvent &event) {
             GameController::leaveGame();
@@ -187,7 +206,7 @@ void MainGamePanelWizard::buildLeaveGameButton(wxGridBagSizer *sizer, game_state
     }
 
 }
-
+*/
 void MainGamePanelWizard::buildOtherPlayers(wxGridBagSizer* sizer, game_state* gameState, player* me, int myPosition)
 {
     std::vector<player*> players = gameState->get_players();
diff --git a/src/client/panels/MainGamePanelWizard.h b/src/client/panels/MainGamePanelWizard.h
index 2950112..01831b0 100644
--- a/src/client/panels/MainGamePanelWizard.h
+++ b/src/client/panels/MainGamePanelWizard.h
@@ -20,8 +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 buildLeaveGameButton(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 34cb20d..277d4d2 100644
--- a/src/client/panels/TrickEstimationPanel.cpp
+++ b/src/client/panels/TrickEstimationPanel.cpp
@@ -100,27 +100,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");
-    sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+    scoreBoardButton->SetMinSize(wxSize(90, 35));
+
+    scoreBoardButton->SetBackgroundColour(wxColour(50,0,51));  // Set background color to blue
+    scoreBoardButton->SetForegroundColour(*wxWHITE);
+
+
+    sizer_hor->Add(scoreBoardButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3);
 
     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(90, 35));
+    sizer_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3);
+
+    leaveGameButton->SetBackgroundColour(wxColour(50,0,51));  // Set background color to blue
+    leaveGameButton->SetForegroundColour(*wxWHITE);
+
+    leaveGameButton->Bind(wxEVT_BUTTON, [gameState](wxCommandEvent &event) {
+        GameController::leaveGame();
+    });
+
 }
 
 
diff --git a/src/client/panels/TrickEstimationPanel.h b/src/client/panels/TrickEstimationPanel.h
index f8d9ef6..bd42b4f 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;
 };
-- 
GitLab


From 26e70b1e03592002275df073bd0b209d8e313e5f Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Sat, 14 Dec 2024 12:29:27 +0100
Subject: [PATCH 08/16] adapt button size

---
 src/client/panels/MainGamePanelWizard.cpp  | 2 +-
 src/client/panels/TrickEstimationPanel.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp
index 64b1fb6..726b090 100644
--- a/src/client/panels/MainGamePanelWizard.cpp
+++ b/src/client/panels/MainGamePanelWizard.cpp
@@ -190,7 +190,7 @@ void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_sta
         });
 
         wxButton *leaveGameButton = new wxButton(panel, wxID_ANY, "Leave Game");
-        leaveGameButton->SetMinSize(wxSize(90, 35));
+        leaveGameButton->SetMinSize(wxSize(110, 43));
         sizer_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3);
 
         leaveGameButton->SetFont(magicalFont);
diff --git a/src/client/panels/TrickEstimationPanel.cpp b/src/client/panels/TrickEstimationPanel.cpp
index 14bb384..e661ccf 100644
--- a/src/client/panels/TrickEstimationPanel.cpp
+++ b/src/client/panels/TrickEstimationPanel.cpp
@@ -132,7 +132,7 @@ void TrickEstimationPanel::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_st
     });
 
     wxButton *leaveGameButton = new wxButton(panel, wxID_ANY, "Leave Game");
-    leaveGameButton->SetMinSize(wxSize(90, 35));
+    leaveGameButton->SetMinSize(wxSize(110, 43));
     sizer_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3);
 
     leaveGameButton->SetFont(magicalFontTrick);
-- 
GitLab


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 09/16] 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


From da7c7fb6354f7bc8f2cb18b4874fcd7f63c1a419 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Sun, 15 Dec 2024 00:32:24 +0100
Subject: [PATCH 10/16] leave game early works now

---
 src/common/game_state/game_state.cpp | 37 +++++++++-------------------
 src/server/game_instance.cpp         | 12 ++++++++-
 src/server/request_handler.cpp       | 31 +++++++++++------------
 3 files changed, 37 insertions(+), 43 deletions(-)

diff --git a/src/common/game_state/game_state.cpp b/src/common/game_state/game_state.cpp
index 458294a..78a0dd9 100644
--- a/src/common/game_state/game_state.cpp
+++ b/src/common/game_state/game_state.cpp
@@ -453,35 +453,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)
 {
-    // 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;
+    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);
+            }
+            _players.erase(_players.begin() + idx);
+            return true;
+        } else {
+            return finish_game(err);
         }
-    }
-    std::cout << "Loop ended" << std::endl;
-
-    if (leaving_player == nullptr) {
+    } else {
         err = "Could not leave game, as the requested player was not found in that game.";
         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)
diff --git a/src/server/game_instance.cpp b/src/server/game_instance.cpp
index 9c844c0..38d1ad6 100644
--- a/src/server/game_instance.cpp
+++ b/src/server/game_instance.cpp
@@ -75,6 +75,15 @@ 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("");
+        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);
@@ -82,7 +91,8 @@ bool game_instance::try_remove_player(player *player, std::string &err) {
         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)){
+    */
+    //}// 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);
diff --git a/src/server/request_handler.cpp b/src/server/request_handler.cpp
index c28844c..081e78c 100644
--- a/src/server/request_handler.cpp
+++ b/src/server/request_handler.cpp
@@ -129,26 +129,23 @@ request_response* request_handler::handle_request(const client_request* const re
             // ##################### LEAVE GAME #####################  //
         case RequestType::leave_game:
             {
-
-
                 // 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)) {
-                    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);
+                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);
+                        }
 
-                    //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 {
-                    err = "Player was found neither in any game nor in lookup table.";
+                    }
+                } // 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);
                 }
             }
-- 
GitLab


From 67dee97c3af5709c56916c8d775459d72f0e997b Mon Sep 17 00:00:00 2001
From: hwinter <hwinter@student.ethz.ch>
Date: Sun, 15 Dec 2024 10:16:43 +0100
Subject: [PATCH 11/16] leave  game in lobby

---
 src/client/panels/MainGamePanelWizard.cpp | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp
index 39f2d4f..f17e836 100644
--- a/src/client/panels/MainGamePanelWizard.cpp
+++ b/src/client/panels/MainGamePanelWizard.cpp
@@ -159,9 +159,6 @@ void MainGamePanelWizard::buildGameState(game_state* gameState, player* me)
     // show button to display score board
     this->buildScoreLeaveButtons(sizer, gameState);
 
-    // show button to leave game
-    // this->buildLeaveGameButton(sizer, gameState);
-
     // update Layout
     this->Layout();
 }
@@ -170,12 +167,13 @@ void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_sta
     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);
-        auto sizer_hor = new wxBoxSizer(wxHORIZONTAL);
-        sizer_vert->Add(sizer_hor, 1, wxALIGN_LEFT);
+    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_hor->Add(scoreBoardButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3);
@@ -188,7 +186,7 @@ void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_sta
             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_hor->Add(leaveGameButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3);
@@ -200,8 +198,6 @@ void MainGamePanelWizard::buildScoreLeaveButtons(wxGridBagSizer *sizer, game_sta
         leaveGameButton->Bind(wxEVT_BUTTON, [gameState](wxCommandEvent &event) {
             GameController::leaveGame();
         });
-    }
-
 }
 
 /*
-- 
GitLab


From a56889d124d38ecbb15a257478ad09155b519cd6 Mon Sep 17 00:00:00 2001
From: hwinter <hwinter@student.ethz.ch>
Date: Sun, 15 Dec 2024 10:25:09 +0100
Subject: [PATCH 12/16] buttons adjusted

---
 src/client/panels/MainGamePanelWizard.cpp  | 4 ++--
 src/client/panels/TrickEstimationPanel.cpp | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp
index f17e836..9d8f3b1 100644
--- a/src/client/panels/MainGamePanelWizard.cpp
+++ b/src/client/panels/MainGamePanelWizard.cpp
@@ -176,7 +176,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_VERTICAL | wxALL, 3);
+        sizer_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3);
 
         scoreBoardButton->SetFont(magicalFont);
         scoreBoardButton->SetForegroundColour(wxColour(225, 225, 225)); // Set button text color
@@ -189,7 +189,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_VERTICAL | wxALL, 3);
+        sizer_vert->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 79e7092..a29ca2b 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_VERTICAL | wxALL, 3);
+    sizer_vert->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_VERTICAL | wxALL, 3);
+    sizer_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3);
 
     leaveGameButton->SetFont(magicalFontTrick);
     leaveGameButton->SetBackgroundColour(wxColour(50,0,51));  // Set background color to blue
-- 
GitLab


From 6811d6bcb70b784808799909837d5c5665336af7 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Sun, 15 Dec 2024 12:45:36 +0100
Subject: [PATCH 13/16] game can now also be left when game has not started yet

---
 src/client/GameController.cpp             |  7 ++++++-
 src/client/GameController.h               |  1 +
 src/client/panels/MainGamePanelWizard.cpp | 14 ++++++++++---
 src/common/game_state/game_state.cpp      |  1 +
 src/common/game_state/player/player.cpp   | 25 +++++++++++++++++++++--
 src/common/game_state/player/player.h     | 16 +++++++++++++++
 6 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/src/client/GameController.cpp b/src/client/GameController.cpp
index 40522af..d040d52 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 90310f6..4494b48 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 03c6006..f9b2eac 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 845f157..e2295a1 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 2efef60..c33546f 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 1eb41bd..3a1f159 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.
-- 
GitLab


From 70469c2854abc65a64e43a98e15caad3996dd073 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Sun, 15 Dec 2024 12:52:03 +0100
Subject: [PATCH 14/16] fixed wxwidget error with vertical sizers

---
 src/client/panels/TrickEstimationPanel.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/client/panels/TrickEstimationPanel.cpp b/src/client/panels/TrickEstimationPanel.cpp
index 581df62..102d2de 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_vert->Add(scoreBoardButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3);
+    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
@@ -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_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3);
+    sizer_vert->Add(leaveGameButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 3);
 
     leaveGameButton->SetFont(magicalFontTrick);
     leaveGameButton->SetBackgroundColour(wxColour(50,0,51));  // Set background color to blue
-- 
GitLab


From a1c548d8602c1b3c9229eb44d18e775c9ca5609c Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Sun, 15 Dec 2024 13:32:44 +0100
Subject: [PATCH 15/16] adapt game state test to make sure it still runs even
 though new object was added to game state

---
 src/common/game_state/game_state.cpp |  6 +++---
 unit-tests/game_state.cpp            | 26 +++++++++++++++++++-------
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/common/game_state/game_state.cpp b/src/common/game_state/game_state.cpp
index e2295a1..625c5f8 100644
--- a/src/common/game_state/game_state.cpp
+++ b/src/common/game_state/game_state.cpp
@@ -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/unit-tests/game_state.cpp b/unit-tests/game_state.cpp
index 6954e44..c5032b8 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;
-- 
GitLab


From 33d797ab64c52d3126a7552cd7c9d31a721d1294 Mon Sep 17 00:00:00 2001
From: marie3003 <marie.viktoria.becker@gmail.com>
Date: Sun, 15 Dec 2024 13:35:26 +0100
Subject: [PATCH 16/16] remove prints

---
 src/client/panels/MainGamePanelWizard.cpp  | 3 ---
 src/client/panels/TrickEstimationPanel.cpp | 1 -
 2 files changed, 4 deletions(-)

diff --git a/src/client/panels/MainGamePanelWizard.cpp b/src/client/panels/MainGamePanelWizard.cpp
index f9b2eac..8aa0f92 100644
--- a/src/client/panels/MainGamePanelWizard.cpp
+++ b/src/client/panels/MainGamePanelWizard.cpp
@@ -98,14 +98,12 @@ 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 if (me->has_left_game() == true)
     {
-        //GameController::showError("Left Game", "You have left the game.");
         GameController::closeGameWindow();
         return;
     }
@@ -316,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/TrickEstimationPanel.cpp b/src/client/panels/TrickEstimationPanel.cpp
index 102d2de..c5c88ea 100644
--- a/src/client/panels/TrickEstimationPanel.cpp
+++ b/src/client/panels/TrickEstimationPanel.cpp
@@ -160,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);
 
 
-- 
GitLab