diff --git a/.idea/artifacts/Client_jar.xml b/.idea/artifacts/Client_jar.xml index 9b55114..4de7eb1 100644 --- a/.idea/artifacts/Client_jar.xml +++ b/.idea/artifacts/Client_jar.xml @@ -1,8 +1,8 @@ $PROJECT_DIR$/out/artifacts/Client_jar - - + + \ No newline at end of file diff --git a/.idea/artifacts/Server_jar.xml b/.idea/artifacts/Server_jar.xml new file mode 100644 index 0000000..a469dd7 --- /dev/null +++ b/.idea/artifacts/Server_jar.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/out/artifacts/Server_jar + + + + + \ No newline at end of file diff --git a/Client/Client.iml b/Client/Client.iml index c90834f..17ba59d 100644 --- a/Client/Client.iml +++ b/Client/Client.iml @@ -3,6 +3,7 @@ + diff --git a/Client/src/META-INF/MANIFEST.MF b/Client/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..d3e52b4 --- /dev/null +++ b/Client/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: networking.Client + diff --git a/Client/src/games/Board.java b/Client/src/games/Board.java deleted file mode 100644 index da92e49..0000000 --- a/Client/src/games/Board.java +++ /dev/null @@ -1,148 +0,0 @@ -package games; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.Arrays; - -public class Board extends JPanel implements ActionListener { - - private final int B_WIDTH = 900; - private final int B_HEIGHT = 900; - private final int TILE_X = 300; - private final int TILE_Y = 300; - private final int DELAY = 50; - - private boolean ended = false; - private boolean gameWon = false; - - int[] oldPlayfield; - - private Timer timer; - private Game game; - private Painter painter; - - public Board(){ - initBoard(); - } - - private void initBoard(){ - painter = new Painter(B_WIDTH,B_HEIGHT); - - addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - super.mouseClicked(e); - int column = e.getX()/TILE_X; - int row = e.getY()/TILE_Y; - game.place(column * 3 + row, 1); - } - }); - - setBackground(Color.BLACK); - setFocusable(true); - setPreferredSize(new Dimension(B_WIDTH,B_HEIGHT)); - - initGame(); - } - - private void initGame(){ - game = new Game(); - oldPlayfield = game.getPlayfield().clone(); - timer = new Timer(DELAY, this); - timer.start(); - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - painter.paintGrid(g); - updateBoard(g); - } - - private void updateBoard(Graphics g){ - int actions = 0; - for (int column = 0; column < 3; column++) { - for (int row = 0; row < 3; row++) { - if (game.getPlayfield()[actions] == 1) { - painter.drawX(g, column, row); - } else if (game.getPlayfield()[actions] == -1) { - painter.drawO(g, column, row); - } - actions++; - } - } - if (gameWon) { - painter.paintWinnerLine(g); - } - } - - public void resetBoard(){ - for (int i = 0; i < game.getPlayfield().length; i++){ - game.setPlayfield(i, 0); - } - timer.start(); - oldPlayfield = game.getPlayfield().clone(); - game.setTurnTaken(false); - gameWon = false; - repaint(); - } - - public void setWinningLine(){ - painter.setWinningX1(game.getWinningX1()); - painter.setWinningY1(game.getWinningY1()); - painter.setWinningX2(game.getWinningX2()); - painter.setWinningY2(game.getWinningY2()); - } - - //game controlling method - @Override - public void actionPerformed(ActionEvent e) { - Thread actionThread = new Thread(){ - @Override - public void run() { - //check if game state evaluation needs to be done - if (isChanged(oldPlayfield)) { - gameWon = game.checkWin(); - //repaint board if not won - if (!gameWon) { - repaint(); - oldPlayfield = game.getPlayfield().clone(); - } - //stop timer if game won - if (gameWon || game.emptyTiles() == 0) { - if (gameWon) { - setWinningLine(); - } - repaint(); - timer.stop(); - try { - Thread.sleep(1000); - int n = JOptionPane.showConfirmDialog(null, "Do you want to play again?"); - if (n == 0){ - resetBoard(); - } else { - System.exit(0); - } - } catch (InterruptedException interruptedException) { - interruptedException.printStackTrace(); - } - } - } - //check if computer needs to take a turn - if (game.isTurnTaken()){ - game.setTurnTaken(false); - game.computersTurn(); - } - } - }; - actionThread.start(); - } - - private boolean isChanged(int[] playfield){ - return !Arrays.equals(game.getPlayfield(), playfield); - } -} diff --git a/Client/src/games/Executor.java b/Client/src/games/Executor.java deleted file mode 100644 index 00d5d07..0000000 --- a/Client/src/games/Executor.java +++ /dev/null @@ -1,28 +0,0 @@ -package games; - -import javax.swing.*; - -public class Executor extends JFrame { - public Executor(){ - initUI(); - } - - private void initUI(){ - Board board = new Board(); - setTitle("TicTacToe - MinMax"); - add(board); - pack(); - setDefaultCloseOperation(EXIT_ON_CLOSE); - setLocationRelativeTo(null); - } - - public static void main(String[] args) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - Executor exc = new Executor(); - exc.setVisible(true); - } - }); - } -} diff --git a/Client/src/games/Game.java b/Client/src/games/Game.java deleted file mode 100644 index b3a7a07..0000000 --- a/Client/src/games/Game.java +++ /dev/null @@ -1,118 +0,0 @@ -package games; - -import javax.swing.*; - -public class Game { - - private int[] playfield; - private boolean turnTaken = false; - private int winningX1,winningY1,winningX2,winningY2; - - public Game(){ - playfield = new int[9]; - } - - public void place(int position, int player){ - if (playfield[position] == 0){ - playfield[position] = player; - if (player == 1) { - turnTaken = true; - } - } else { - JOptionPane.showInternalMessageDialog(null,"Tile is already taken"); - } - } - - public void computersTurn(){ - boolean isPlaced = false; - try { - Thread.sleep(750); - } catch (InterruptedException e) { - e.printStackTrace(); - } - while(!isPlaced){ - int random = (int) (Math.random() * 9); - // if field is free - if (playfield[random] == 0) { - place(random, -1); - isPlaced = true; - } - } - } - - - public boolean checkWin() { - //only check if winning is possible - if (emptyTiles() < 5) { - for (int i = 0; i < 3; i++) { - //horizontal - if ((playfield[i] == playfield[i + 3] && playfield[i] != 0) && (playfield[i] == playfield[i + 6])) { - winningX1 = 75; - winningX2 = 825; - winningY1 = winningY2 = i * 300 + 150; - return true; - } - //vertical - else if ((playfield[i * 3] == playfield[i * 3 + 1] && playfield[i * 3] != 0) && (playfield[i * 3] == playfield[i * 3 + 2])) { - winningY1 = 75; - winningY2 = 825; - winningX1 = winningX2 = i * 300 + 150; - return true; - } - } - //diagonal - if ((playfield[2] == playfield[4] && playfield[2] != 0) && (playfield[2] == playfield[6])){ - winningX2 = winningY1 = 75; - winningX1 = winningY2 = 825; - return true; - } else if ((playfield[0] == playfield[4] && playfield[0] != 0) && (playfield[0] == playfield[8])){ - winningX1 = winningY1 = 75; - winningX2 = winningY2 = 825; - return true; - } - } - return false; - } - - public int emptyTiles(){ - int n = 9; - for (int i = 0; i < playfield.length; i++){ - if (playfield[i] != 0){ - n -= 1; - } - } - return n; - } - - public boolean isTurnTaken() { - return turnTaken; - } - - public void setTurnTaken(boolean turnTaken) { - this.turnTaken = turnTaken; - } - - public void setPlayfield(int position, int value) { - playfield[position] = value; - } - - public int[] getPlayfield() { - return playfield; - } - - public int getWinningX1() { - return winningX1; - } - - public int getWinningX2() { - return winningX2; - } - - public int getWinningY1() { - return winningY1; - } - - public int getWinningY2() { - return winningY2; - } -} diff --git a/Client/src/games/Painter.java b/Client/src/games/Painter.java deleted file mode 100644 index 109bb2d..0000000 --- a/Client/src/games/Painter.java +++ /dev/null @@ -1,75 +0,0 @@ -package games; - -import java.awt.*; - -public class Painter { - - private final int TILE_X; - private final int TILE_Y; - - private int winningX1, winningY1, winningX2, winningY2; - - public Painter(int boardWidth, int boardHeight){ - TILE_X = boardWidth/3; - TILE_Y = boardHeight/3; - } - - public void drawX(Graphics g, int column, int row) { - Graphics2D g2d = (Graphics2D) g; - - int nextColumn = column + 1; - int nextRow = row + 1; - int x1 = column * TILE_X + 25; - int x2 = nextColumn * TILE_Y - 25; - int y1 = row * TILE_X + 25; - int y2 = nextRow * TILE_Y - 25; - - g2d.setColor(Color.WHITE); - g2d.setStroke(new BasicStroke(5)); - g2d.drawLine(x1, y1, x2, y2); - g2d.drawLine(x1, y2, x2, y1); - } - - public void drawO(Graphics g, int column, int row){ - int x = column * TILE_X + 25; - int y = row * TILE_Y + 25; - g.drawOval(x,y,250,250); - } - - public void paintGrid(Graphics g){ - Graphics2D g2d = (Graphics2D)g; - g2d.setColor(Color.WHITE); - g2d.setStroke(new BasicStroke(10)); - //horizontal - for (int i = 1; i < 3; i++) { - g2d.drawLine(0, TILE_Y*i, TILE_X*3, TILE_Y*i); - } - //vertical - for (int i = 1; i < 3; i++){ - g2d.drawLine(TILE_X*i, 0, TILE_X*i, TILE_Y*3); - } - } - - public void paintWinnerLine(Graphics g){ - Graphics2D g2d = (Graphics2D) g; - g2d.setColor(Color.RED); - g2d.setStroke(new BasicStroke(40)); - g2d.drawLine(winningX1, winningY1, winningX2, winningY2); - } - - public void setWinningX1(int winningX1) { - this.winningX1 = winningX1; - } - - public void setWinningX2(int winningX2) { - this.winningX2 = winningX2; - } - - public void setWinningY1(int winningY1) { - this.winningY1 = winningY1; - } - - public void setWinningY2(int winningY2) { - this.winningY2 = winningY2; - } -} diff --git a/Client/src/games/TicTacToe/TicTacToe_Client.css b/Client/src/games/TicTacToe/TicTacToe_Client.css new file mode 100644 index 0000000..f89ce7e --- /dev/null +++ b/Client/src/games/TicTacToe/TicTacToe_Client.css @@ -0,0 +1,3 @@ +.root { + -fx-background-image: url("TicTacToe_Grid.png"); +} \ No newline at end of file diff --git a/Client/src/games/TicTacToe/TicTacToe_Client.java b/Client/src/games/TicTacToe/TicTacToe_Client.java new file mode 100644 index 0000000..5828e0a --- /dev/null +++ b/Client/src/games/TicTacToe/TicTacToe_Client.java @@ -0,0 +1,103 @@ +package games.TicTacToe; + +import javafx.application.Application; +import javafx.event.EventHandler; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.GridPane; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; +import javafx.scene.text.Text; +import javafx.stage.Stage; +import networking.Client; + +public class TicTacToe_Client extends Application { + + GridPane grid; + Client client; + + private void initializeGrid(){ + grid = new GridPane(); + grid.setMinSize(900,900); + grid.setAlignment(Pos.CENTER); + grid.setHgap(150); + grid.setVgap(75); + grid.setGridLinesVisible(true); + } + + + + private void drawCross(int column, int row){ + Text cross = new Text("X"); + cross.setFont(Font.font("Tahoma", FontWeight.NORMAL, 200)); + grid.add(cross, column, row); + } + + private void drawCircle(int column, int row){ + Text circle = new Text("O"); + circle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 200)); + grid.add(circle, column, row); + } + + + private void drawEmptyField(int column, int row) { + Text emptyField = new Text(" "); + emptyField.setFont(Font.font("Tahoma", FontWeight.NORMAL, 200)); + grid.add(emptyField, column, row); + } + + private void drawBoard(String gameState){ + if (gameState.length() != 9){ + System.err.println("Wrong length of gameState string"); + return; + } + for (int i = 0; i < gameState.length(); i++){ + int column = i % 3; + int row = i / 3; + if (gameState.charAt(i) == 'x'){ + this.drawCross(column, row); + } else if (gameState.charAt(i) == 'o'){ + this.drawCircle(column, row); + } else { + this.drawEmptyField(column, row); + } + + } + } + + private Scene setScene(){ + Scene scene = new Scene(grid, 900, 900); + scene.getStylesheets().add + (TicTacToe_Client.class.getResource("TicTacToe_Client.css").toExternalForm()); + scene.setOnMousePressed(new EventHandler() { + @Override + public void handle(MouseEvent event) { + client.sendToServer(String.format("(%f|%f)", event.getX(), event.getY())); + client.getGameState(); + } + }); + return scene; + } + + @Override + public void start(Stage primaryStage) { + primaryStage.setTitle("TicTacToe"); + primaryStage.setResizable(false); + + this.initializeGrid(); + + primaryStage.setScene(this.setScene()); + + primaryStage.show(); + + this.drawBoard("---------"); + + client = new Client("localhost", 2589, "TestClient"); + client.handshake(); + } + + public static void main(String[] args) { + launch(args); + } +} diff --git a/Client/src/games/TicTacToe/TicTacToe_Grid.png b/Client/src/games/TicTacToe/TicTacToe_Grid.png new file mode 100644 index 0000000..5dbb56d Binary files /dev/null and b/Client/src/games/TicTacToe/TicTacToe_Grid.png differ diff --git a/Client/src/logging/ClientLogger.java b/Client/src/logging/ClientLogger.java index 96269e3..622f133 100644 --- a/Client/src/logging/ClientLogger.java +++ b/Client/src/logging/ClientLogger.java @@ -44,4 +44,12 @@ public class ClientLogger { public void printLog(String message, boolean success, LogType logType){ this.printLog(message, "server", success, logType); } + + public void printConfirmation(int code){ + if (code == 200){ + 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 b987212..bf6ab0c 100644 --- a/Client/src/networking/Client.java +++ b/Client/src/networking/Client.java @@ -2,7 +2,6 @@ package networking; import logging.ClientLogger; import logging.LogType; - import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -18,10 +17,6 @@ public class Client { private String serverName; private boolean success; - public static final String ANSI_RESET = "\u001B[0m"; - public static final String ANSI_CYAN = "\u001B[36m"; - - public Client(String ip, int port, String name) { try { scanner = new Scanner(System.in); @@ -39,13 +34,12 @@ public class Client { public void handshake() { try { - out.writeInt(15315); + out.writeInt(165313125); out.flush(); success = in.readInt() == 200; if (success){ out.writeUTF(name); serverName = in.readUTF(); - System.out.println(serverName); clientLogger.printLog("You successfully connected to me", serverName, success, LogType.Log); } else { clientLogger.printLog("Connection failed try again", success, LogType.Log); @@ -56,21 +50,6 @@ public class Client { } } - public void oneSidedMessage() { - while (true) { - System.out.print("input> "); - String message = scanner.nextLine(); - try { - out.writeUTF(message); - System.out.println(in.readInt()); - } catch (IOException e) { - e.printStackTrace(); - } - if(message.equalsIgnoreCase("exit()")) - break; - } - } - public void sendToServer(String message) { try { out.writeUTF(message); @@ -81,21 +60,20 @@ public class Client { } } + public String getGameState(){ + try { + out.writeUTF("gamestate"); + return in.readUTF(); + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } + public boolean hasSucceeded() { return success; } public String getName(){return name;} - - public static void main(String[] args) { - Client client; - if (args.length > 0) { - client = new Client("localhost", 2589, args[0]); - } else { - client = new Client("localhost", 2589, "GenericName"); - } - client.handshake(); - client.oneSidedMessage(); - } } \ No newline at end of file diff --git a/Server/Server.iml b/Server/Server.iml index c90834f..17ba59d 100644 --- a/Server/Server.iml +++ b/Server/Server.iml @@ -3,6 +3,7 @@ + diff --git a/Server/src/META-INF/MANIFEST.MF b/Server/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..9ae8574 --- /dev/null +++ b/Server/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: networking.Server + diff --git a/out/production/Client/META-INF/MANIFEST.MF b/out/production/Client/META-INF/MANIFEST.MF new file mode 100644 index 0000000..d3e52b4 --- /dev/null +++ b/out/production/Client/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: networking.Client + diff --git a/out/production/Client/games/TicTacToe/Login.css b/out/production/Client/games/TicTacToe/Login.css new file mode 100644 index 0000000..f89ce7e --- /dev/null +++ b/out/production/Client/games/TicTacToe/Login.css @@ -0,0 +1,3 @@ +.root { + -fx-background-image: url("TicTacToe_Grid.png"); +} \ No newline at end of file diff --git a/out/production/Client/games/TicTacToe/TicTacToe_Grid.png b/out/production/Client/games/TicTacToe/TicTacToe_Grid.png new file mode 100644 index 0000000..5dbb56d Binary files /dev/null and b/out/production/Client/games/TicTacToe/TicTacToe_Grid.png differ diff --git a/out/production/Server/META-INF/MANIFEST.MF b/out/production/Server/META-INF/MANIFEST.MF new file mode 100644 index 0000000..9ae8574 --- /dev/null +++ b/out/production/Server/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: networking.Server + diff --git a/src/client/logging/ClientLogger.java b/src/client/logging/ClientLogger.java new file mode 100644 index 0000000..7d06fe5 --- /dev/null +++ b/src/client/logging/ClientLogger.java @@ -0,0 +1,39 @@ +package client.logging; + +import java.sql.Timestamp; + +public class ClientLogger { + + private static final String ANSI_RESET = "\u001B[0m"; + private static final String ANSI_BLACK = "\u001B[30m"; + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_YELLOW = "\u001B[33m"; + private static final String ANSI_BLUE = "\u001B[34m"; + private static final String ANSI_PURPLE = "\u001B[35m"; + private static final String ANSI_CYAN = "\u001B[36m"; + private static final String ANSI_WHITE = "\u001B[37m"; + + public void printLog(String message, String name, LogType logType, boolean success){ + switch (logType){ + case Log: + System.out.printf(ANSI_CYAN + "%s %s%n"+ANSI_RESET, new Timestamp(System.currentTimeMillis()), message); + break; + + case Error: + System.out.printf(ANSI_RED + "%s %s%n"+ ANSI_RESET, new Timestamp(System.currentTimeMillis()), message); + break; + + case Message: + System.out.printf(ANSI_WHITE + " %s %s %s%n" +ANSI_RESET, new Timestamp(System.currentTimeMillis()), name, message); + break; + + default: + System.err.println("NO VALID LOGTYPE GIVEN");; + } + } + + public void printLog(String message, LogType logType, boolean success){ + this.printLog(message, "", logType, success); + } +} diff --git a/src/client/logging/LogType.java b/src/client/logging/LogType.java new file mode 100644 index 0000000..a212134 --- /dev/null +++ b/src/client/logging/LogType.java @@ -0,0 +1,7 @@ +package client.logging; + +public enum LogType { + Log, + Message, + Error +}