Skip to content

Instantly share code, notes, and snippets.

@mAlaliSy
Last active August 21, 2018 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mAlaliSy/efd83bf3f4e150059b84db4ed6c16b33 to your computer and use it in GitHub Desktop.
Save mAlaliSy/efd83bf3f4e150059b84db4ed6c16b33 to your computer and use it in GitHub Desktop.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class XOGame {
private static final int DEPTH = 9;
private static int[] iStart = {0, 1, 2, 0, 0, 0, 0, 0};
private static int[] jStart = {0, 0, 0, 0, 1, 2, 0, 2};
private static int[] iIncrement = {0, 0, 0, 1, 1, 1, 1, 1};
private static int[] jIncrement = {1, 1, 1, 0, 0, 0, 1, -1};
private static Scanner scanner;
public static void main(String[] args) {
scanner = new Scanner(System.in);
System.out.println(
"1\t|\t2\t|\t3\t\n" +
"4\t|\t5\t|\t6\t\n" +
"7\t|\t8\t|\t9\t\n");
char[][] board = new char[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = ' ';
}
}
char winner = ' ';
boolean playerTurn = new Random().nextBoolean();
char playerLetter;
char computerLetter;
if (playerTurn) {
playerLetter = 'X';
computerLetter = 'O';
} else {
playerLetter = 'O';
computerLetter = 'X';
}
if (playerTurn) {
playerTurn(board, playerLetter);
printBoard(board);
}
do {
int bestMove = minMax(board, DEPTH, computerLetter);
board[bestMove / 3][bestMove % 3] = computerLetter;
printBoard(board);
winner = getWinnerIfThere(board);
if (winner == ' ' && !isDraw(board)) {
playerTurn(board, playerLetter);
printBoard(board);
} else {
/*
* Computer Won Or Draw, Break!
* */
break;
}
playerTurn = !playerTurn;
winner = getWinnerIfThere(board);
} while (!isDraw(board) && winner == ' ');
if (winner == ' ') {
System.out.println("Draw");
} else {
System.out.println(winner + " Wins");
}
}
private static void playerTurn(char[][] board, char playerLetter) {
System.out.println("#===============Your Turn===============#");
boolean validMove;
do {
System.out.print("Enter a number for an empty square:");
int move = scanner.nextInt();
if (move > 9 || move < 1 || board[(move - 1) / 3][(move - 1) % 3] != ' ')
validMove = false;
else {
board[(move - 1) / 3][(move - 1) % 3] = playerLetter;
validMove = true;
}
if (!validMove)
System.out.println("Invalid Square!");
} while (!validMove);
}
private static void printBoard(char[][] board) {
System.out.println("-------------------------");
for (int i = 0; i < 3; i++) {
System.out.print("|\t");
for (int j = 0; j < 3; j++) {
System.out.print(board[i][j] + "\t|\t");
}
System.out.println("\n-------------------------");
}
System.out.println();
}
private static List<Integer> availableMoves(char[][] board) {
List<Integer> availableSquares = new ArrayList<>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == ' ')
availableSquares.add(i * 3 + j);
}
}
return availableSquares;
}
private static int evaluate(char[][] board, char player) {
int value = 0;
/*
* For each line of the eight lines
* */
for (int line = 0; line < iStart.length; line++) {
int i = iStart[line];
int j = jStart[line];
/*
* Number of squares in the line for each player
* */
int playersSquare = 0;
int opponentSquare = 0;
int emptySquares = 0;
int k = 0;
do {
char currentSquare = board[i][j];
if (currentSquare != ' ') {
if (currentSquare == player)
playersSquare++;
else
opponentSquare++;
} else
emptySquares++;
i += iIncrement[line];
j += jIncrement[line];
k++;
} while (k < 3);
if (playersSquare == 2 && emptySquares == 1)
value += 10;
else if (playersSquare == 1 && emptySquares == 2)
value += 1;
if (opponentSquare == 2 && emptySquares == 1)
value -= 10;
else if (opponentSquare == 1 && emptySquares == 2)
value -= 1;
}
return value;
}
private static int minMax(char[][] board, int depth, char player) {
double bestMoveValue = Double.NEGATIVE_INFINITY;
int bestMove = 0;
for (int move : availableMoves(board)) {
/*
* Avoid modifying the board because it is needed for the other moves
* */
char[][] copyBoard = copyBoard(board);
copyBoard[move / 3][move % 3] = player;
double moveValue = min(copyBoard, depth - 1, player);
if (moveValue > bestMoveValue) {
bestMoveValue = moveValue;
bestMove = move;
}
}
return bestMove;
}
private static double min(char[][] board, int depth, char player) {
char winner = getWinnerIfThere(board);
if (winner != ' ') {
if (winner == player) {
return Double.POSITIVE_INFINITY;
} else {
return Double.NEGATIVE_INFINITY;
}
}
if (isDraw(board))
return 0;
if (depth == 0) {
return evaluate(board, player);
}
char opponent = player == 'X' ? 'O' : 'X';
double bestMoveValue = Double.POSITIVE_INFINITY;
for (int move : availableMoves(board)) {
char[][] copyBoard = copyBoard(board);
copyBoard[move / 3][move % 3] = opponent;
double moveValue = max(copyBoard, depth - 1, player);
if (moveValue < bestMoveValue) {
bestMoveValue = moveValue;
}
}
return bestMoveValue;
}
private static double max(char[][] board, int depth, char player) {
char winner = getWinnerIfThere(board);
if (winner != ' ') {
if (winner == player) {
return Double.POSITIVE_INFINITY;
} else {
return Double.NEGATIVE_INFINITY;
}
}
if (isDraw(board))
return 0;
if (depth == 0) {
return evaluate(board, player);
}
double bestMoveValue = Double.NEGATIVE_INFINITY;
for (int move : availableMoves(board)) {
char[][] copyBoard = copyBoard(board);
copyBoard[move / 3][move % 3] = player;
double moveValue = min(copyBoard, depth - 1, player);
if (moveValue > bestMoveValue) {
bestMoveValue = moveValue;
}
}
return bestMoveValue;
}
private static char getWinnerIfThere(char[][] board) {
for (int line = 0; line < iStart.length; line++) {
boolean xWin = true;
boolean oWin = true;
int i = iStart[line];
int j = jStart[line];
int k = 0;
do {
char currentSquare = board[i][j];
if (currentSquare != 'X') {
xWin = false;
}
if (currentSquare != 'O') {
oWin = false;
}
i += iIncrement[line];
j += jIncrement[line];
k++;
} while (k < 3);
if (xWin)
return 'X';
if (oWin)
return 'O';
}
return ' ';
}
private static boolean isDraw(char[][] board) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == ' ')
return false;
}
}
return true;
}
private static char[][] copyBoard(char[][] board) {
char[][] copyBoard = new char[3][3];
for (int i = 0; i < 3; i++) {
System.arraycopy(board[i], 0, copyBoard[i], 0, 3);
}
return copyBoard;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment