From 5ca49f7249ac9f9a4fd25c8cac67e9b3f5bc9bd4 Mon Sep 17 00:00:00 2001
From: "Anders H. Rebner" <anderhre@stud.ntnu.no>
Date: Thu, 22 Apr 2021 17:09:10 +0200
Subject: [PATCH] Leave-button, cLobbyLeave uses playerId, server lobby
 hasStarted boolean++

---
 .../game/controllers/GameController.java      |  12 ++-
 .../game/controllers/PlayerController.java    |   2 +-
 .../src/com/mygdx/game/controllers/Utils.kt   |  19 ----
 .../controllers/commands/cLobbyLeave.java     |  51 ++++++---
 .../core/src/com/mygdx/game/model/Game.kt     |  20 +++-
 .../core/src/com/mygdx/game/model/GameMode.kt |   4 +-
 .../core/src/com/mygdx/game/model/Lobby.java  |  12 +++
 .../src/com/mygdx/game/views/MenuView.java    |   2 +-
 .../src/com/mygdx/game/views/PlayView.java    |  32 +++++-
 .../mygdx/game/views/tokens/StarPiece.java    | 101 ++++++++++--------
 .../game/controller/NetworkController.java    |   2 +
 .../controller/commands/cLobbyGetList.java    |  12 +++
 .../game/controller/commands/cLobbyLeave.java |  26 +++--
 .../controller/commands/cSetPlayerReady.java  |   1 +
 .../game/controller/commands/cStartGame.java  |   1 -
 .../core/src/com/mygdx/game/model/Lobby.java  |   9 ++
 16 files changed, 202 insertions(+), 104 deletions(-)

diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/GameController.java b/CheckersClient/core/src/com/mygdx/game/controllers/GameController.java
index 7fe618e..4abcc8f 100644
--- a/CheckersClient/core/src/com/mygdx/game/controllers/GameController.java
+++ b/CheckersClient/core/src/com/mygdx/game/controllers/GameController.java
@@ -35,6 +35,7 @@ public class GameController {
         this.view.initializePieces(this.model.getStartFieldCoordinates());
         this.view.placePlayerNames(usedBoardSlots, playerNameTextFieldCoordinates);
         this.view.placeTurnIndicator(playerNameTextFieldCoordinates.get(this.model.getPlayerTurnSlot()));
+        this.view.placeLeaveButton();
     }
 
     public void handleClick(float x, float y) {
@@ -95,12 +96,21 @@ public class GameController {
             if (player.getID() == playerId) {
                 playerIndex = players.indexOf(player);
                 this.view.setPlayerFinished(playerIndex, place);
+                break;
             }
         }
     }
 
     public void setGameFinished() {
         this.view.removeTurnIndicator();
-        this.view.placeHomeButton();
+        this.view.placeExitButton();
+    }
+
+    // External, called by CLobbyLeave command
+    public void setPlayerLeftMidGame(int playerId) {
+        System.out.println("Other player left, id: " + playerId);
+        model.setPlayerLeftMidGame(playerId);
+        setPlayerFinished(playerId, -1);
+        this.view.placeTurnIndicator(playerNameTextFieldCoordinates.get(model.getPlayerTurnSlot()));
     }
 }
diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/PlayerController.java b/CheckersClient/core/src/com/mygdx/game/controllers/PlayerController.java
index 04f9ecf..e4a4c4e 100644
--- a/CheckersClient/core/src/com/mygdx/game/controllers/PlayerController.java
+++ b/CheckersClient/core/src/com/mygdx/game/controllers/PlayerController.java
@@ -67,7 +67,7 @@ public class PlayerController {
 
     public void joinLobby(int id){ sendCommand(new cLobbyJoin(id)); }
 
-    public void leaveLobby(int id) { sendCommand(new cLobbyLeave(id)); }
+    public void leaveLobby(int id) { sendCommand(new cLobbyLeave(id, getPlayer().getID())); }
 
     public Lobby getLobby(){ return lobby; }
 
diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/Utils.kt b/CheckersClient/core/src/com/mygdx/game/controllers/Utils.kt
index fec97eb..cf38da2 100644
--- a/CheckersClient/core/src/com/mygdx/game/controllers/Utils.kt
+++ b/CheckersClient/core/src/com/mygdx/game/controllers/Utils.kt
@@ -1,6 +1,5 @@
 package com.mygdx.game.controllers
 
-import com.badlogic.gdx.math.Vector2
 import com.badlogic.gdx.math.Vector3
 import java.util.*
 import kotlin.math.roundToInt
@@ -8,13 +7,6 @@ import kotlin.math.sqrt
 
 // https://stackoverflow.com/questions/2459402/hexagonal-grid-coordinates-to-pixel-coordinates
 
-fun cubeToPixel(x: Float, y: Float, z: Float, hexSideLength: Float = 1F): Array<Float> {
-    val pixelX = sqrt(3F) * hexSideLength * ( (z / 2F) + x )
-    val pixelY = 3F/2F * hexSideLength * z
-
-    return arrayOf(pixelX, pixelY)
-}
-
 fun cubeToPixel(vector: Vector3, hexSideLength: Float = 1F): Array<Float> {
     val pixelX = sqrt(3F) * hexSideLength * ( (vector.z / 2F) + vector.x )
     val pixelY = 3F/2F * hexSideLength * vector.z
@@ -30,17 +22,6 @@ fun pixelToCube(x: Float, y: Float, hexSideLength: Float = 1F) : Vector3 {
     return Vector3(cubeX.toFloat(), cubeY.toFloat(), cubeZ.toFloat())
 }
 
-fun pixelToCube(vector: Vector2, hexSideLength: Float = 1F) : Array<Float> {
-    val x = vector.x
-    val y = vector.y
-
-    val cubeX = (sqrt(3F) / 3F * x - y / 3F) / hexSideLength
-    val cubeY = -(sqrt(3F) / 3F * x + y / 3F) / hexSideLength
-    val cubeZ = 2F / 3F * y / hexSideLength
-
-    return arrayOf(cubeX, cubeY, cubeZ)
-}
-
 fun cubeCoordinateSetToPixel(cubeCoordinateSet: List<List<Vector3>>, hexSideLength: Float = 1F): List<List<Array<Float>>> {
     // Convert to pixel coordinates
     val startFieldCoordinatesPixel: MutableList<List<Array<Float>>> = ArrayList()
diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/commands/cLobbyLeave.java b/CheckersClient/core/src/com/mygdx/game/controllers/commands/cLobbyLeave.java
index 21c47b8..eda5266 100644
--- a/CheckersClient/core/src/com/mygdx/game/controllers/commands/cLobbyLeave.java
+++ b/CheckersClient/core/src/com/mygdx/game/controllers/commands/cLobbyLeave.java
@@ -1,33 +1,52 @@
 package com.mygdx.game.controllers.commands;
 
 import com.esotericsoftware.kryonet.Connection;
+import com.mygdx.game.controllers.GameController;
 import com.mygdx.game.controllers.PlayerController;
 import com.mygdx.game.model.Lobby;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class cLobbyLeave extends Command{
 
     public cLobbyLeave() { super("cLobbyLeave"); }
 
-    public cLobbyLeave(int id) { super("cLobbyLeave", (Integer) id); }
+    int lobbyId;
+    int playerId;
+
+    public cLobbyLeave(int id, int playerId) {
+        super("cLobbyLeave");
+        this.lobbyId = id;
+        this.playerId = playerId;
+
+        ArrayList<Object> data = new ArrayList<Object>();
+        data.add(lobbyId);
+        data.add(playerId);
+
+        this.data = data;
+    }
 
     @Override
     public void execute(PlayerController playerController, Connection connection){
-        if(data instanceof Lobby){
-            Lobby lobby = (Lobby) data;
-            if(lobby.getID() != -1){
-                if (lobby.getPlayersID().contains((Integer) connection.getID())) {
-                    //Somebody else left
-                    System.out.println("Somebody left the lobby");
-                    playerController.setLobby(lobby);
-                }
-                else{
-                    //The current player left
-                    playerController.setLobby(new Lobby(-1));
-                    System.out.println("Request to leave lobby successful");
+        if (data instanceof ArrayList) {
+            List<Object> receivedData = (ArrayList<Object>) data;
+
+            lobbyId = (int) receivedData.get(0);
+            playerId = (int) receivedData.get(1);
+
+            if (playerId == playerController.getPlayer().getID()) {
+                System.out.println("Request to leave lobby successful");
+                playerController.setLobby(new Lobby(-1));
+            } else {
+                System.out.println("Somebody left the lobby");
+
+                GameController gameController = playerController.getGameController();
+                if (gameController != null) {
+                    gameController.setPlayerLeftMidGame(playerId);
                 }
-            }
-            else{
-                System.out.println("Received leaveLobby command with an error");
+
+                playerController.getLobby().removePlayer(playerId);
             }
         }
     }
diff --git a/CheckersClient/core/src/com/mygdx/game/model/Game.kt b/CheckersClient/core/src/com/mygdx/game/model/Game.kt
index 07e39f0..6050d10 100644
--- a/CheckersClient/core/src/com/mygdx/game/model/Game.kt
+++ b/CheckersClient/core/src/com/mygdx/game/model/Game.kt
@@ -11,6 +11,7 @@ class Game(gameState: GameState, playerIds: LinkedHashSet<Int>) {
     private var playerTurnIndex: Int = 0 // TODO: Random from server
     private var playerTurnSlot: Int
     private var playerFinishedIds: List<Int> = listOf()
+    private var playerLeftIds: List<Int> = listOf()
     private var usedBoardSlots: List<Int>
 
     init {
@@ -35,7 +36,7 @@ class Game(gameState: GameState, playerIds: LinkedHashSet<Int>) {
         return this.gameState.getBoardState().fields[cubeCoordinates]?.hasPiece() == true
     }
 
-    fun isLegalMove(fromCoordinates: Vector3, toCoordinates: Vector3): Boolean {
+    private fun isLegalMove(fromCoordinates: Vector3, toCoordinates: Vector3): Boolean {
         return getGameState()?.getGameMode()?.getPossibleMoves(fromCoordinates)?.contains(toCoordinates) ?: false
     }
 
@@ -55,7 +56,7 @@ class Game(gameState: GameState, playerIds: LinkedHashSet<Int>) {
                         this.gameState.setWinner(playerId)
                     }
                     // All players are finished
-                    if (playerFinishedIds.size == playerIds.size) {
+                    if (playerFinishedIds.size == playerIds.size - playerLeftIds.size) {
                         gameController.setGameFinished()
                         this.gameState.setFinished()
                     }
@@ -88,7 +89,7 @@ class Game(gameState: GameState, playerIds: LinkedHashSet<Int>) {
                 playerTurnIndex = 0
             }
             playerTurnId = playerIds.elementAt(playerTurnIndex)
-        } while (playerFinishedIds.contains(playerTurnId) && playerFinishedIds.size < playerIds.size)
+        } while (playerFinishedIds.contains(playerTurnId) && thereArePlayersLeft() || playerLeftIds.contains(playerTurnId))
     }
 
     fun getPieceOwnerId(coordinates: Vector3): Int {
@@ -124,4 +125,15 @@ class Game(gameState: GameState, playerIds: LinkedHashSet<Int>) {
     fun getPlayerNameCoordinates(hex_side_length: Float): List<List<Float>> {
         return gameState.getRules().getPlayerNameCoordinates(hex_side_length)
     }
-}
\ No newline at end of file
+
+    fun setPlayerLeftMidGame(playerId: Int) {
+        playerLeftIds = playerLeftIds + playerId
+        if (playerTurnId == playerId) {
+            nextPlayer()
+        }
+    }
+
+    private fun thereArePlayersLeft(): Boolean {
+        return playerFinishedIds.size < playerIds.size - playerLeftIds.size
+    }
+}
diff --git a/CheckersClient/core/src/com/mygdx/game/model/GameMode.kt b/CheckersClient/core/src/com/mygdx/game/model/GameMode.kt
index a9d3a57..9f0d97b 100644
--- a/CheckersClient/core/src/com/mygdx/game/model/GameMode.kt
+++ b/CheckersClient/core/src/com/mygdx/game/model/GameMode.kt
@@ -118,8 +118,8 @@ class GameMode(rules:AbstractRules, board:AbstractBoard) {
     }
 
     fun getPossibleMoves(position: Vector3): ArrayList<Vector3> {
-        var possibleMoves: ArrayList<Vector3> = arrayListOf()
-        zigzagAlgorithm(position, possibleMoves, this.rules.moveRange , this.rules?.jumpRange)
+        val possibleMoves: ArrayList<Vector3> = arrayListOf()
+        zigzagAlgorithm(position, possibleMoves, this.rules.moveRange , this.rules.jumpRange)
         return possibleMoves
     }
 }
diff --git a/CheckersClient/core/src/com/mygdx/game/model/Lobby.java b/CheckersClient/core/src/com/mygdx/game/model/Lobby.java
index a6ba03f..a7d2eef 100644
--- a/CheckersClient/core/src/com/mygdx/game/model/Lobby.java
+++ b/CheckersClient/core/src/com/mygdx/game/model/Lobby.java
@@ -70,6 +70,18 @@ public class Lobby {
         return set;
     }
 
+    public void removePlayer(int playerID) {
+        Player leavingPlayer = null;
+        for (Player player : players) {
+            if (player.getID() == playerID) {
+                leavingPlayer = player;
+            }
+        }
+        if (leavingPlayer != null) {
+            players.remove(leavingPlayer);
+        }
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
diff --git a/CheckersClient/core/src/com/mygdx/game/views/MenuView.java b/CheckersClient/core/src/com/mygdx/game/views/MenuView.java
index 4aad563..7bdd794 100644
--- a/CheckersClient/core/src/com/mygdx/game/views/MenuView.java
+++ b/CheckersClient/core/src/com/mygdx/game/views/MenuView.java
@@ -258,7 +258,7 @@ public class MenuView extends View{
         }
 
         stage.draw();
-        drawGrid();
+        //drawGrid();
     }
 
     @Override
diff --git a/CheckersClient/core/src/com/mygdx/game/views/PlayView.java b/CheckersClient/core/src/com/mygdx/game/views/PlayView.java
index c7238af..df0823f 100644
--- a/CheckersClient/core/src/com/mygdx/game/views/PlayView.java
+++ b/CheckersClient/core/src/com/mygdx/game/views/PlayView.java
@@ -120,6 +120,8 @@ public class PlayView extends View{
         starPieceHead = (Texture) assetManager.get(PlayAssets.STAR_PIECE_HEAD.path, PlayAssets.STAR_PIECE_HEAD.classType);
         starPieceHeadBorder = (Texture) assetManager.get(PlayAssets.STAR_PIECE_HEAD_BORDER.path, PlayAssets.STAR_PIECE_HEAD_BORDER.classType);
 
+        placeLeaveButton();
+
         this.pieces = new ConcurrentHashMap<>();
     }
 
@@ -252,30 +254,34 @@ public class PlayView extends View{
         // Create and place place-field
         TextField placeField;
 
-        if (place <= 3) {
+        if (place >= 0 && place <= 3) {
             List<String> placeStrings= Arrays.asList("st", "nd", "rd");
             placeField = new TextField(place + placeStrings.get(place - 1), skin);
             placeField.setColor(PODIUM_COLORS.get(place - 1));
-        } else {
+        } else if (place > 3){
             placeField = new TextField(place + "th", skin);
             placeField.setColor(new Color(205/255F, 127/255F, 50/255F, 1));
+        } else {
+            placeField = new TextField("dnf", skin);
+            placeField.setColor(new Color(205/255F, 127/255F, 50/255F, 1));
         }
+
         placeField.setSize(115, 65);
         placeField.setPosition(playerNameField.getX() + playerNameField.getWidth() - placeField.getWidth(), playerNameField.getY());
 
         stage.addActor(placeField);
     }
 
-    public void placeHomeButton() {
+    public void placeExitButton() {
         TextButton homeButton = new TextButton("Exit", skin, "small");
         homeButton.setPosition(Gdx.graphics.getWidth() / 2F - homeButton.getWidth() / 2F, Gdx.graphics.getHeight() / 2F - homeButton.getHeight() / 2F);
 
         homeButton.addListener(new InputListener(){
             @Override
             public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
-                startFadeout = true;
                 playerController.setLobbyPlayerReady(false);
                 playerController.leaveLobby(playerController.getLobby().getID());
+                startFadeout = true;
                 return true;
             }
         });
@@ -283,6 +289,23 @@ public class PlayView extends View{
         stage.addActor(homeButton);
     }
 
+    public void placeLeaveButton() {
+        TextButton leaveButton = new TextButton("Leave", skin, "small");
+        leaveButton.setPosition(Gdx.graphics.getWidth() / 2F + (boardImage.getWidth() * boardImage.getScaleX()) / 2F, Gdx.graphics.getHeight() - 3F * hex_side_length - leaveButton.getHeight() / 2F);
+
+        leaveButton.addListener(new InputListener(){
+            @Override
+            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
+                playerController.setLobbyPlayerReady(false);
+                playerController.leaveLobby(playerController.getLobby().getID());
+                startFadeout = true;
+                return true;
+            }
+        });
+
+        stage.addActor(leaveButton);
+    }
+
     @Override
     public void fadeIn(float dt) {
         stage.getBatch().begin();
@@ -310,7 +333,6 @@ public class PlayView extends View{
         if(fadeOutAlpha >= 1){
             stage.clear();
             startFadeout = false;
-            //gvm.set(new MenuView(gvm, playerController, assetManager, stage, skin));
             gvm.set(new LobbyView(gvm, playerController, assetManager, stage, skin, Constants.AVAILABLEAVATARSHASHMAP, null));
         }
     }
diff --git a/CheckersClient/core/src/com/mygdx/game/views/tokens/StarPiece.java b/CheckersClient/core/src/com/mygdx/game/views/tokens/StarPiece.java
index 418ffd4..b2b58a0 100644
--- a/CheckersClient/core/src/com/mygdx/game/views/tokens/StarPiece.java
+++ b/CheckersClient/core/src/com/mygdx/game/views/tokens/StarPiece.java
@@ -7,27 +7,31 @@ import com.badlogic.gdx.graphics.g2d.Batch;
 public class StarPiece {
 
     private final Color color;
-    private Texture base;
-    private Texture baseBorder;
-    private float xPos;
-    private float yPos;
+    private final Texture base;
+    private final Texture baseBorder;
 
-    private Texture mast;
-    private Texture mastBorder;
+    private final Texture mast;
+    private final Texture mastBorder;
 
-    private Texture head;
-    private Texture headBorder;
+    private final Texture head;
+    private final Texture headBorder;
     private boolean rotateHead;
     private float headRotation = 1;
 
     Float scale_factor;
 
+    private float baseXPos;
+    private float baseYPos;
+
+    private float localHeadXPos;
+    private float localHeadYPos;
+
+    private float localMastXPos;
+    private float localMastYPos;
+
     public StarPiece (float scale_factor, float xPos, float yPos, Color color, Texture base, Texture baseBorder, Texture mast, Texture mastBorder, Texture head, Texture headBorder){
 
-        this.xPos = xPos;
-        this.yPos = yPos;
         this.color = color;
-
         this.base = base;
         this.baseBorder = baseBorder;
         this.mast = mast;
@@ -37,51 +41,55 @@ public class StarPiece {
         this.rotateHead=false;
 
         this.scale_factor = scale_factor;
+
+        setX(xPos);
+        setY(yPos);
+
     }
 
+
     public void draw(Batch sb){
         Color sbColor = sb.getColor();
         sb.begin();
         sb.setColor(color);
-        sb.draw(base, xPos, yPos, base.getWidth() * scale_factor, base.getHeight() * scale_factor);
+        sb.draw(base, baseXPos, baseYPos, base.getWidth() * scale_factor, base.getHeight() * scale_factor);
         sb.setColor(Color.BLACK);
-        sb.draw(baseBorder, xPos, yPos, baseBorder.getWidth() * scale_factor, baseBorder.getHeight() * scale_factor);
+        sb.draw(baseBorder, baseXPos, baseYPos, baseBorder.getWidth() * scale_factor, baseBorder.getHeight() * scale_factor);
 
         sb.setColor(color);
-        sb.draw(mast, xPos+ (base.getWidth() * scale_factor)/2-(mast.getWidth() * scale_factor)/2, yPos+(base.getHeight() * scale_factor)*0.35f, mast.getWidth() * scale_factor, mast.getHeight() * scale_factor);
+        sb.draw(mast, localMastXPos, localMastYPos, mast.getWidth() * scale_factor, mast.getHeight() * scale_factor);
         sb.setColor(Color.BLACK);
-        sb.draw(mastBorder, xPos+(base.getWidth() * scale_factor)/2-(mast.getWidth()*scale_factor)/2, yPos+(base.getHeight() * scale_factor)*0.35f, mastBorder.getWidth() * scale_factor, mastBorder.getHeight() * scale_factor);
+        sb.draw(mastBorder, localMastXPos, localMastYPos, mast.getWidth() * scale_factor, mast.getHeight() * scale_factor);
 
         if(rotateHead){
             sb.setColor(color);
-
             sb.draw(head,
-             xPos+(base.getWidth() * scale_factor)/2-(head.getWidth()*scale_factor)/2,
-            yPos+(base.getHeight()*scale_factor)-(head.getWidth()*scale_factor)/2,
-            head.getWidth()*scale_factor/2,
-            head.getHeight()*scale_factor/2,
-            head.getWidth()*scale_factor,
-            head.getHeight()*scale_factor,
-            1F,
-            1F,
-            headRotation++,
-            0,
-            0,
+                    localHeadXPos,
+                    localHeadYPos,
+                    head.getWidth()*scale_factor/2,
+                    head.getHeight()*scale_factor/2,
+                    head.getWidth()*scale_factor,
+                    head.getHeight()*scale_factor,
+                    1f,
+                    1f,
+                    headRotation++,
+                    0,
+                    0,
                     head.getWidth(),
                     head.getHeight(),
-            false,
-            false);
+                    false,
+                    false);
 
             sb.setColor(Color.BLACK);
             sb.draw(headBorder,
-                    xPos+(base.getWidth()*scale_factor)/2-(head.getWidth()*scale_factor)/2,
-                    yPos+(base.getHeight()*scale_factor)-(head.getWidth()*scale_factor)/2,
+                    localHeadXPos,
+                    localHeadYPos,
                     head.getWidth()*scale_factor/2,
                     head.getHeight()*scale_factor/2,
                     head.getWidth()*scale_factor,
                     head.getHeight()*scale_factor,
-                    1F,
-                    1F,
+                    1f,
+                    1f,
                     headRotation++,
                     0,
                     0,
@@ -92,9 +100,9 @@ public class StarPiece {
         }
         else{
             sb.setColor(color);
-            sb.draw(head, xPos+(base.getWidth() * scale_factor)/2-(head.getWidth() * scale_factor)/2, yPos+(base.getHeight() * scale_factor)-(head.getWidth() * scale_factor)/2, head.getWidth() * scale_factor, head.getHeight() * scale_factor);
+            sb.draw(head, localHeadXPos, localHeadYPos, head.getWidth() * scale_factor, head.getHeight() * scale_factor);
             sb.setColor(Color.BLACK);
-            sb.draw(headBorder, xPos+(base.getWidth() * scale_factor)/2-(head.getWidth() * scale_factor)/2, yPos+(base.getHeight() * scale_factor)-(head.getWidth() * scale_factor)/2, headBorder.getWidth() * scale_factor, headBorder.getHeight() * scale_factor);
+            sb.draw(headBorder, localHeadXPos, localHeadYPos, head.getWidth() * scale_factor, head.getHeight() * scale_factor);
         }
 
         sb.setColor(sbColor);
@@ -105,28 +113,29 @@ public class StarPiece {
         this.rotateHead = rotateHead;
     }
 
+
     public void setX(float xPos){
-        this.xPos = xPos;
+        this.baseXPos = xPos;
+        this.localMastXPos = xPos+ (base.getWidth() * scale_factor)/2-(mast.getWidth() * scale_factor)/2;
+        this.localHeadXPos = baseXPos +(base.getWidth() * scale_factor)/2 - (head.getWidth() * scale_factor)/2;
     }
 
     public void setY(float yPos){
-        this.yPos = yPos;
+        this.baseYPos = yPos;
+        this.localMastYPos = yPos+(base.getHeight() * scale_factor)*0.35f;
+        this.localHeadYPos = yPos+(base.getHeight() * scale_factor)-(head.getWidth() * scale_factor)/2;
     }
 
     public float getX(){
-        return xPos;
+        return baseXPos;
     }
 
     public float getY(){
-        return yPos;
+        return baseYPos;
     }
 
-    public float getWidth() { return base.getWidth() * scale_factor;}
-
-    public float getHeight() { return base.getHeight() * scale_factor;}
-
     public void setPosition(float xPos, float yPos){
-        this.xPos = xPos;
-        this.yPos = yPos;
+        setX(xPos);
+        setY(yPos);
     }
-}
+}
\ No newline at end of file
diff --git a/CheckersServer/core/src/com/mygdx/game/controller/NetworkController.java b/CheckersServer/core/src/com/mygdx/game/controller/NetworkController.java
index 69788e3..415e1f5 100644
--- a/CheckersServer/core/src/com/mygdx/game/controller/NetworkController.java
+++ b/CheckersServer/core/src/com/mygdx/game/controller/NetworkController.java
@@ -13,6 +13,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
 
 public class NetworkController {
 
@@ -161,6 +162,7 @@ public class NetworkController {
         kryo.register(cSetPlayerName.class, 27);
         kryo.register(cStartGame.class, 28);
         kryo.register(Vector3.class, 29);
+        kryo.register(List.class, 30);
     }
 
     public NetworkController getNetworkController() { return this; }
diff --git a/CheckersServer/core/src/com/mygdx/game/controller/commands/cLobbyGetList.java b/CheckersServer/core/src/com/mygdx/game/controller/commands/cLobbyGetList.java
index 6ccd56a..abb44e2 100644
--- a/CheckersServer/core/src/com/mygdx/game/controller/commands/cLobbyGetList.java
+++ b/CheckersServer/core/src/com/mygdx/game/controller/commands/cLobbyGetList.java
@@ -6,6 +6,7 @@ import com.mygdx.game.model.Lobby;
 import com.mygdx.game.model.Player;
 
 import java.util.ArrayList;
+import java.util.List;
 
 public class cLobbyGetList extends Command{
 
@@ -14,6 +15,17 @@ public class cLobbyGetList extends Command{
     @Override
     public void execute(NetworkController net, Connection connection){
         data = net.getLobbies();
+
+        // Exclude lobbies where game has already started
+        List<Lobby> startedLobbies = new ArrayList<>();
+
+        for (Lobby lobby : (List<Lobby>) data) {
+            if (lobby.getLobbyGameStarted()) {
+                startedLobbies.add(lobby);
+            }
+        }
+        ((List<Lobby>) data).removeAll(startedLobbies);
+
         System.out.printf("Request to get list of lobbies from Client. Returning: %s \n", data.toString());
         connection.sendTCP(this);
         System.out.println("Number of available lobbies" + net.getLobbies().size());
diff --git a/CheckersServer/core/src/com/mygdx/game/controller/commands/cLobbyLeave.java b/CheckersServer/core/src/com/mygdx/game/controller/commands/cLobbyLeave.java
index d21ef48..d3d16fe 100644
--- a/CheckersServer/core/src/com/mygdx/game/controller/commands/cLobbyLeave.java
+++ b/CheckersServer/core/src/com/mygdx/game/controller/commands/cLobbyLeave.java
@@ -6,26 +6,36 @@ import com.mygdx.game.model.Lobby;
 
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 
 public class cLobbyLeave extends Command{
 
     public cLobbyLeave() { super("cLobbyLeave"); }
 
+    int lobbyId;
+    int playerId;
+
     public cLobbyLeave(Lobby lobby) { super("cLobbyLeave", lobby); }
 
     @Override
     public void execute(NetworkController net, Connection connection){
-        if(data instanceof Integer) {
-            int lobby_id = (int) data;
-            Lobby lobby = net.getLobby(lobby_id);
-            ArrayList<Connection> connections = net.getConnections(lobby);
-            data = net.leaveLobby(connection.getID(),lobby_id);
-            net.getPlayer(connection.getID()).setIsPlayerReady(false);
+        if (data instanceof ArrayList) {
+            List<Object> receivedData = (ArrayList<Object>) data;
+
+            lobbyId = (int) receivedData.get(0);
+            playerId = (int) receivedData.get(1);
+
+            Lobby lobby = net.getLobby(lobbyId);
+
             System.out.printf("Request from Player w. ID: %d to leave Lobby w. ID: %d. Returning Lobby w. ID: %d \n",
-                    connection.getID(), lobby_id, ((Lobby)data).getID());
-            for (Connection c : connections) {
+                    playerId, lobbyId, lobbyId);
+
+            for (Connection c : net.getConnections(lobby)) {
                 c.sendTCP(this);
             }
+
+            net.leaveLobby(playerId, lobbyId);
+            net.getPlayer(playerId).setIsPlayerReady(false);
         }
     }
 }
diff --git a/CheckersServer/core/src/com/mygdx/game/controller/commands/cSetPlayerReady.java b/CheckersServer/core/src/com/mygdx/game/controller/commands/cSetPlayerReady.java
index eb793ad..a3b66e4 100644
--- a/CheckersServer/core/src/com/mygdx/game/controller/commands/cSetPlayerReady.java
+++ b/CheckersServer/core/src/com/mygdx/game/controller/commands/cSetPlayerReady.java
@@ -37,6 +37,7 @@ public class cSetPlayerReady extends Command{
             if(lobby.isFullAndReady()){
                 for (Connection c : net.getConnections(lobby)) {
                     c.sendTCP(new cStartGame());
+                    lobby.setLobbyGameStarted(true);
                 }
                 System.out.printf("Lobby %b is about to start. \n", lobbyID);
             }
diff --git a/CheckersServer/core/src/com/mygdx/game/controller/commands/cStartGame.java b/CheckersServer/core/src/com/mygdx/game/controller/commands/cStartGame.java
index 0b907c8..1cb08f0 100644
--- a/CheckersServer/core/src/com/mygdx/game/controller/commands/cStartGame.java
+++ b/CheckersServer/core/src/com/mygdx/game/controller/commands/cStartGame.java
@@ -2,7 +2,6 @@ package com.mygdx.game.controller.commands;
 
 import com.esotericsoftware.kryonet.Connection;
 import com.mygdx.game.controller.NetworkController;
-import com.mygdx.game.model.Lobby;
 
 public class cStartGame extends Command{
 
diff --git a/CheckersServer/core/src/com/mygdx/game/model/Lobby.java b/CheckersServer/core/src/com/mygdx/game/model/Lobby.java
index 46496c4..e6c6079 100644
--- a/CheckersServer/core/src/com/mygdx/game/model/Lobby.java
+++ b/CheckersServer/core/src/com/mygdx/game/model/Lobby.java
@@ -9,6 +9,7 @@ public class Lobby {
     private String name;
     private int MAX_PLAYERS;
     private ArrayList<Player> players;
+    private boolean lobbyGameStarted = false;
 
     public Lobby() {}
 
@@ -84,6 +85,14 @@ public class Lobby {
         }
     }
 
+    public void setLobbyGameStarted(boolean lobbyGameStarted) {
+        this.lobbyGameStarted = lobbyGameStarted;
+    }
+
+    public Boolean getLobbyGameStarted() {
+        return lobbyGameStarted;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-- 
GitLab