From 9dfbbe330ecf965d2c530ef9d992f3a2a70babf3 Mon Sep 17 00:00:00 2001 From: stefagr <stefagr@stud.ntnu.no> Date: Tue, 20 Apr 2021 06:24:51 +0200 Subject: [PATCH] added more stuff to server --- .../game/controllers/GameController.java | 21 +++- .../game/controllers/NetworkController.java | 22 +++- .../game/controllers/PlayerController.java | 5 +- .../game/controllers/commands/Command.java | 5 +- .../controllers/commands/cUpdateGame.java | 26 +++++ .../src/com/mygdx/game/model/GameState.kt | 1 + .../core/src/com/mygdx/game/model/Lobby.java | 6 + ...le__CheckersServer_desktop_desktop_1_0.xml | 9 ++ CheckersServer/.idea/modules.xml | 2 +- .../core/src/com/mygdx/game/Constants.java | 16 +++ .../game/controller/NetworkController.java | 34 +++++- .../game/controller/commands/Command.java | 5 +- .../controller/commands/cPlayerPieceMove.java | 34 +----- .../game/controller/commands/cUpdateGame.java | 28 +++++ .../core/src/com/mygdx/game/model/Field.kt | 34 ++++++ .../core/src/com/mygdx/game/model/Game.kt | 25 ++++ .../core/src/com/mygdx/game/model/GameMode.kt | 30 +++++ .../src/com/mygdx/game/model/GameState.kt | 57 ++++++++++ .../core/src/com/mygdx/game/model/Lobby.java | 7 ++ .../core/src/com/mygdx/game/model/Piece.kt | 12 ++ .../model/gamemodes/boards/AbstractBoard.kt | 13 +++ .../model/gamemodes/boards/DefaultBoard.kt | 82 ++++++++++++++ .../game/model/gamemodes/boards/Direction.kt | 15 +++ .../model/gamemodes/rules/AbstractRules.kt | 16 +++ .../model/gamemodes/rules/DefaultRules.kt | 107 ++++++++++++++++++ 25 files changed, 568 insertions(+), 44 deletions(-) create mode 100644 CheckersClient/core/src/com/mygdx/game/controllers/commands/cUpdateGame.java create mode 100644 CheckersServer/.idea/libraries/Gradle__CheckersServer_desktop_desktop_1_0.xml create mode 100644 CheckersServer/core/src/com/mygdx/game/Constants.java create mode 100644 CheckersServer/core/src/com/mygdx/game/controller/commands/cUpdateGame.java create mode 100644 CheckersServer/core/src/com/mygdx/game/model/Field.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/Game.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/GameMode.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/GameState.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/Piece.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/AbstractBoard.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/DefaultBoard.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/Direction.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/gamemodes/rules/AbstractRules.kt create mode 100644 CheckersServer/core/src/com/mygdx/game/model/gamemodes/rules/DefaultRules.kt diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/GameController.java b/CheckersClient/core/src/com/mygdx/game/controllers/GameController.java index cd4d843..2a86a2f 100644 --- a/CheckersClient/core/src/com/mygdx/game/controllers/GameController.java +++ b/CheckersClient/core/src/com/mygdx/game/controllers/GameController.java @@ -1,8 +1,11 @@ package com.mygdx.game.controllers; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.Vector3; import com.mygdx.game.controllers.commands.cPlayerPieceMove; import com.mygdx.game.model.Game; +import com.mygdx.game.model.GameState; +import com.mygdx.game.model.Lobby; import com.mygdx.game.model.Player; import com.mygdx.game.views.PlayView; import com.mygdx.game.views.tokens.StarPiece; @@ -19,7 +22,7 @@ public class GameController { private final PlayerController playerController; private final List<List<Float>> playerNameTextFieldCoordinates; - public GameController(Game model, PlayView view, PlayerController playerController) { + public GameController(Game model, PlayView view, final PlayerController playerController) { this.model = model; this.view = view; this.playerController = playerController; @@ -35,6 +38,19 @@ public class GameController { this.view.initializePieces(this.model.getStartFieldCoordinates()); this.view.placePlayerNames(usedBoardSlots, playerNameTextFieldCoordinates); this.view.placeTurnIndicator(playerNameTextFieldCoordinates.get(this.model.getPlayerTurnSlot())); + + playerController.getLobby().setGame(model); //set game in playerController + playerController.updateGame(); //send to server + Thread thread = new Thread(){ + public void run(){ + while (playerController.getLastCommand() == null) { + System.out.println("Waiting for game update"); + } + GameState gs = (GameState) playerController.getLobby().getGame(); + System.out.println("gameUpdate received: " + gs); + } + }; + thread.start(); } public void handleClick(float x, float y) { @@ -62,7 +78,10 @@ public class GameController { this.view.movePiece(activePiece, cubeCoordinates); activePiece.setRotateHead(false); activePiece = null; + playerController.getNetWorkController().sendToServer(new cPlayerPieceMove(previousCoordinateClicked, cubeCoordinates, playerController.getLobby().getID(), playerController.getPlayer().getID())); + //playerController.updateGame(); + previousCoordinateClicked = null; this.view.placeTurnIndicator(playerNameTextFieldCoordinates.get(this.model.getPlayerTurnSlot())); diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/NetworkController.java b/CheckersClient/core/src/com/mygdx/game/controllers/NetworkController.java index 92da9b2..c81de43 100644 --- a/CheckersClient/core/src/com/mygdx/game/controllers/NetworkController.java +++ b/CheckersClient/core/src/com/mygdx/game/controllers/NetworkController.java @@ -5,8 +5,15 @@ import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryonet.Client; import com.mygdx.game.controllers.commands.Command; import com.mygdx.game.controllers.commands.*; +import com.mygdx.game.model.DefaultBoard; +import com.mygdx.game.model.Field; +import com.mygdx.game.model.Game; +import com.mygdx.game.model.GameMode; +import com.mygdx.game.model.GameState; import com.mygdx.game.model.Lobby; +import com.mygdx.game.model.Piece; import com.mygdx.game.model.Player; +import com.mygdx.game.model.gamemodes.rules.DefaultRules; import java.io.IOException; import java.util.ArrayList; @@ -23,7 +30,8 @@ public class NetworkController { this.client = new Client(); client.start(); try { - String IP4_LAN_ADDRESS = "192.168.0.136"; //122 //"192.168.87.20"; + //192.168.0.136 + String IP4_LAN_ADDRESS = "192.168.10.154"; //122 //"192.168.87.20"; client.connect(10000, IP4_LAN_ADDRESS, 54555, 54777); } catch (IOException e) { e.printStackTrace(); @@ -53,6 +61,18 @@ public class NetworkController { kryo.register(cSetPlayerName.class, 27); kryo.register(cStartGame.class, 28); kryo.register(Vector3.class, 29); + kryo.register(cUpdateGame.class, 30); + kryo.register(Game.class, 31); + kryo.register(GameState.class, 32); + kryo.register(GameMode.class, 33); + kryo.register(Piece.class, 34); + kryo.register(Field.class, 35); + kryo.register(DefaultBoard.class, 36); + kryo.register(DefaultRules.class, 37); + kryo.register(java.util.HashMap.class, 38); + kryo.register(java.util.Arrays.asList().getClass(), 39); + kryo.register(kotlin.collections.EmptyList.class, 40); //works anyway ignore + kryo.register(java.util.LinkedHashSet.class, 41); } public Client getClient() { return client; } diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/PlayerController.java b/CheckersClient/core/src/com/mygdx/game/controllers/PlayerController.java index 04f9ecf..6ce3dd2 100644 --- a/CheckersClient/core/src/com/mygdx/game/controllers/PlayerController.java +++ b/CheckersClient/core/src/com/mygdx/game/controllers/PlayerController.java @@ -5,9 +5,6 @@ import com.esotericsoftware.kryonet.Listener; import com.mygdx.game.controllers.commands.*; import com.mygdx.game.model.Lobby; import com.mygdx.game.model.Player; - -import org.javatuples.Pair; - import java.util.ArrayList; import java.util.LinkedList; @@ -69,6 +66,8 @@ public class PlayerController { public void leaveLobby(int id) { sendCommand(new cLobbyLeave(id)); } + public void updateGame(){ sendCommand(new cUpdateGame(lobby.getGame(), lobby.getID()));} + public Lobby getLobby(){ return lobby; } public ArrayList<Lobby> getLobbyList(){ return lobbies; } diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/commands/Command.java b/CheckersClient/core/src/com/mygdx/game/controllers/commands/Command.java index b8bb4a0..79f1dd1 100644 --- a/CheckersClient/core/src/com/mygdx/game/controllers/commands/Command.java +++ b/CheckersClient/core/src/com/mygdx/game/controllers/commands/Command.java @@ -30,9 +30,12 @@ public class Command{ @Override public String toString() { + String toString; + if(data == null) toString = "null"; + else toString = data.toString(); return "Command{" + "text='" + text + '\'' + - "data='" + data.toString() + '\'' + + "data='" + toString + '\'' + '}'; } } \ No newline at end of file diff --git a/CheckersClient/core/src/com/mygdx/game/controllers/commands/cUpdateGame.java b/CheckersClient/core/src/com/mygdx/game/controllers/commands/cUpdateGame.java new file mode 100644 index 0000000..c6eaf2b --- /dev/null +++ b/CheckersClient/core/src/com/mygdx/game/controllers/commands/cUpdateGame.java @@ -0,0 +1,26 @@ +package com.mygdx.game.controllers.commands; + +import com.esotericsoftware.kryonet.Connection; +import com.mygdx.game.controllers.PlayerController; + +import java.util.ArrayList; + +public class cUpdateGame extends Command{ + + public cUpdateGame() { super("cUpdateGame"); } + + public cUpdateGame(Object game, int lobbyId ) { + super("cUpdateGame"); + ArrayList<Object> data = new ArrayList<Object>(); + data.add(game); + data.add(lobbyId); + this.data = data; + } + + @Override + public void execute(PlayerController playerController, Connection connection){ + playerController.getLobby().setGame(data); //gameState as object, need to cast before using + if(data == null) System.out.println("gameState update received and it is null"); + else System.out.println("gameState update received correctly"); + } +} diff --git a/CheckersClient/core/src/com/mygdx/game/model/GameState.kt b/CheckersClient/core/src/com/mygdx/game/model/GameState.kt index c153bb6..35ece69 100644 --- a/CheckersClient/core/src/com/mygdx/game/model/GameState.kt +++ b/CheckersClient/core/src/com/mygdx/game/model/GameState.kt @@ -52,4 +52,5 @@ class GameState(gameMode: GameMode) { fun setFinished() { isFinished = true } + } \ No newline at end of file diff --git a/CheckersClient/core/src/com/mygdx/game/model/Lobby.java b/CheckersClient/core/src/com/mygdx/game/model/Lobby.java index a6ba03f..1e0cd58 100644 --- a/CheckersClient/core/src/com/mygdx/game/model/Lobby.java +++ b/CheckersClient/core/src/com/mygdx/game/model/Lobby.java @@ -11,6 +11,7 @@ public class Lobby { private int MAX_PLAYERS; private ArrayList<Player> players; private boolean lobbyGameStarted = false; + private Object game; public Lobby() {} @@ -24,6 +25,7 @@ public class Lobby { this.name = name; this.MAX_PLAYERS = MAX_PLAYERS; players = new ArrayList<Player>(); + game = null; } public int getID(){ return ID; } @@ -62,6 +64,10 @@ public class Lobby { return players; } + public void setGame(Object gameState){ this.game = gameState; } + + public Object getGame(){ return this.game; } + public LinkedHashSet<Integer> getPlayersID(){ LinkedHashSet<Integer> set = new LinkedHashSet<Integer>(); for(Player player : players){ diff --git a/CheckersServer/.idea/libraries/Gradle__CheckersServer_desktop_desktop_1_0.xml b/CheckersServer/.idea/libraries/Gradle__CheckersServer_desktop_desktop_1_0.xml new file mode 100644 index 0000000..369215d --- /dev/null +++ b/CheckersServer/.idea/libraries/Gradle__CheckersServer_desktop_desktop_1_0.xml @@ -0,0 +1,9 @@ +<component name="libraryTable"> + <library name="Gradle: CheckersServer.desktop.desktop-1.0"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/desktop/build/libs/desktop-1.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> +</component> \ No newline at end of file diff --git a/CheckersServer/.idea/modules.xml b/CheckersServer/.idea/modules.xml index 1b6b39a..a8a1a25 100644 --- a/CheckersServer/.idea/modules.xml +++ b/CheckersServer/.idea/modules.xml @@ -2,7 +2,7 @@ <project version="4"> <component name="ProjectModuleManager"> <modules> - <module fileurl="file://$PROJECT_DIR$/.idea/modules/CheckersServer.iml" filepath="$PROJECT_DIR$/.idea/modules/CheckersServer.iml" /> + <module fileurl="file://$PROJECT_DIR$/.idea/CheckersServer.iml" filepath="$PROJECT_DIR$/.idea/CheckersServer.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/android/CheckersServer.android.iml" filepath="$PROJECT_DIR$/.idea/modules/android/CheckersServer.android.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/core/CheckersServer.core.iml" filepath="$PROJECT_DIR$/.idea/modules/core/CheckersServer.core.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/desktop/CheckersServer.desktop.iml" filepath="$PROJECT_DIR$/.idea/modules/desktop/CheckersServer.desktop.iml" /> diff --git a/CheckersServer/core/src/com/mygdx/game/Constants.java b/CheckersServer/core/src/com/mygdx/game/Constants.java new file mode 100644 index 0000000..5170020 --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/Constants.java @@ -0,0 +1,16 @@ +package com.mygdx.game; + +import java.util.HashMap; + +public class Constants { + public static final int PLAYER_NAME_TEXT_FIELD_WIDTH = 340; + public static final int PLAYER_NAME_TEXT_FIELD_HEIGHT = 80; + public static final HashMap<Integer, String> AVAILABLEAVATARSHASHMAP = new HashMap<Integer, String>() {{ + put(0, "RegularGuy"); + put(1, "HipsterGirl"); + put(2, "HighSchoolGuy"); + put(3, "RocketGuy"); + put(4, "AsianGirl"); + put(5, "Grandma"); + }}; +} diff --git a/CheckersServer/core/src/com/mygdx/game/controller/NetworkController.java b/CheckersServer/core/src/com/mygdx/game/controller/NetworkController.java index 69788e3..1340ac8 100644 --- a/CheckersServer/core/src/com/mygdx/game/controller/NetworkController.java +++ b/CheckersServer/core/src/com/mygdx/game/controller/NetworkController.java @@ -1,17 +1,22 @@ package com.mygdx.game.controller; -import com.badlogic.gdx.math.Vector3; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryonet.Connection; import com.esotericsoftware.kryonet.Listener; import com.esotericsoftware.kryonet.Server; import com.mygdx.game.controller.commands.*; +import com.mygdx.game.model.DefaultBoard; +import com.mygdx.game.model.Field; +import com.mygdx.game.model.Game; +import com.mygdx.game.model.GameMode; +import com.mygdx.game.model.GameState; import com.mygdx.game.model.Lobby; +import com.mygdx.game.model.Piece; import com.mygdx.game.model.Player; +import com.mygdx.game.model.gamemodes.rules.DefaultRules; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; public class NetworkController { @@ -27,7 +32,7 @@ public class NetworkController { private Kryo kryo; public NetworkController(){ - server = new Server(); + server = new Server(16384,3072); server.start(); try { server.bind(54555, 54777); @@ -124,6 +129,16 @@ public class NetworkController { return new Lobby(-1); } + public Object updateGame(Game game, int lobbyID){ + Lobby lobby = getLobby(lobbyID); + if (lobby.getID() != -1){ + lobby.setGame(game); + lobbies.set(lobbies.indexOf(lobby), lobby); + return game; + } + return null; + } + public Lobby getLobby(int lobbyID){ int lobby_idx = lobbies.indexOf(new Lobby(lobbyID)); if (lobby_idx != -1){ @@ -160,7 +175,18 @@ public class NetworkController { kryo.register(cSetPlayerReady.class, 26); kryo.register(cSetPlayerName.class, 27); kryo.register(cStartGame.class, 28); - kryo.register(Vector3.class, 29); + kryo.register(cUpdateGame.class, 30); + kryo.register(Game.class, 31); + kryo.register(GameState.class, 32); + kryo.register(GameMode.class, 33); + kryo.register(Piece.class, 34); + kryo.register(Field.class, 35); + kryo.register(DefaultBoard.class, 36); + kryo.register(DefaultRules.class, 37); + kryo.register(java.util.HashMap.class, 38); + kryo.register(java.util.Arrays.asList().getClass(), 39); + kryo.register(kotlin.collections.EmptyList.class, 40); //works anyway ignore + kryo.register(java.util.LinkedHashSet.class, 41); } public NetworkController getNetworkController() { return this; } diff --git a/CheckersServer/core/src/com/mygdx/game/controller/commands/Command.java b/CheckersServer/core/src/com/mygdx/game/controller/commands/Command.java index 017f74c..dca9d8c 100644 --- a/CheckersServer/core/src/com/mygdx/game/controller/commands/Command.java +++ b/CheckersServer/core/src/com/mygdx/game/controller/commands/Command.java @@ -26,9 +26,12 @@ public class Command{ @Override public String toString() { + String toString; + if(data == null) toString = "null"; + else toString = data.toString(); return "Command{" + "text='" + text + '\'' + - "data='" + data.toString() + '\'' + + "data='" + toString + '\'' + '}'; } } \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/controller/commands/cPlayerPieceMove.java b/CheckersServer/core/src/com/mygdx/game/controller/commands/cPlayerPieceMove.java index b718675..9504cab 100644 --- a/CheckersServer/core/src/com/mygdx/game/controller/commands/cPlayerPieceMove.java +++ b/CheckersServer/core/src/com/mygdx/game/controller/commands/cPlayerPieceMove.java @@ -1,48 +1,18 @@ package com.mygdx.game.controller.commands; -import com.badlogic.gdx.math.Vector3; import com.esotericsoftware.kryonet.Connection; import com.mygdx.game.controller.NetworkController; -import java.util.ArrayList; - public class cPlayerPieceMove extends Command { - Vector3 fromCoordinates; - Vector3 toCordinates; - int lobby_id; - int playerId; - public cPlayerPieceMove() { super("cPlayerPieceMove"); } - /*public cPlayerPieceMove(Vector3 fromCoordinates, Vector3 toCoordinates, int lobbyId, int playerId) { - super("cPlayerPieceMove"); - - this.fromCoordinates = fromCoordinates; - this.toCordinates = toCoordinates; - this.lobby_id = lobbyId; - this.playerId = playerId; - - ArrayList<Object> data = new ArrayList<Object>(); - data.add(fromCoordinates); - data.add(toCoordinates); - data.add(playerId); - this.data = data; - }*/ - @Override public void execute(NetworkController net, Connection connection){ - if (data instanceof ArrayList) { - System.out.println("Checking if valid move.. If valid, moving player piece from A to B... Updating model.. Sending move to clients...."); - } - - for (Connection c : net.getConnections(net.getLobby(lobby_id))) { - if (c != connection) { - c.sendTCP(this); - } - } + System.out.println("Checking if valid move.. If valid, moving player piece from A to B... Updating model.. Sending move to clients...."); + connection.sendTCP(this); } } diff --git a/CheckersServer/core/src/com/mygdx/game/controller/commands/cUpdateGame.java b/CheckersServer/core/src/com/mygdx/game/controller/commands/cUpdateGame.java new file mode 100644 index 0000000..76359a6 --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/controller/commands/cUpdateGame.java @@ -0,0 +1,28 @@ +package com.mygdx.game.controller.commands; + +import com.esotericsoftware.kryonet.Connection; +import com.mygdx.game.controller.NetworkController; +import com.mygdx.game.model.Game; +import com.mygdx.game.model.Lobby; + +import java.util.ArrayList; + +public class cUpdateGame extends Command{ + + public cUpdateGame() { super("cUpdateGame"); } + + public cUpdateGame(Game game) { super("cUpdateGame", game); } + + @Override + public void execute(NetworkController net, Connection connection){ + if(data instanceof ArrayList){ + Game gameState = (Game)((ArrayList) data).get(0); + int lobbyID = (int) ((ArrayList) data).get(1); + data = net.updateGame(gameState, lobbyID); + for (Connection c : net.getConnections(net.getLobby(lobbyID))) { + c.sendTCP(this); + } + } + System.out.println("Game update request received"); + } +} \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/Field.kt b/CheckersServer/core/src/com/mygdx/game/model/Field.kt new file mode 100644 index 0000000..015e5ce --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/Field.kt @@ -0,0 +1,34 @@ +//Inside gameState, data for a specific field +package com.mygdx.game.model + +import java.lang.Exception + +class Field { + + private var piece: Piece? + //private var powerup: Powerup? + + init { + this.piece = null + } + + fun setPiece(piece: Piece) { + if (this.piece != null) { + throw Exception("Field already holds a piece.") + } else { + this.piece = piece + } + } + + fun getPiece(): Piece? { + return this.piece + } + + fun hasPiece(): Boolean { + return this.piece != null + } + + fun removePiece() { + this.piece = null + } +} \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/Game.kt b/CheckersServer/core/src/com/mygdx/game/model/Game.kt new file mode 100644 index 0000000..fd32d0c --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/Game.kt @@ -0,0 +1,25 @@ +package com.mygdx.game.model + +import com.badlogic.gdx.math.Vector3 + +class Game(gameState: GameState, playerIds: LinkedHashSet<Int>) { + + private var gameState: GameState + private var playerIds: LinkedHashSet<Int> + private var playerTurnId: Int + private var playerTurnIndex: Int = 0 // TODO: Random from server + private var playerTurnSlot: Int + private var playerFinishedIds: List<Int> = listOf() + private var usedBoardSlots: List<Int> + + init { + this.gameState = gameState + this.playerIds = playerIds + this.gameState.getBoardState().placePiecesAtStart(this.gameState.getRules(), this.playerIds) + + usedBoardSlots = this.gameState.getRules().getUsedBoardSlots(playerIds.size) + playerTurnSlot = usedBoardSlots[0] + playerTurnId = playerIds.elementAt(playerTurnIndex) + } + +} \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/GameMode.kt b/CheckersServer/core/src/com/mygdx/game/model/GameMode.kt new file mode 100644 index 0000000..98f51fb --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/GameMode.kt @@ -0,0 +1,30 @@ +package com.mygdx.game.model//Holds a ruleset and a board + +class GameMode(rules:AbstractRules, board:AbstractBoard) { + + private var rules: AbstractRules + private var board: AbstractBoard + + init { } + + init { + this.rules = rules + this.board = board + } + + fun setBoard(board:AbstractBoard) { + this.board = board + } + + fun getBoard(): AbstractBoard { + return this.board + } + + fun setRules(rules: AbstractRules) { + this.rules = rules + } + + fun getRules(): AbstractRules { + return this.rules + } +} \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/GameState.kt b/CheckersServer/core/src/com/mygdx/game/model/GameState.kt new file mode 100644 index 0000000..40d43c0 --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/GameState.kt @@ -0,0 +1,57 @@ +package com.mygdx.game.model + +import com.mygdx.game.model.gamemodes.rules.DefaultRules + +/* +Holds the state of the game and all data related to this. +*/ +class GameState(gameMode: GameMode) { + + private var boardState: AbstractBoard + private var rules: AbstractRules + private var isStarted: Boolean + private var winner: Int? + private var isFinished: Boolean = false + + init { } + + init { + this.rules = gameMode.getRules() + this.boardState = gameMode.getBoard() + + this.isStarted = false + this.winner = null + } + + fun getBoardState(): AbstractBoard { + return boardState + } + + fun getRules(): AbstractRules { + return rules + } + + fun isStarted(): Boolean { + return isStarted + } + + fun setStarted() { + this.isStarted = true + } + + fun isFinished(): Boolean { + return isFinished + } + + fun getWinner(): Int? { + return this.winner + } + + fun setWinner(winner: Int) { + this.winner = winner + } + + fun setFinished() { + isFinished = true + } +} \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/Lobby.java b/CheckersServer/core/src/com/mygdx/game/model/Lobby.java index 46496c4..2d6e8b5 100644 --- a/CheckersServer/core/src/com/mygdx/game/model/Lobby.java +++ b/CheckersServer/core/src/com/mygdx/game/model/Lobby.java @@ -1,5 +1,6 @@ package com.mygdx.game.model; + import java.util.ArrayList; import java.util.HashSet; @@ -9,6 +10,7 @@ public class Lobby { private String name; private int MAX_PLAYERS; private ArrayList<Player> players; + private Game game; public Lobby() {} @@ -22,6 +24,7 @@ public class Lobby { this.name = name; this.MAX_PLAYERS = MAX_PLAYERS; players = new ArrayList<Player>(); + game = null; } public int playerJoin(Player player){ @@ -84,6 +87,10 @@ public class Lobby { } } + public void setGame(Game game){ this.game = game; } + + public Object getGame(){ return this.game; } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/CheckersServer/core/src/com/mygdx/game/model/Piece.kt b/CheckersServer/core/src/com/mygdx/game/model/Piece.kt new file mode 100644 index 0000000..9c2dc1a --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/Piece.kt @@ -0,0 +1,12 @@ +package com.mygdx.game.model + +class Piece(ownerId: Int) { + + private var ownerId: Int = ownerId + + init { } + + fun getOwnerId(): Int { + return this.ownerId + } +} diff --git a/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/AbstractBoard.kt b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/AbstractBoard.kt new file mode 100644 index 0000000..06d857d --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/AbstractBoard.kt @@ -0,0 +1,13 @@ +package com.mygdx.game.model + +import com.badlogic.gdx.math.Vector3 + +abstract class AbstractBoard { + + var fields = HashMap<Vector3, Field>() + + abstract fun computeFields() // Computes all fields on the board + abstract fun fieldExists(coordinates: Vector3): Boolean + abstract fun placePiecesAtStart(rules: AbstractRules, playerIds: HashSet<Int>) + abstract fun movePiece(fromCoordinates: Vector3, toCoordinates: Vector3): Boolean +} \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/DefaultBoard.kt b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/DefaultBoard.kt new file mode 100644 index 0000000..a20a6b3 --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/DefaultBoard.kt @@ -0,0 +1,82 @@ +//General board class +package com.mygdx.game.model + +import com.badlogic.gdx.math.Vector3 +import java.lang.Integer.max +import java.lang.Integer.min + +class DefaultBoard: AbstractBoard() { + var r = 8 + + init { } + + init { + computeFields() + } + + override fun computeFields() { + // https://www.redblobgames.com/grids/hexagons/#range + for (x in -r..r) { + loop@ for (y in max(-r, -x - r)..min(r, -x + r)) { + val z = -x - y + + val coordinates = Vector3(x.toFloat(), y.toFloat(), z.toFloat()) + if (!fieldShouldBeAddedToBoard(coordinates)) { + continue@loop + } + fields[coordinates] = Field() + } + } + } + + override fun placePiecesAtStart(rules: AbstractRules, playerIds: HashSet<Int>) { + + val startFields: List<List<Vector3>> = rules.generateStartFields(playerIds.size) + + for ((playerIndex, coordinateSet: List<Vector3>) in startFields.withIndex()) { + for (coordinate: Vector3 in coordinateSet) { + val piece = Piece(playerIds.elementAt(playerIndex)) + fields[coordinate]?.setPiece(piece) + } + } + } + + override fun fieldExists(coordinates: Vector3): Boolean { + return fields[coordinates] != null + } + + override fun movePiece(fromCoordinates: Vector3, toCoordinates: Vector3): Boolean { + val piece = fields[fromCoordinates]?.getPiece() + + if (piece != null) { + fields[toCoordinates]?.setPiece(piece) + fields[fromCoordinates]?.removePiece() + return true + } + return false + } + + private fun fieldShouldBeAddedToBoard(coordinates: Vector3) : Boolean { + val x = coordinates.x + val y = coordinates.y + val z = coordinates.z + + // Upper right + if (x > 4) { + if (y < -4 || z < -4) + return false + } + // Bottom + if (z > 4) { + if (y < -4 || x < -4) + return false + } + // Upper left + if (y > 4) { + if (x < -4 || z < -4) { + return false + } + } + return true + } +} \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/Direction.kt b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/Direction.kt new file mode 100644 index 0000000..e49fa59 --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/boards/Direction.kt @@ -0,0 +1,15 @@ +package com.mygdx.game.model + +import com.badlogic.gdx.math.Vector3 + +enum class Direction { + UPPERRIGHT, + RIGHT, + LOWERRIGHT, + LOWERLEFT, + LEFT, + UPPERLEFT +} + +// Sequence matches Direction enum above (UpperRight, Right, LowerRight, LowerLeft, Left, UpperLeft) +var directionalUnitVectors = listOf(Vector3(1F, 0F, -1F), Vector3(1F, -1F, 0F), Vector3(0F, -1F, 1F), Vector3(-1F, 0F, 1F), Vector3(-1F, 1F, 0F), Vector3(0F, 1F, -1F)) \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/gamemodes/rules/AbstractRules.kt b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/rules/AbstractRules.kt new file mode 100644 index 0000000..618a82f --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/rules/AbstractRules.kt @@ -0,0 +1,16 @@ +package com.mygdx.game.model + +import com.badlogic.gdx.math.Vector3 + +abstract class AbstractRules { + + abstract var startFields: List<List<Vector3>> // List containing list of startfields for each player + abstract var moveRange: Int // How far a piece can be moved + abstract var jumpRange: Int // How many pieces a piece can jump over + + abstract fun getPlayerStartfields(boardSlot: Int) : List<Vector3> // Returns a list of startfields for a given player + abstract fun getPlayerTargetFields(boardSlot: Int) : List<Vector3> // Returns a list of targetfields for a given player + abstract fun generateStartFields(playerCount: Int = 6): List<List<Vector3>> // Returns a list with lists of startfields + abstract fun getUsedBoardSlots(playerCount: Int): List<Int> // Returns a list with used boardslots + abstract fun getPlayerNameCoordinates(hex_side_length: Float): List<List<Float>> // Returns a list with lists of coordinates for playernames +} \ No newline at end of file diff --git a/CheckersServer/core/src/com/mygdx/game/model/gamemodes/rules/DefaultRules.kt b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/rules/DefaultRules.kt new file mode 100644 index 0000000..a3e2591 --- /dev/null +++ b/CheckersServer/core/src/com/mygdx/game/model/gamemodes/rules/DefaultRules.kt @@ -0,0 +1,107 @@ +package com.mygdx.game.model.gamemodes.rules + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.math.Vector3 +import com.mygdx.game.Constants +import com.mygdx.game.model.AbstractRules + +class DefaultRules: AbstractRules() { + override var startFields = generateStartFields() + override var moveRange = 1 + override var jumpRange = 2 + + init { } + + override fun getPlayerStartfields(boardSlot: Int): List<Vector3> { + return startFields[boardSlot] + } + + override fun getPlayerTargetFields(boardSlot: Int): List<Vector3> { + var slot = boardSlot + + for (i in 0..2) { + slot++ + // Wrap around to first player + if(slot == 6) { + slot = 0 + } + } + return startFields[slot] + } + + // Sequence: top, upperright, lowerright, bottom, lowerleft, upperleft + override fun generateStartFields(playerCount: Int): List<List<Vector3>> { + val startFields: MutableList<List<Vector3>> = mutableListOf() + val allStartFields: List<List<Vector3>> = listOf( + listOf(Vector3(1F, 4F, -5F), Vector3(2F, 3F, -5F), Vector3(3F, 2F, -5F), Vector3(4F, 1F, -5F), + Vector3(2F, 4F, -6F), Vector3(3F, 3F, -6F), Vector3(4F, 2F, -6F), Vector3(3F, 4F, -7F), + Vector3(4F, 3F, -7F), Vector3(4F, 4F, -8F) + ), + listOf(Vector3(5F, -1F, -4F), Vector3(5F, -2F, -3F), Vector3(5F, -3F, -2F), Vector3(5F, -4F, -1F), + Vector3(6F, -2F, -4F), Vector3(6F, -3F, -3F), Vector3(6F, -4F, -2F), Vector3(7F, -3F, -4F), + Vector3(7F, -4F, -3F), Vector3(8F, -4F, -4F) + ), + listOf(Vector3(4F, -5F, 1F), Vector3(3F, -5F, 2F), Vector3(2F, -5F, 3F), Vector3(1F, -5F, 4F), + Vector3(4F, -6F, 2F), Vector3(3F, -6F, 3F), Vector3(2F, -6F, 4F), Vector3(4F, -7F, 3F), + Vector3(3F, -7F, 4F), Vector3(4F, -8F, 4F) + ), + listOf(Vector3(-4F, -1F, 5F), Vector3(-3F, -2F, 5F), Vector3(-2F, -3F, 5F), Vector3(-1F, -4F, 5F), + Vector3(-4F, -2F, 6F), Vector3(-3F, -3F, 6F), Vector3(-2F, -4F, 6F), Vector3(-4F, -3F, 7F), + Vector3(-3F, -4F, 7F), Vector3(-4F, -4F, 8F) + ), + listOf(Vector3(-5F, 4F, 1F), Vector3(-5F, 3F, 2F), Vector3(-5F, 2F, 3F), Vector3(-5F, 1F, 4F), + Vector3(-6F, 4F, 2F), Vector3(-6F, 3F, 3F), Vector3(-6F, 2F, 4F), Vector3(-7F, 4F, 3F), + Vector3(-7F, 3F, 4F), Vector3(-8F, 4F, 4F) + ), + listOf(Vector3(-1F, 5F, -4F), Vector3(-2F, 5F, -3F), Vector3(-3F, 5F, -2F), Vector3(-4F, 5F, -1F), + Vector3(-2F, 6F, -4F), Vector3(-3F, 6F, -3F), Vector3(-4F, 6F, -2F), Vector3(-3F, 7F, -4F), + Vector3(-4F, 7F, -3F), Vector3(-4F, 8F, -4F) + ) + ) + + when (playerCount) { + 2 -> { + startFields.add(allStartFields[0]) + startFields.add(allStartFields[3]) + } + 4 -> { + startFields.add(allStartFields[1]) + startFields.add(allStartFields[2]) + startFields.add(allStartFields[4]) + startFields.add(allStartFields[5]) + } + 6 -> startFields.addAll(allStartFields) + else -> { + print("ERROR: DefaultBoard needs 2, 4 or 6 players.") + } + } + + return startFields + } + + override fun getUsedBoardSlots(playerCount: Int): List<Int> { + return when (playerCount) { + 2 -> { + listOf(0, 3) + } + 4 -> { + listOf(1, 2, 4, 5) + } + else -> { + listOf(0, 1, 2, 3, 4, 5) + } + } + } + + override fun getPlayerNameCoordinates(hex_side_length: Float): List<List<Float>> { + return listOf( + listOf(Gdx.graphics.width / 2f - Constants.PLAYER_NAME_TEXT_FIELD_WIDTH - 2.5f * hex_side_length, Gdx.graphics.height - Constants.PLAYER_NAME_TEXT_FIELD_HEIGHT - 1.5f * hex_side_length), + listOf(Gdx.graphics.width / 2f + Constants.PLAYER_NAME_TEXT_FIELD_WIDTH + 4f * hex_side_length, Gdx.graphics.height / 2f + 4 * hex_side_length), + listOf(Gdx.graphics.width / 2f + Constants.PLAYER_NAME_TEXT_FIELD_WIDTH + 4f * hex_side_length, Gdx.graphics.height / 2f - 5 * hex_side_length), + listOf(Gdx.graphics.width / 2f - Constants.PLAYER_NAME_TEXT_FIELD_WIDTH - 2.5f * hex_side_length, 1.5f * hex_side_length), + listOf(Gdx.graphics.width / 2f - Constants.PLAYER_NAME_TEXT_FIELD_WIDTH - 12f * hex_side_length, Gdx.graphics.height / 2f - 5 * hex_side_length), + listOf(Gdx.graphics.width / 2f - Constants.PLAYER_NAME_TEXT_FIELD_WIDTH - 12f * hex_side_length, Gdx.graphics.height / 2f + 4 * hex_side_length) + ) + } +} + -- GitLab