This commit is contained in:
2021-03-24 23:34:47 +01:00
parent abcfc8d0d6
commit 2ba6dea788
14 changed files with 232 additions and 30 deletions

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -11,6 +11,7 @@ import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import java.awt.*;
import java.util.concurrent.CountDownLatch;
@@ -38,22 +39,9 @@ public class Engine extends Application {
grid.setVgap(75);
}
private Scene setStartingScene(){
scene = new Scene(grid, 900, 900);
grid.add(new javafx.scene.control.Label("Your Username"), 0, 0);
grid.add(new javafx.scene.control.TextField(), 1,0);
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
}
});
return scene;
}
private Scene setPlayingScene() {
scene = new Scene(grid, 900, 900);
scene.getStylesheets().add("res/TicTacToe_Client.css");
scene.getStylesheets().add("game/TicTacToe_Client.css");
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
@@ -149,7 +137,8 @@ public class Engine extends Application {
primaryStage.setTitle("Test");
primaryStage.setResizable(true);
this.initializeGrid();
primaryStage.setScene(this.setPlayingScene());
this.scene = this.setPlayingScene();
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

View File

@@ -1,6 +1,6 @@
import logging.LogType;
import logging.ServerLogger;
import res.TicTacToe_GameRules;
import game.TicTacToe_GameRules;
import java.awt.*;
import java.io.DataInputStream;
@@ -201,12 +201,16 @@ public class TicTacToe_Server {
sendGameState();
serverLogger.printLog("Trigger computer move", LogType.Log);
ticTacToe_gameRules.makeComputerMove();
outstreams.get(client).writeUTF("opponentMove");
outstreams.get(client).flush();
sendGameState();
Thread.sleep(500);
if (ticTacToe_gameRules.gameEnded()){
sendGameState();
Thread.sleep(1000);
this.onGameEnd();
break;
} else {
outstreams.get(client).writeUTF("opponentMove");
outstreams.get(client).flush();
sendGameState();
}
}
@@ -217,6 +221,8 @@ public class TicTacToe_Server {
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;

208
Server/src/ai/MinMax.java Normal file
View File

@@ -0,0 +1,208 @@
package ai;
// Java program to find the
// next optimal move for a player
public class MinMax
{
static char player = 'o', opponent = 'x';
// This function returns true if there are moves
// remaining on the board. It returns false if
// there are no moves left to play.
static Boolean isMovesLeft(char board[][])
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (board[i][j] == '-')
return true;
return false;
}
// This is the evaluation function as discussed
// in the previous article ( http://goo.gl/sJgv68 )
static int evaluate(char b[][])
{
// Checking for Rows for X or O victory.
for (int row = 0; row < 3; row++)
{
if (b[row][0] == b[row][1] &&
b[row][1] == b[row][2])
{
if (b[row][0] == player)
return +10;
else if (b[row][0] == opponent)
return -10;
}
}
// Checking for Columns for X or O victory.
for (int col = 0; col < 3; col++)
{
if (b[0][col] == b[1][col] &&
b[1][col] == b[2][col])
{
if (b[0][col] == player)
return +10;
else if (b[0][col] == opponent)
return -10;
}
}
// Checking for Diagonals for X or O victory.
if (b[0][0] == b[1][1] && b[1][1] == b[2][2])
{
if (b[0][0] == player)
return +10;
else if (b[0][0] == opponent)
return -10;
}
if (b[0][2] == b[1][1] && b[1][1] == b[2][0])
{
if (b[0][2] == player)
return +10;
else if (b[0][2] == opponent)
return -10;
}
// Else if none of them have won then return 0
return 0;
}
// This is the minimax function. It considers all
// the possible ways the game can go and returns
// the value of the board
static int minimax(char board[][],
int depth, Boolean isMax)
{
int score = evaluate(board);
// If Maximizer has won the game
// return his/her evaluated score
if (score == 10)
return score;
// If Minimizer has won the game
// return his/her evaluated score
if (score == -10)
return score;
// If there are no more moves and
// no winner then it is a tie
if (isMovesLeft(board) == false)
return 0;
// If this maximizer's move
if (isMax)
{
int best = -1000;
// Traverse all cells
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
// Check if cell is empty
if (board[i][j]=='-')
{
// Make the move
board[i][j] = player;
// Call minimax recursively and choose
// the maximum value
best = Math.max(best, minimax(board,
depth + 1, !isMax));
// Undo the move
board[i][j] = '-';
}
}
}
return best;
}
// If this minimizer's move
else
{
int best = 1000;
// Traverse all cells
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
// Check if cell is empty
if (board[i][j] == '-')
{
// Make the move
board[i][j] = opponent;
// Call minimax recursively and choose
// the minimum value
best = Math.min(best, minimax(board,
depth + 1, !isMax));
// Undo the move
board[i][j] = '-';
}
}
}
return best;
}
}
// This will return the best possible
// move for the player
public int findBestMove(char board[][])
{
int bestVal = -1000;
int row = -1;
int col = -1;
// Traverse all cells, evaluate minimax function
// for all empty cells. And return the cell
// with optimal value.
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
// Check if cell is empty
if (board[i][j] == '-')
{
// Make the move
board[i][j] = player;
// compute evaluation function for this
// move.
int moveVal = minimax(board, 0, false);
// Undo the move
board[i][j] = '-';
// If the value of the current move is
// more than the best value, then update
// best/
if (moveVal > bestVal)
{
row = i;
col = j;
bestVal = moveVal;
}
}
}
}
return col*3+row;
}
public char[][] convertBoard(String gameState){
char board[][] = new char[3][3];
for (int i = 0; i < gameState.length(); i++) {
int column = i / 3;
int row = i % 3;
board[row][column] = gameState.charAt(i);
}
return board;
}
}

View File

@@ -1,18 +1,21 @@
package res;
package game;
import ai.MinMax;
import java.awt.*;
import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.Random;
public class TicTacToe_GameRules {
private String gameState;
private Integer[][] board;
private MinMax ai;
Point startWin, endWin;
public TicTacToe_GameRules(){
gameState = "---------";
ai = new MinMax();
}
public void resetGameState() {
@@ -55,12 +58,8 @@ public class TicTacToe_GameRules {
}
public void makeComputerMove(){
LinkedList<Integer> emptySpaces = getEmptySpaces();
if (emptySpaces.size() > 0) {
Random random = new Random();
int index = emptySpaces.get(random.nextInt(emptySpaces.size()));
makeMoveOnBoard(index, 1);
}
int index = ai.findBestMove(ai.convertBoard(this.getGameState()));
makeMoveOnBoard(index, 1);
}
private LinkedList<Integer> getEmptySpaces(){

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 137 KiB

View File

@@ -1,6 +1,6 @@
#!/bin/sh
cp ~/Code/ArcadeMachine/out/artifacts/Client_jar/Client.jar ~/Code/ArcadeMachine/deployment/client/package
cd /var/www/html
scp * root@server:/var/www/html/
scp files/* root@server:/var/www/html/files
ssh root@server systemctl restart apache2
scp index.css index.html root@server:/var/www/html/
scp files/Client.jar files/startClient.bat root@server:/var/www/html/files
ssh root@server systemctl restart apache

View File

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB