Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

In Java, write a class (and a client class to test it) that encapsulates a tic-t

ID: 3794523 • Letter: I

Question

In Java, write a class (and a client class to test it) that encapsulates a tic-tac-toe board. A tic-tac-toe board looks like a table of three rows and three columns partially or completely filled with the characters X and O. At any point, a cell of that table could be empty or could contain an X or an O. You should have one instance variable, a two-dimensional array of values representing the tic-tac-toe board.

This game should involve one human player vs. the computer (aka, it should be a one player game). At the start of each game, randomly select if the computer will play X or O and who (i.e. human or computer) will make the first move.

Your default constructor should instantiate the array so that it represents an empty board.

You should include the following methods:

a method that generates a valid play by the computer and displays the board after each play.

a method that requests a valid play from the human and displays the board after each play.

a method to display the tic-tac-toe board.

a method checking if a player has won based on the contents of the board; this method takes no parameter. It returns X if the "X player" has won, O if the "O player" has won, T if the game was a tie. A player wins if he or she has placed an X (or an O) in all cells in a row, all cells in a column, or all cells in one of the diagonals.

NOTE: Be sure to display the board after each move. You must provide clear prompts for the human player to select a space on the tic-tac-toe board.

Input Validation: Verify that all moves by the human player are to a valid space on the tic-tac-toe board. An incorrect choice should not halt or terminate the game. Also, no human vs. human mode should be included in the program. Just Human vs. the Computer is what the game should only involve.

Explanation / Answer

The following program does not consider X or O but considers computers turn as 1 and human's turn as 2. Also it does not return X or O as the winners but tells if the computer is winner or human is the winner. For these two changes I needed some more time which I didn't have. This solution uses minmax approach used in game bot designing. Please revert in case of any query.

package tic.tac.toe;

import java.util.Random;

public class TicTacToe {
   public static void main(String[] args) {
Board b = new Board();
Random rand = new Random();
  
b.showBoard();
  
int choice = rand.nextInt(2)+1;
if(choice == 1){
   System.out.println("Computer is starting the game !! ");
playFirstComputerMove(b, rand);
}
  
while (!b.isGameOver()) {
System.out.println("Human's move: ");
playValidUserMove(b);
if (b.isGameOver()) {
break;
}
playValidComputerMove(b);
}
if (b.hasXWon()) {
System.out.println("you lost!");
} else if (b.hasOWon()) {
System.out.println("You win! ");
} else {
System.out.println("It's a draw!");
}
}

   private static void playFirstComputerMove(Board b, Random rand) {
       Coordinate p = new Coordinate(rand.nextInt(3), rand.nextInt(3));
       b.placeAMove(p, 1);
       b.showBoard();
   }

   private static void playValidComputerMove(Board b) {
       b.callMinimax(0, 1);
       b.placeAMove(b.returnBestMove(), 1);
       b.showBoard();
   }

   private static void playValidUserMove(Board b) {
       Coordinate userMove = new Coordinate(b.scan.nextInt(), b.scan.nextInt());
       b.placeAMove(userMove, 2); //2 for O and O is the user
       b.showBoard();
   }
  
  
}

package tic.tac.toe;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Board {
     
List<Coordinate> availableCoordinates;
Scanner scan ;
int[][] board ;

public Board() {
   scan= new Scanner(System.in);
   board=new int[3][3];
}

public boolean isGameOver() {
//Game is over is someone has won, or board is full (draw)
return (hasXWon() || hasOWon() || getAvailableStates().isEmpty());
}

public boolean hasXWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == 1) || (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == 1)) {
//System.out.println("X Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if (((board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == 1)
|| (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] == 1))) {
// System.out.println("X Row or Column win");
return true;
}
}
return false;
}

public boolean hasOWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == 2) || (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == 2)) {
// System.out.println("O Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if ((board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == 2)
|| (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] == 2)) {
// System.out.println("O Row or Column win");
return true;
}
}

return false;
}

public List<Coordinate> getAvailableStates() {
availableCoordinates = new ArrayList<>();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0) {
availableCoordinates.add(new Coordinate(i, j));
}
}
}
return availableCoordinates;
}

public void placeAMove(Coordinate Coordinate, int player) {
board[Coordinate.x][Coordinate.y] = player; //player = 1 for X, 2 for O
}

public Coordinate returnBestMove() {
int MAX = -100000;
int best = -1;

for (int i = 0; i < rootsChildrenScores.size(); ++i) {
if (MAX < rootsChildrenScores.get(i).rank) {
MAX = rootsChildrenScores.get(i).rank;
best = i;
}
}

return rootsChildrenScores.get(best).coordinate;
}

void takeHumanInput() {
System.out.println("Your move: ");
int x = scan.nextInt();
int y = scan.nextInt();
Coordinate Coordinate = new Coordinate(x, y);
placeAMove(Coordinate, 2);
}

public void showBoard() {
System.out.println();

for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
System.out.print(board[i][j] + " ");
}
System.out.println();

}
}

public int returnMin(List<Integer> list) {
int min = Integer.MAX_VALUE;
int index = -1;
for (int i = 0; i < list.size(); ++i) {
if (list.get(i) < min) {
min = list.get(i);
index = i;
}
}
return list.get(index);
}

public int returnMax(List<Integer> list) {
int max = Integer.MIN_VALUE;
int index = -1;
for (int i = 0; i < list.size(); ++i) {
if (list.get(i) > max) {
max = list.get(i);
index = i;
}
}
return list.get(index);
}

List<CoordinatesAndRanks> rootsChildrenScores;

public void callMinimax(int depth, int turn){
rootsChildrenScores = new ArrayList<>();
minimax(depth, turn);
}
  
public int minimax(int depth, int turn) {

if (hasXWon()) return +1;
if (hasOWon()) return -1;

List<Coordinate> CoordinatesAvailable = getAvailableStates();
if (CoordinatesAvailable.isEmpty()) return 0;

List<Integer> scores = new ArrayList<>();

for (int i = 0; i < CoordinatesAvailable.size(); ++i) {
Coordinate Coordinate = CoordinatesAvailable.get(i);

if (turn == 1) { //X's turn select the highest from below minimax() call
placeAMove(Coordinate, 1);
int currentScore = minimax(depth + 1, 2);
scores.add(currentScore);

if (depth == 0)
rootsChildrenScores.add(new CoordinatesAndRanks(currentScore, Coordinate));
  
} else if (turn == 2) {//O's turn select the lowest from below minimax() call
placeAMove(Coordinate, 2);
scores.add(minimax(depth + 1, 1));
}
board[Coordinate.x][Coordinate.y] = 0; //Reset this Coordinate
}
return turn == 1 ? returnMax(scores) : returnMin(scores);
}
}

package tic.tac.toe;

class Coordinate {

Integer x, y;

public Coordinate(Integer x, Integer y) {
this.x = x;
this.y = y;
}

}

package tic.tac.toe;

public class CoordinatesAndRanks {

   int rank;
   Coordinate coordinate;

   CoordinatesAndRanks(int rank, Coordinate coordinate) {
   this.rank = rank;
   this.coordinate = coordinate;
   }
  
}

In case of any doubts please comment on the solution.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote