Merge pull request #2 from cato447/client_logging

Implemented Logging system
This commit is contained in:
cato
2021-02-17 03:48:34 +01:00
committed by GitHub
21 changed files with 198 additions and 404 deletions

View File

@@ -1,8 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="Client:jar">
<output-path>$PROJECT_DIR$/out/artifacts/Client_jar</output-path>
<root id="archive" name="ArcadeMachine.jar">
<element id="module-output" name="ArcadeMachine" />
<root id="archive" name="Client.jar">
<element id="module-output" name="Client" />
</root>
</artifact>
</component>

8
.idea/artifacts/Server_jar.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="Server:jar">
<output-path>$PROJECT_DIR$/out/artifacts/Server_jar</output-path>
<root id="archive" name="Server.jar">
<element id="module-output" name="Server" />
</root>
</artifact>
</component>

View File

@@ -3,6 +3,7 @@
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: networking.Client

View File

@@ -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);
}
}

View File

@@ -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);
}
});
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,3 @@
.root {
-fx-background-image: url("TicTacToe_Grid.png");
}

View File

@@ -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<MouseEvent>() {
@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);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}

View File

@@ -3,6 +3,7 @@
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: networking.Server

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: networking.Client

View File

@@ -0,0 +1,3 @@
.root {
-fx-background-image: url("TicTacToe_Grid.png");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: networking.Server

View File

@@ -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);
}
}

View File

@@ -0,0 +1,7 @@
package client.logging;
public enum LogType {
Log,
Message,
Error
}