diff --git a/.idea/artifacts/Client.xml b/.idea/artifacts/Client.xml
new file mode 100644
index 0000000..43d929f
--- /dev/null
+++ b/.idea/artifacts/Client.xml
@@ -0,0 +1,22 @@
+
+
+ $PROJECT_DIR$/out/artifacts/Client
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/artifacts/Client_jar.xml b/.idea/artifacts/Client_jar.xml
deleted file mode 100644
index 4de7eb1..0000000
--- a/.idea/artifacts/Client_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
- $PROJECT_DIR$/out/artifacts/Client_jar
-
-
-
-
-
\ No newline at end of file
diff --git a/Client/src/META-INF/MANIFEST.MF b/Client/src/META-INF/MANIFEST.MF
index d3e52b4..b851779 100644
--- a/Client/src/META-INF/MANIFEST.MF
+++ b/Client/src/META-INF/MANIFEST.MF
@@ -1,3 +1,3 @@
Manifest-Version: 1.0
-Main-Class: networking.Client
+Main-Class: game.TicTacToe_Client
diff --git a/Client/src/games/TicTacToe/TicTacToe_Client.css b/Client/src/game/TicTacToe_Client.css
similarity index 100%
rename from Client/src/games/TicTacToe/TicTacToe_Client.css
rename to Client/src/game/TicTacToe_Client.css
diff --git a/Client/src/games/TicTacToe/TicTacToe_Client.java b/Client/src/game/TicTacToe_Client.java
similarity index 80%
rename from Client/src/games/TicTacToe/TicTacToe_Client.java
rename to Client/src/game/TicTacToe_Client.java
index 5828e0a..aee4a00 100644
--- a/Client/src/games/TicTacToe/TicTacToe_Client.java
+++ b/Client/src/game/TicTacToe_Client.java
@@ -1,4 +1,4 @@
-package games.TicTacToe;
+package game;
import javafx.application.Application;
import javafx.event.EventHandler;
@@ -26,8 +26,6 @@ public class TicTacToe_Client extends Application {
grid.setGridLinesVisible(true);
}
-
-
private void drawCross(int column, int row){
Text cross = new Text("X");
cross.setFont(Font.font("Tahoma", FontWeight.NORMAL, 200));
@@ -40,7 +38,6 @@ public class TicTacToe_Client extends Application {
grid.add(circle, column, row);
}
-
private void drawEmptyField(int column, int row) {
Text emptyField = new Text(" ");
emptyField.setFont(Font.font("Tahoma", FontWeight.NORMAL, 200));
@@ -53,8 +50,8 @@ public class TicTacToe_Client extends Application {
return;
}
for (int i = 0; i < gameState.length(); i++){
- int column = i % 3;
- int row = i / 3;
+ int column = i / 3;
+ int row = i % 3;
if (gameState.charAt(i) == 'x'){
this.drawCross(column, row);
} else if (gameState.charAt(i) == 'o'){
@@ -73,8 +70,16 @@ public class TicTacToe_Client extends Application {
scene.setOnMousePressed(new EventHandler() {
@Override
public void handle(MouseEvent event) {
- client.sendToServer(String.format("(%f|%f)", event.getX(), event.getY()));
- client.getGameState();
+ client.sendToServer("update");
+ client.sendToServer(String.format("%f|%f", event.getX(), event.getY()));
+ String gameState = client.getResponse();
+ if (gameState.length() == 9) {
+ drawBoard(gameState);
+ } else {
+ int column = (int) event.getX() / 300;
+ int row = (int) event.getY() / 300;
+ System.err.printf("You are not allowed to place at %f|%f%n", column, row);
+ }
}
});
return scene;
@@ -82,6 +87,9 @@ public class TicTacToe_Client extends Application {
@Override
public void start(Stage primaryStage) {
+ client = new Client("localhost", 2589, "TestClient");
+ client.handshake();
+
primaryStage.setTitle("TicTacToe");
primaryStage.setResizable(false);
@@ -91,10 +99,7 @@ public class TicTacToe_Client extends Application {
primaryStage.show();
- this.drawBoard("---------");
-
- client = new Client("localhost", 2589, "TestClient");
- client.handshake();
+ this.drawBoard(client.getGameState());
}
public static void main(String[] args) {
diff --git a/Client/src/games/TicTacToe/TicTacToe_Grid.png b/Client/src/game/TicTacToe_Grid.png
similarity index 100%
rename from Client/src/games/TicTacToe/TicTacToe_Grid.png
rename to Client/src/game/TicTacToe_Grid.png
diff --git a/Client/src/networking/Client.java b/Client/src/networking/Client.java
index bf6ab0c..ebb1a7c 100644
--- a/Client/src/networking/Client.java
+++ b/Client/src/networking/Client.java
@@ -2,6 +2,8 @@ package networking;
import logging.ClientLogger;
import logging.LogType;
+
+import javax.swing.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -37,8 +39,9 @@ public class Client {
out.writeInt(165313125);
out.flush();
success = in.readInt() == 200;
- if (success){
+ if (success) {
out.writeUTF(name);
+ out.flush();
serverName = in.readUTF();
clientLogger.printLog("You successfully connected to me", serverName, success, LogType.Log);
} else {
@@ -55,18 +58,37 @@ public class Client {
out.writeUTF(message);
out.flush();
success = in.readInt() == 200;
+ clientLogger.printLog(String.format("Sent the message: %s", message), serverName, success, LogType.Log);
} catch (IOException e) {
e.printStackTrace();
}
}
- public String getGameState(){
+ public String getResponse() {
try {
- out.writeUTF("gamestate");
- return in.readUTF();
+ String message = in.readUTF();
+ clientLogger.printLog(String.format("Message recieved: %s", message), serverName, success, LogType.Log);
+ return message;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ public String getGameState() {
+ this.sendToServer("gameState");
+ String gameState = this.getResponse();
+ return gameState;
+ }
+
+ public void exitProcess(){
+ try {
+ out.writeUTF("exit()");
+ out.flush();
+ success = in.readInt()==200;
+ clientLogger.printLog("Closing connection to server", serverName, success, LogType.Log);
} catch (IOException e) {
e.printStackTrace();
- return "";
}
}
@@ -74,6 +96,8 @@ public class Client {
return success;
}
- public String getName(){return name;}
+ public String getName() {
+ return name;
+ }
}
\ No newline at end of file
diff --git a/Server/res/META-INF/MANIFEST.MF b/Server/res/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9ae8574
--- /dev/null
+++ b/Server/res/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: networking.Server
+
diff --git a/Server/src/game/TicTacToe_Server.java b/Server/src/game/TicTacToe_Server.java
new file mode 100644
index 0000000..f7220fa
--- /dev/null
+++ b/Server/src/game/TicTacToe_Server.java
@@ -0,0 +1,41 @@
+package game;
+
+import java.nio.charset.StandardCharsets;
+
+public class TicTacToe_Server {
+
+ private String gameState;
+
+ public TicTacToe_Server(){
+ gameState = "---------";
+ }
+
+ public void setGameState(String gameState) {
+ this.gameState = gameState;
+ }
+
+ public String getGameState() {
+ return gameState;
+ }
+
+ public int makeClientMove(String input) {
+ int column = Double.valueOf(input.split("\\|")[0]).intValue() / 300;
+ int row = Double.valueOf(input.split("\\|")[1]).intValue() / 300;
+ int index = column * 3 + row;
+
+ if (isLegalMove(column, row)) {
+ byte[] gameStateBytes = gameState.getBytes();
+ gameStateBytes[index] = (byte) 'x';
+ gameState = new String(gameStateBytes, StandardCharsets.UTF_8);
+ return 200;
+ } else {
+ return 404;
+ }
+ }
+
+ private boolean isLegalMove(int column, int row){
+ int index = column * 3 + row;
+ return gameState.charAt(index) == '-';
+ }
+
+}
diff --git a/Server/src/networking/Server.java b/Server/src/networking/Server.java
index 5f4b2fe..9b15e51 100644
--- a/Server/src/networking/Server.java
+++ b/Server/src/networking/Server.java
@@ -1,5 +1,6 @@
package networking;
+import game.TicTacToe_Server;
import logging.LogType;
import logging.ServerLogger;
@@ -15,7 +16,8 @@ public class Server {
private HashMap clientNames;
private HashMap outstreams;
private HashMap instreams;
- private ServerLogger logger;
+ private TicTacToe_Server ticTacToe_server;
+ private ServerLogger serverLogger;
private Scanner scanner;
private int requiredConnections;
@@ -26,11 +28,12 @@ public class Server {
clientNames = new HashMap<>();
outstreams = new HashMap<>();
instreams = new HashMap<>();
+ ticTacToe_server = new TicTacToe_Server();
scanner = new Scanner(System.in);
- logger = new ServerLogger();
+ serverLogger = new ServerLogger();
requiredConnections = 1;
- logger.printLog("Server started successfully", LogType.Log);
+ serverLogger.printLog("Server started successfully", LogType.Log);
} catch (IOException e) {
e.printStackTrace();
}
@@ -39,7 +42,7 @@ public class Server {
public void connectClients(){
try {
int id = 0;
- logger.printLog(String.format("Waiting for %d clients to connect ...", requiredConnections), LogType.Log);
+ serverLogger.printLog(String.format("Waiting for %d clients to connect ...", requiredConnections), LogType.Log);
while(clients.size() < requiredConnections) {
Socket momentaryClient = serverSocket.accept();
clients.put(id, momentaryClient);
@@ -62,7 +65,7 @@ public class Server {
clientNames.put(client, instreams.get(client).readUTF());
outstreams.get(client).writeUTF(serverSocket.getInetAddress().getHostAddress()+":"+serverSocket.getLocalPort());
outstreams.get(client).flush();
- logger.printLog(String.format("%s got connected", clientNames.get(client)), LogType.Log);
+ serverLogger.printLog(String.format("%s got connected", clientNames.get(client)), LogType.Log);
} else {
outstreams.get(client).writeInt(403);
outstreams.get(client).flush();
@@ -74,19 +77,16 @@ public class Server {
}
}
- public void getMessages(){
+ public void ticTacToe_gameloop(){
for (Socket client: clients.values()) {
try {
- while (true) {
+ while (!client.isClosed()) {
String message = instreams.get(client).readUTF();
- if (!message.equalsIgnoreCase("exit()")) {
- logger.printLog(message, clientNames.get(client), LogType.Message);
- } else {
- outstreams.get(client).writeInt(200);
- logger.printLog(String.format("%s closed the connection",clientNames.get(client)), LogType.Log);
- break;
- }
+ serverLogger.printLog(message, clientNames.get(client), LogType.Message);
outstreams.get(client).writeInt(200);
+ outstreams.get(client).flush();
+ serverLogger.printLog("Sent verification code", clientNames.get(client), LogType.Log);
+ this.gameFlow(message, client);
}
} catch (IOException e) {
e.printStackTrace();
@@ -97,10 +97,56 @@ public class Server {
}
}
}
- clients.clear();
- System.out.println("Do you want to keep the server alive and wait for other clients ? [y]/[n]");
- if (scanner.nextLine().equalsIgnoreCase("y")){
- this.connectClients();
+ }
+
+ public void gameFlow(String input, Socket client){
+ switch (input){
+ case "gameState":
+ try {
+ outstreams.get(client).writeUTF(ticTacToe_server.getGameState());
+ outstreams.get(client).flush();
+ serverLogger.printLog("Sent gameState", clientNames.get(client), LogType.Log);
+ break;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ case "update":
+ try {
+ String position = instreams.get(client).readUTF();
+ serverLogger.printLog(position, clientNames.get(client), LogType.Message);
+ outstreams.get(client).writeInt(200);
+ outstreams.get(client).flush();
+ serverLogger.printLog("Sent verification code", clientNames.get(client), LogType.Log);
+ int verificationCode = ticTacToe_server.makeClientMove(position);
+ if (verificationCode == 200) {
+ String gameState = ticTacToe_server.getGameState();
+ outstreams.get(client).writeUTF(gameState);
+ outstreams.get(client).flush();
+ serverLogger.printLog(String.format("Sent gameState: %s", gameState), clientNames.get(client), LogType.Log);
+ break;
+ } else {
+ outstreams.get(client).writeUTF(" ");
+ outstreams.get(client).flush();
+ serverLogger.printLog(String.format("Move is not allowed!"), clientNames.get(client), LogType.Error);
+ break;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ case "exit()":
+ try {
+ outstreams.get(client).writeInt(200);
+ outstreams.get(client).flush();
+ outstreams.get(client).close();
+ instreams.get(client).close();
+ client.close();
+ serverLogger.printLog(String.format("%s closed the connection",clientNames.get(client)), LogType.Log);
+ break;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
}
@@ -108,6 +154,6 @@ public class Server {
Server server = new Server(2589);
server.connectClients();
server.handshake();
- server.getMessages();
+ server.ticTacToe_gameloop();
}
}
\ No newline at end of file
diff --git a/out/artifacts/Client/Client.html b/out/artifacts/Client/Client.html
new file mode 100644
index 0000000..af4b518
--- /dev/null
+++ b/out/artifacts/Client/Client.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+Test page for Client
+ Webstart: click to launch this app as webstart
+
+
+
+
diff --git a/out/artifacts/Client/Client.jnlp b/out/artifacts/Client/Client.jnlp
new file mode 100644
index 0000000..eff4374
--- /dev/null
+++ b/out/artifacts/Client/Client.jnlp
@@ -0,0 +1,15 @@
+
+
+
+ Client
+ Unknown
+ Client
+
+
+
+
+
+
+
+
+
diff --git a/out/production/Client/META-INF/MANIFEST.MF b/out/production/Client/META-INF/MANIFEST.MF
index d3e52b4..b851779 100644
--- a/out/production/Client/META-INF/MANIFEST.MF
+++ b/out/production/Client/META-INF/MANIFEST.MF
@@ -1,3 +1,3 @@
Manifest-Version: 1.0
-Main-Class: networking.Client
+Main-Class: game.TicTacToe_Client
diff --git a/out/production/Client/games/TicTacToe/Login.css b/out/production/Client/game/TicTacToe_Client.css
similarity index 100%
rename from out/production/Client/games/TicTacToe/Login.css
rename to out/production/Client/game/TicTacToe_Client.css
diff --git a/out/production/Client/games/TicTacToe/TicTacToe_Grid.png b/out/production/Client/game/TicTacToe_Grid.png
similarity index 100%
rename from out/production/Client/games/TicTacToe/TicTacToe_Grid.png
rename to out/production/Client/game/TicTacToe_Grid.png