Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions java/Board.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class Board {
private String[] board;

public Board() {
board = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8"};
}

public void printBoard() {
System.out.println(" " + board[0] + " | " + board[1] + " | " + board[2] +
"\n===+===+===\n" +
" " + board[3] + " | " + board[4] + " | " + board[5] +
"\n===+===+===\n" +
" " + board[6] + " | " + board[7] + " | " + board[8] + "\n");
}

public boolean isValidMove(int spot) {
return !board[spot].equals("X") && !board[spot].equals("O");
}

public void markSpot(int spot, String symbol) {
board[spot] = symbol;
}

public String[] getBoard() {
return board;
}
}

29 changes: 29 additions & 0 deletions java/ComputerPlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;

class ComputerPlayer extends Player {
public ComputerPlayer(String symbol) {
super(symbol);
}


public void makeMove(Board board) {
System.out.println("Computer's turn...");
int bestMove = getBestMove(board);
board.markSpot(bestMove, getSymbol());
}

private int getBestMove(Board board) {

ArrayList<String> availableSpaces = new ArrayList<>();
String[] b = board.getBoard();
for (String s : b) {
if (!s.equals("X") && !s.equals("O")) {
availableSpaces.add(s);
}
}
int n = ThreadLocalRandom.current().nextInt(0, availableSpaces.size());
return Integer.parseInt(availableSpaces.get(n));
}
}

148 changes: 4 additions & 144 deletions java/Game.java
Original file line number Diff line number Diff line change
@@ -1,146 +1,6 @@
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;

/**
* Tic-Tac-Toe: TWo-player console version.
*/
public class Game {
// The game board and the game status
public static String[] board = {"0", "1", "2", "3", "4", "5", "6", "7", "8"};
public static int currentState; // the current state of the game
public static String currentPlayer; // the current player

public static Scanner input = new Scanner(System.in); // the input Scanner

/** The entry main method (the program starts here) */
public static void main(String[] args) {
// Initialize the game-board and current status
initGame();
printBoard();
do {
getHumanSpot();
if (!gameIsOver() && !tie()) {
evalBoard();
}
} while (!gameIsOver() && !tie()); // repeat if not game-over
System.out.print("Game over\n");
}

/** Initializes the game */
public static void initGame() {
currentState = 0; // "playing" or ready to play
currentPlayer = "X"; // cross plays first
}

public static String nextPlayer() {
if (currentPlayer == "X") {
return "O";
} else {
return "X";
}
}

/** Update global variables "board" and "currentPlayer". */
public static void getHumanSpot() {
boolean validInput = false; // for input validation
System.out.print("Enter [0-8]:\n");
do {
int spot = input.nextInt();
if (board[spot] != "X" && board[spot] != "O") {
board[spot] = "X"; // update game-board content
printBoard();
validInput = true; // input okay, exit loop
}
currentPlayer = nextPlayer(); // cross plays first
} while (!validInput); // repeat until input is valid
}

public static void evalBoard() {
boolean foundSpot = false;
do {
if (board[4] == "4") {
board[4] = "O";
foundSpot = true;
} else {
int spot = getBestMove();
if (board[spot] != "X" && board[spot] != "O") {
foundSpot = true;
board[spot] = "O";
} else {
foundSpot = false;
}
}
} while (!foundSpot);
printBoard();
}

/** Return true if the game was just won */
public static boolean gameIsOver() {
return board[0] == board[1] && board[1] == board[2] ||
board[3] == board[4] && board[4] == board[5] ||
board[6] == board[7] && board[7] == board[8] ||
board[0] == board[3] && board[3] == board[6] ||
board[1] == board[4] && board[4] == board[7] ||
board[2] == board[5] && board[5] == board[8] ||
board[0] == board[4] && board[4] == board[8] ||
board[2] == board[4] && board[4] == board[6];
}


public static int getBestMove() {
ArrayList<String> availableSpaces = new ArrayList<String>();
boolean foundBestMove = false;
int spot = 100;
for (String s: board) {
if (s != "X" && s != "O") {
availableSpaces.add(s);
}
}
for (String as: availableSpaces) {
spot = Integer.parseInt(as);
board[spot] = "O";
if (gameIsOver()) {
foundBestMove = true;
board[spot] = as;
return spot;
} else {
board[spot] = "X";
if (gameIsOver()) {
foundBestMove = true;
board[spot] = as;
return spot;
} else {
board[spot] = as;
}
}
}
if (foundBestMove) {
return spot;
} else {
int n = ThreadLocalRandom.current().nextInt(0, availableSpaces.size());
return Integer.parseInt(availableSpaces.get(n));
}
}

/** Return true if it is a draw (no more empty cell) */
// TODO: maybe there is an easeir way to check this
public static boolean tie() {
return board[0] != "0" &&
board[1] != "1" &&
board[2] != "2" &&
board[3] != "3" &&
board[4] != "4" &&
board[5] != "5" &&
board[6] != "6" &&
board[7] != "7" &&
board[8] != "8";
}

/** Print the game board */
public static void printBoard() {
System.out.println(" " + board[0] + " | " + board[1] + " | " + board[2] + "\n===+===+===\n" + " " + board[3] + " | " + board[4] + " | " + board[5] + "\n===+===+===\n" + " " + board[6] + " | " + board[7] + " | " + board[8] + "\n"); // print all the board cells
}

}
interface Game {
void startGame();
void switchPlayers();
}
44 changes: 44 additions & 0 deletions java/GameEngine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class GameEngine implements Game {
private Board board;
private Player player1;
private Player player2;
private Player currentPlayer;
private GameRules gameRules;

public GameEngine(Board board, Player player1, Player player2) {
this.board = board;
this.player1 = player1;
this.player2 = player2;
this.currentPlayer = player1;
this.gameRules = new GameRules(board);
}


public void startGame() {
board.printBoard();
while (true) {
currentPlayer.makeMove(board);
board.printBoard();

if (gameRules.isGameOver()) {
System.out.println("Player " + currentPlayer.getSymbol() + " wins!");
break;
}

if (gameRules.isTie()) {
System.out.println("It's a tie!");
break;
}

switchPlayers();
}
}


public void switchPlayers() {
currentPlayer = (currentPlayer == player1) ? player2 : player1;
}
}



30 changes: 30 additions & 0 deletions java/GameRules.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class GameRules {
private Board board;

public GameRules(Board board) {
this.board = board;
}

public boolean isGameOver() {
String[] b = board.getBoard();
return (b[0].equals(b[1]) && b[1].equals(b[2])) ||
(b[3].equals(b[4]) && b[4].equals(b[5])) ||
(b[6].equals(b[7]) && b[7].equals(b[8])) ||
(b[0].equals(b[3]) && b[3].equals(b[6])) ||
(b[1].equals(b[4]) && b[4].equals(b[7])) ||
(b[2].equals(b[5]) && b[5].equals(b[8])) ||
(b[0].equals(b[4]) && b[4].equals(b[8])) ||
(b[2].equals(b[4]) && b[4].equals(b[6]));
}

public boolean isTie() {
String[] b = board.getBoard();
for (int i = 0; i < b.length; i++) {
if (b[i].equals(String.valueOf(i))) {
return false;
}
}
return true;
}
}

33 changes: 33 additions & 0 deletions java/HumanPlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import java.util.Scanner;

class HumanPlayer extends Player{
private Scanner input = new Scanner(System.in);

public HumanPlayer(String symbol) {
super(symbol);
}


public void makeMove(Board board) {
boolean validInput = false;
int spot;
do {
System.out.print("Player " + getSymbol() + ", enter [0-8]: ");
while (!input.hasNextInt()) {
System.out.println("Please enter a valid number between 0 and 8.");
input.next();
}
spot = input.nextInt();
input.nextLine();

if (board.isValidMove(spot)) {
board.markSpot(spot, getSymbol());
validInput = true;
} else {
System.out.println("Invalid move, try again.");
}
} while (!validInput);
}
}


26 changes: 26 additions & 0 deletions java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

try (Scanner scanner = new Scanner(System.in)) {
System.out.println("Welcome to Tic Tac Toe!");
System.out.print("Choose game mode (1 - Single Player, 2 - Two Player): ");
int mode = scanner.nextInt();

Board board = new Board();
Player player1 = new HumanPlayer("X");
GameEngine gameEngine;

if (mode == 1) {
Player computerPlayer = new ComputerPlayer("O");
gameEngine = new GameEngine(board, player1, computerPlayer);
} else {
Player player2 = new HumanPlayer("O");
gameEngine = new GameEngine(board, player1, player2);
}

gameEngine.startGame();
}
}
}
13 changes: 13 additions & 0 deletions java/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
public abstract class Player {
protected String symbol;

public Player(String symbol) {
this.symbol = symbol;
}

public String getSymbol() {
return symbol;
}

public abstract void makeMove(Board board);
}