diff --git a/Client/src/TicTacToe_Client.java b/Client/src/TicTacToe_Client.java index ad9b2e8..2acb959 100644 --- a/Client/src/TicTacToe_Client.java +++ b/Client/src/TicTacToe_Client.java @@ -1,4 +1,5 @@ import javafx.application.Platform; +import logging.LogType; import networking.Client; import render.Engine; @@ -11,26 +12,29 @@ public class TicTacToe_Client { private Client client; private static String clientName; private boolean isPlayerOne; + private boolean isAllowedToMove; public TicTacToe_Client() { renderEngine = Engine.waitForEngine(); client = new Client("server", 2589, clientName); client.handshake(); isPlayerOne = client.isPlayerOne(); + isAllowedToMove = isPlayerOne; this.setWindowTitle(isPlayerOne); client.sendToServer("ready"); } private void ticTacToe_gameloop() { - this.drawBoard(client.getGameState()); - if (isPlayerOne){ - this.userInput(); - } while (client.isConnected() && !renderEngine.isWindowClosed()) { + client.printLog("Waiting for data", true, LogType.Log); String message = client.getResponse(); //Check if message is gamestate - if (message.charAt(0) == 'x' || message.charAt(0) == '-' || message.charAt(0) == 'o') { + if (message.matches("([xo-]){9}")) { + client.printLog("Board updated", true, LogType.Log); this.drawBoard(message); + if (isAllowedToMove){ + this.gameFlow("userInput"); + } } //Handle everything else else { @@ -46,6 +50,11 @@ public class TicTacToe_Client { private void gameFlow(String input) { switch (input) { + case "opponentMove": + //if opponent makes move allow a move + isAllowedToMove = true; + break; + case "userInput": while (!renderEngine.isMouseClicked()) { try { @@ -55,21 +64,21 @@ public class TicTacToe_Client { } } renderEngine.setMouseClicked(false); + isAllowedToMove = false; this.userInput(); break; case "invalidInput": + isAllowedToMove = true; this.onInvalidInput(); break; - case "" + case "gameEnded": + this.onGameEnd(); + break; } } - private void requestOpponentMove(){ - client.sendToServer("opponentMove"); - } - private void onGameEnd(){ LinkedList winCoordinates = new LinkedList<>(); //Get winning fields @@ -91,27 +100,12 @@ public class TicTacToe_Client { int column = (int) renderEngine.getCoordinates().getX() / 300; int row = (int) renderEngine.getCoordinates().getY() / 300; System.err.printf("You are not allowed to place at %d|%d%n", column, row); - this.userInput(); + this.gameFlow("userInput"); } private void userInput() { client.sendToServer("clientMove"); client.sendToServer(String.format("%f|%f", renderEngine.getCoordinates().getX(), renderEngine.getCoordinates().getY())); - //Get gameState - String gameState = client.getResponse(); - if (gameState.length() == 9) { - this.drawBoard(gameState); - //Send command - if (!client.getGameEnded()) { - this.requestOpponentMove(); - } else { - this.onGameEnd(); - } - } else { - int column = (int) renderEngine.getCoordinates().getX() / 300; - int row = (int) renderEngine.getCoordinates().getY() / 300; - System.err.printf("You are not allowed to place at %d|%d%n", column, row); - } } private void drawBoard(String gameState) { @@ -148,12 +142,12 @@ public class TicTacToe_Client { javafx.application.Application.launch(Engine.class); } }.start(); - TicTacToe_Client test = new TicTacToe_Client(); try { clientName = args[0]; } catch (Exception e) { clientName = "testing"; } + TicTacToe_Client test = new TicTacToe_Client(); test.ticTacToe_gameloop(); } diff --git a/Client/src/logging/ClientLogger.java b/Client/src/logging/ClientLogger.java index d88a7cc..bc45e52 100644 --- a/Client/src/logging/ClientLogger.java +++ b/Client/src/logging/ClientLogger.java @@ -54,8 +54,8 @@ public class ClientLogger { this.printLog(message, "server", success, logType); } - public void printConfirmation(int code){ - if (code == 200){ + public void printConfirmation(boolean success){ + if (success){ printLog(" Status: sent!", true, LogType.Log); } else { printLog(" Status: not sent!", false, LogType.Log); diff --git a/Client/src/networking/Client.java b/Client/src/networking/Client.java index d6887be..3057e91 100644 --- a/Client/src/networking/Client.java +++ b/Client/src/networking/Client.java @@ -7,7 +7,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; -import java.util.Scanner; +import java.util.Arrays; public class Client { private Socket serverSocket; @@ -39,7 +39,7 @@ public class Client { try { out.writeInt(165313125); out.flush(); - success = in.readInt() == 200; + success = in.readBoolean(); if (success) { out.writeUTF(name); out.flush(); @@ -54,11 +54,37 @@ public class Client { } public void sendToServer(String message) { + int availableBits = 0; try { out.writeUTF(message); out.flush(); - success = in.readInt() == 200; + boolean success = in.readBoolean(); clientLogger.printLog(String.format("Sent the message: %s", message), serverName, success, LogType.Output); + if(in.available() > 0){ + availableBits = in.available(); + throw new Exception("More than just a boolean sent"); + } + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + this.exitProcess(); + this.printInputStream(); + e.printStackTrace(); + System.exit(0); + } + } + + private void printInputStream(){ + try { + byte[] inputBytes = in.readAllBytes(); + for (byte b: inputBytes) { + if (b == 1 || b == 0){ + System.out.println(b == 1); + } + System.out.print(Character.toString(b)); + } + System.out.println(Arrays.toString(inputBytes)); + System.out.print("\n"); } catch (IOException e) { e.printStackTrace(); } @@ -124,7 +150,7 @@ public class Client { try { out.writeUTF("exit"); out.flush(); - success = in.readInt()==200; + success = in.readBoolean(); clientLogger.printLog("Closing connection to server", serverName, success, LogType.Log); } catch (IOException e) { e.printStackTrace(); @@ -135,7 +161,7 @@ public class Client { try { out.writeUTF("reset"); out.flush(); - success = in.readInt()==200; + success = in.readBoolean(); clientLogger.printLog("Resetting board", serverName, success, LogType.Log); } catch (IOException e) { e.printStackTrace(); @@ -150,8 +176,8 @@ public class Client { authorizedToMove = isAuthorizedToMove; } - public void printLog(String message, boolean success){ - clientLogger.printLog(message, success, LogType.Log); + public void printLog(String message, boolean success, LogType logType){ + clientLogger.printLog(message, success, logType); } public boolean isConnected(){ diff --git a/Client/src/render/Engine.java b/Client/src/render/Engine.java index bba1f4a..09a5910 100644 --- a/Client/src/render/Engine.java +++ b/Client/src/render/Engine.java @@ -64,7 +64,6 @@ public class Engine extends Application { } public void updateTitle(String title) { - System.out.println("title: " + title); primaryStage.setTitle(title); } @@ -87,10 +86,6 @@ public class Engine extends Application { } public void drawBoard(String gameState) { - if (gameState.length() != 9) { - System.err.println("Wrong length of gameState string"); - return; - } if (gameState.equals("---------")) { grid.getChildren().clear(); } diff --git a/Server/src/networking/TicTacToe_Server.java b/Server/src/networking/TicTacToe_Server.java index 655d889..1df45fb 100644 --- a/Server/src/networking/TicTacToe_Server.java +++ b/Server/src/networking/TicTacToe_Server.java @@ -18,7 +18,6 @@ public class TicTacToe_Server { private HashMap clients; private HashMap clientIds; private HashMap clientNames; - private HashMap clientMoveAuthorizations; private HashMap outstreams; private HashMap instreams; private TicTacToe_GameRules ticTacToe_gameRules; @@ -33,7 +32,6 @@ public class TicTacToe_Server { clients = new HashMap<>(); clientNames = new HashMap<>(); clientIds = new HashMap<>(); - clientMoveAuthorizations = new HashMap<>(); outstreams = new HashMap<>(); instreams = new HashMap<>(); ticTacToe_gameRules = new TicTacToe_GameRules(); @@ -48,10 +46,18 @@ public class TicTacToe_Server { } private boolean isSingleServer() { - serverLogger.printLog(""+ requiredConnections + (requiredConnections == 1), LogType.Error); return requiredConnections == 1; } + private boolean allClientsReady(){ + for (boolean status: clientsReady) { + if (status == false){ + return false; + } + } + return true; + } + public void connectClients() { try { int id = 0; @@ -74,7 +80,7 @@ public class TicTacToe_Server { try { int handshakeValue = instreams.get(client).readInt(); if (handshakeValue == 165313125) { - outstreams.get(client).writeInt(200); + outstreams.get(client).writeBoolean(true); outstreams.get(client).flush(); clientNames.put(client, instreams.get(client).readUTF()); serverLogger.printLog(String.format("Client \"%s\" got connected", clientNames.get(client)), LogType.Log); @@ -109,11 +115,12 @@ public class TicTacToe_Server { public String handleInput(Socket client) { String message = null; try { + serverLogger.printLog("Waiting for input...", LogType.Log); message = instreams.get(client).readUTF(); serverLogger.printLog(message, clientNames.get(client), LogType.Message); - outstreams.get(client).writeInt(200); + outstreams.get(client).writeBoolean(true); outstreams.get(client).flush(); - serverLogger.printLog("Sent verification code", "200", clientNames.get(client), LogType.Log); + serverLogger.printLog("Sent verification code", Boolean.toString(true), clientNames.get(client), LogType.Log); } catch (IOException e) { e.printStackTrace(); } @@ -121,6 +128,11 @@ public class TicTacToe_Server { } public void ticTacToe_gameloop() { + while (!allClientsReady()) { + for (Socket client : clients.values()) { + gameFlow(handleInput(client), client); + } + } while (clients.size() == requiredConnections) { for (Socket client : clients.values()) { gameFlow(handleInput(client), client); @@ -149,7 +161,25 @@ public class TicTacToe_Server { String position = handleInput(client); boolean moveAllowed = ticTacToe_gameRules.makeClientMove(position, clientIds.get(client)); if (moveAllowed) { - sendGameState(); + if (ticTacToe_gameRules.gameEnded()){ + for (DataOutputStream outputStream : outstreams.values()) { + outputStream.writeUTF("gameEnded"); + outputStream.flush(); + } + } + if (!isSingleServer()) { + outstreams.get(clients.get(1 - clientIds.get(client))).writeUTF("opponentMove"); + outstreams.get(clients.get(1 - clientIds.get(client))).flush(); + sendGameState(); + } else { + sendGameState(); + ticTacToe_gameRules.makeComputerMove(); + serverLogger.printLog("Trigger computer move", LogType.Log); + outstreams.get(client).writeUTF("opponentMove"); + outstreams.get(client).flush(); + sendGameState(); + } + } else { outstreams.get(client).writeUTF("invalidInput"); outstreams.get(client).flush(); @@ -160,32 +190,6 @@ public class TicTacToe_Server { } break; - case "opponentMove": - if (isSingleServer()) { - ticTacToe_gameRules.makeComputerMove(); - serverLogger.printLog("Made computer move", LogType.Log); - } else { - //request move from other player - try { - outstreams.get(1-clientIds.get(client)).writeUTF("userInput"); - outstreams.get(client).flush(); - serverLogger.printLog("Requested opponent userInput", clientNames.get(1-clientIds.get(client)), LogType.Log); - } catch (IOException e) { - e.printStackTrace(); - } - } - sendGameState(); - if (isSingleServer()) { - try { - outstreams.get(client).writeUTF("userInput"); - outstreams.get(client).flush(); - serverLogger.printLog("Requested userInput", LogType.Log); - } catch (IOException e) { - e.printStackTrace(); - } - } - break; - case "serverType": try { outstreams.get(client).writeBoolean(isSingleServer());