Please ,I need some help with this java project.Tic-Tac-Toe game. Naming require
ID: 3718566 • Letter: P
Question
Please ,I need some help with this java project.Tic-Tac-Toe game.
Naming requirements: .?You should have a class named Board in the default package. This class is where you store a Tic Tac Toe board as an array of 9 values.?You should have a class named Game in the default package. This class is where the logic of the game will be. This is the class that will contain a Dictionary for storing Tic Tac Toe boards.?You should have a class named GameInteraction in the default package. This is where the user interaction for the game should be. This is where the main() method should be.
Project Goal:Consider all the possible boards in a game of Tic Tac Toe. For each board position, there is a "best move" (or multiple moves that are tied for best). See programming project 6 in chapter 19 (page 573).Write a program that plays a game of Tic Tac Toe in which you use a dictionary to calculate and store all possible board positions, and the best move associated with that position.
Specifics:?Each board position should be stored as an array (one-or two-dimensional) of 9 values,in the class Board,representing who is occupying each of the 9 squares. Note that a square can be occupied by X or by O, or it can be empty.
?The board position should be the key for the dictionary. The type of array you choose to use is up to you. Choose something that is easy to work with. All you are trying to do is indicate whether each of the 9 squares is X, O, or empty.?In our game, X will always make the first move.
?The value associated with each board should be the best move that can be made in that position. Again, the data type you choose to use is up to you. The move could be represented by a row and column, or by a number in the range 0 to 8. Note that you should not have to indicate WHO moves (it should be obvious from the board). It should only have to indicate where to move. If there is more than one best move, it is up to you which of those best moves you choose to return.
?Important: thus, the key-value pair in your dictionary will be a board (key) and a move (value).
?Although there are 3^9 board configurations (in which each square is X, O, or empty), many of those configurations are not valid in the game of Tic Tac Toe. For example, you cannot have a board in which X appears 7 times and O appears only 1 time. Similarly, you cannot have a board where both players have 3 in a row. You also cannot have a board where O appears 3 times and X appears 2 times (because X goes first). You only need to store valid board positions in your dictionary. It is OK if you want to store ALL positions in the dictionary, but then you should have a plan for what the "best move" value will be for each of those positions, even in the board is not valid.
You can use recursion to generate all valid boards.
You can also use an iterative process.
?
To store the board positions and associated best moves, you must use one of the Dictionary
implementations provided in the file DictionaryImplementations.zip. It is your choice which one
you use.
?
To interact with the user, you may use either a console-based or GUI-based game. Only choose GUI if you are very comfortable working with Java GUIs. If you use a console-based game, allow the human to always go first and always show the board before each human move. The human
should enter her move as a single digit number in the range 0 through 8, where 0, 1, 2 are the top
three cells, 3, 4, 5 are the middle three, and 6, 7, 8 are the top three.
?
You get to decide what methods and constructors you want for the Game class. However, there is one public method that the Game class must have, in order to help me with grading your work:
public int getBestMove(String board)
{
}
This method should take a board in the form of a string, and return the best move as an int in the range 0 through 8. This method should not need much code. It should really just rely on your Dictionary to retrieve the correct move for a given board
(first using the string to create a Board object and use it as a key).
It must be X's move. The best move is to place the X in the lower-right corner. If we number the squares 0 through 8 (by beginning at the top-left and going left-to-right, top-to-bottom), we would represent this board with the string "X--XXOOO-". Thus, getBestMove("X--XXOOO-") should return 8 indicating that the best move is the lower-right corner. Similarly,for the board below, getBestMove("--OXXO--X") should return 0, because the best move for O right now is in the upper-left corner, blocking X from winning.
Just to re-emphasize: the getBestMove() is essential for assisting your instructor in testing your code. It does not mean you must store boards in the dictionary as strings. You could save this method for last if you want because you do not need it for other parts of the program to work.
Explanation / Answer
import java.util.Scanner;
// Defines class Board
class Board
{
// Declares a board of 3 x 3 matrix
static char ticTacToeBoard[][] = new char[3][3];
// Function to create a matrix for board and initializes each cell to null
static void createBoard()
{
// Loops 3 times for rows
for(int ro = 0; ro < 3; ro++)
// Loops 3 times for rows
for(int co = 0; co < 3; co++)
// Sets each cell of the matrix to null
ticTacToeBoard[ro][co] = ' ';
}// End of function
// Displays board
static void displayBoard()
{
// Loops e times
for(int cc = 0; cc < 3; cc++)
{
System.out.printf("%2c | %2c | %2c", ticTacToeBoard[cc][0], ticTacToeBoard[cc][1], ticTacToeBoard[cc][2]);
// Checks if the c value is not 2
if(cc != 2)
// Display hyphon and bars
System.out.printf(" ---|----|--- ");
}// End of for loop
System.out.printf(" ");
}// End of function
}// End of function
// Defines class Game derived from Board
// Implements the logic of tic tac toe game
class Game extends Board
{
// To store row, column and diagonal values
int row, column, diagonal;
// Function to check winning possibility for computer move
boolean winnableCondition(char mat[][])
{
char a, b, c, d, e, f, g, h, i;
// Stores the symbol at 0 row index and 0 column index position in a
a = mat[0][0];
// Stores the symbol at 0 row index and 1 column index position in b
b = mat[0][1];
// Stores the symbol at 0 row index and 2 column index position in c
c = mat[0][2];
// Stores the symbol at 1 row index and 0 column index position in d
d = mat[1][0];
// Stores the symbol at 1 row index and 1 column index position in e
e = mat[1][1];
// Stores the symbol at 1 row index and 2 column index position in f
f = mat[1][2];
// Stores the symbol at 2 row index and 0 column index position in f
g = mat[2][0];
// Stores the symbol at 2 row index and 1 column index position in h
h = mat[2][1];
// Stores the symbol at 2 row index and 2 column index position in i
i = mat[2][2];
// Computer selection row for move
// Checks if symbol 'O' is present in 00 and 01 index position and symbol 'X' is not present in 02 index position
// or symbol 'O' is present in 01 and 02 index position and symbol 'X' is not present in 00 index position
// or symbol 'O' is present in 01 and 02 index position and symbol 'X' is not present in 01 index position
if ( (a=='O' && b=='O' && c!='X') || (b=='O' && c=='O' && a!='X') || (a=='O' && c=='O' && b!='X') )
{
// Computer selection row for move is one
row = 1;
// return true
return true;
}// End of if
if ( (d=='O' && e=='O' && f!='X') || (e=='O' && f=='O' && d!='X') || (d=='O' && f=='O' && e!='X') )
{
// Computer selection row for move is two
row = 2;
return true;
}// End of if
if ( (g=='O' && h=='O' && i!='X') || (h=='O' && i=='O' && g!='X') || (g=='O' && i=='O' && h!='X') )
{
// Computer selection row for move is three
row = 3;
return true;
}// End of if
// Computer selection column for move
// Checks if symbol 'O' is present in 00 and 10 index position and symbol 'X' is not present in 20 index position
// or symbol 'O' is present in 10 and 20 index position and symbol 'X' is not present in 00 index position
// or symbol 'O' is present in 00 and 20 index position and symbol 'X' is not present in 10 index position
if ( (a=='O' && d=='O' && g!='X') || (d=='O' && g=='O' && a!='X') || (a=='O' && g=='O' && d!='X') )
{
// Computer selection column for move is one
column = 1;
return true;
}// End of if
if ( (b=='O' && e=='O' && h!='X') || (e=='O' && h=='O' && b!='X') || (b=='O' && h=='O' && e!='X') )
{
// Computer selection column for move is two
column = 2;
return true;
}// End of if
if ( (c=='O' && f=='O' && i!='X') || (f=='O' && i=='O' && c!='X') || (c=='O' && i=='O' && f!='X') )
{
// Computer selection column for move is three
column = 3;
return true;
}// End of if
// Computer selection diagonal for move
if ( (a=='O' && e=='O' && i!='X') || (e=='O' && i=='O' && a!='X') || (a=='O' && i=='O' && e!='X') )
{
diagonal = 1;
return true;
}// End of if
if ( (g=='O' && e=='O' && c!='X') || (e=='O' && c=='O' && g!='X') || (g=='O' && c=='O' && e!='X') )
{
diagonal = 2;
return true;
}// End of if
return false;
}// End of function
// Function to check the empty column for a given row as a parameter
int emptyColumn(int ro)
{
int res = 0;
// Loops 3 times for each column of given row
for (int co = 0; co < 3; ++co)
{
// Checks if the specified row as parameter and c index position is empty or not
if (ticTacToeBoard[ro][co] == ' ')
// If null return the row index
res = co;
}// End of for loop
return res;
}// End of function
// Function to check the empty row for a given column as a parameter
int emptyRow(int co)
{
int res = 0;
// Loops 3 times for each row of a given column
for (int ro = 0; ro < 3; ++ro)
{
// Checks if the specified column as parameter c and r index position is empty or not
if (ticTacToeBoard[ro][co] == ' ')
// If null return the row index
res = ro;
}// End of for loop
return res;
}// End of function
// Function to check board values for winning
boolean vulnerableCondition(char mat[][])
{
char a, b, c, d, e, f, g, h, i;
// Stores the matrix symbol in variables
a = mat[0][0]; b = mat[0][1]; c = mat[0][2];
d = mat[1][0]; e = mat[1][1]; f = mat[1][2];
g = mat[2][0]; h = mat[2][1]; i = mat[2][2];
// Selects the row number
if ( (a=='X' && b=='X' && c!='O') || (b=='X' && c=='X' && a!='O') || (a=='X' && c=='X' && b!='O') )
{
row = 1;
return true;
}// End of if
if ( (d=='X' && e=='X' && f!='O') || (e=='X' && f=='X' && d!='O') || (d=='X' && f=='X' && e!='O') )
{
row = 2;
return true;
}// End of if
if ( (g=='X' && h=='X' && i!='O') || (h=='X' && i=='X' && g!='O') || (g=='X' && i=='X' && h!='O') )
{
row = 3;
return true;
}// End of if
if ( (a=='X' && d=='X' && g!='O') || (d=='X' && g=='X' && a!='O') || (a=='X' && g=='X' && d!='O') )
{
column = 1;
return true;
}// End of if
if ( (b=='X' && e=='X' && h!='O') || (e=='X' && h=='X' && b!='O') || (b=='X' && h=='X' && e!='O') )
{
column = 2;
return true;
}// End of if
if ( (c=='X' && f=='X' && i!='O') || (f=='X' && i=='X' && c!='O') || (c=='X' && i=='X' && f!='O') )
{
column = 3;
return true;
}// End of if
if ( (a=='X' && e=='X' && i!='O') || (e=='X' && i=='X' && a!='O') || (a=='X' && i=='X' && e!='O') )
{
diagonal = 1;
return true;
}// End of if
if ( (g=='X' && e=='X' && c!='O') || (e=='X' && c=='X' && g!='O') || (g=='X' && c=='X' && e!='O') )
{
diagonal = 2;
return true;
}// End of if
return false;
}// End of function
// Function for computer two move
void computerMove()
{
char temp;
char testBoard[][] = new char[3][3], temporaryBoard[][] = new char[3][3];
// Loops 3 times for row
for (int rr = 0; rr < 3; ++rr)
// Loops 3 times for column
for (int cc = 0; cc < 3; ++cc)
{
// Stores the current row and column index position symbol in a test and temporary matrix
testBoard[rr][cc] = ticTacToeBoard[rr][cc];
temporaryBoard[rr][cc] = ticTacToeBoard[rr][cc];
}// End of for loop
int ro = 0, co = 0;
// Loops 3 times for row
for (ro = 0; ro < 3; ro++)
{
// Loops 3 times for column
for (co = 0; co < 3; co++)
// Checks if the current index position of the row and column is empty
if (ticTacToeBoard[ro][co] == ' ')
{
// Stores the current position symbol in temp
temp = ticTacToeBoard[ro][co];
// Calls the function to get the position for computer's move
if (winnableCondition(testBoard))
{
// Checks for row value set by the winnableCondition function
if (row > 0)
{
// Decides where to put the 'O' symbol for row
if (ticTacToeBoard[row-1][emptyColumn(row-1)] != 'X')
ticTacToeBoard[row-1][emptyColumn(row-1)] = 'O';
return;
}// End of inner if condition
// Checks for column value set by the winnableCondition function
if (column > 0)
{
// Decides where to put the 'O' symbol for column
if (ticTacToeBoard[emptyRow(column-1)][column-1] != 'X')
ticTacToeBoard[emptyRow(column-1)][column-1] = 'O';
return;
}// End of inner if condition
// Checks the diagonal value set by the winnableCondition function
if (diagonal == 1)
{
if ( ticTacToeBoard[0][0] !='X' && ticTacToeBoard[1][1] != 'X' && ticTacToeBoard[2][2] != 'X')
{
ticTacToeBoard[0][0] = 'O';
ticTacToeBoard[1][1] = 'O';
ticTacToeBoard[2][2] = 'O';
}// End of inner if condition
return;
}// End of outer if condition
else
{
if (ticTacToeBoard[0][2] != 'X' && ticTacToeBoard[1][1] != 'X' && ticTacToeBoard[2][0] != 'X')
{
ticTacToeBoard[0][2] = 'O';
ticTacToeBoard[1][1] = 'O';
ticTacToeBoard[2][0] = 'O';
}// End of inner if condition
return;
}// End of else
//return;
}// End of inner if condition
// Stores the symbol in temp in test matrix ro and co index position
testBoard[ro][co] = temp;
}// End of outer most if condition
// Checks the current index position of the board is null
if (ticTacToeBoard[ro][--co]==' ')
{
temp = ticTacToeBoard[ro][co];
if (winnableCondition(testBoard))
{
if (row > 0)
{
if (ticTacToeBoard[row-1][emptyColumn(row-1)] != 'X')
ticTacToeBoard[row-1][emptyColumn(row-1)] = 'O';
return;
}// End of inner if condition
if (column > 0)
{
if (ticTacToeBoard[emptyRow(column-1)][column-1] != 'X')
ticTacToeBoard[emptyRow(column-1)][column-1] = 'O';
return;
}// End of inner if condition
if (diagonal == 1)
{
if ( ticTacToeBoard[0][0] !='X' && ticTacToeBoard[1][1] != 'X' && ticTacToeBoard[2][2] != 'X')
{
ticTacToeBoard[0][0] = 'O';
ticTacToeBoard[1][1] = 'O';
ticTacToeBoard[2][2] = 'O';
}// End of inner if condition
return;
}// End of outer if condition
else
{
if (ticTacToeBoard[0][2] != 'X' && ticTacToeBoard[1][1] != 'X' && ticTacToeBoard[2][0] != 'X')
{
ticTacToeBoard[0][2] = 'O';
ticTacToeBoard[1][1] = 'O';
ticTacToeBoard[2][0] = 'O';
}// End of inner if condition
return;
}// End of else
//return;
}// End of outer if condition
testBoard[ro][co] = temp;
}// End of outer most if condition
}// End of for loop
// Loops 3 times for row
for (ro = 0; ro < 3; ro++)
{
// Loops 3 times for column
for (co = 0; co < 3; co++)
if (ticTacToeBoard[ro][co]==' ')
{
temp = ticTacToeBoard[ro][co];
testBoard[ro][co] = 'O';
if (!vulnerableCondition(testBoard))
break;
testBoard[ro][co] = temp;
}// End of if condition
// Checks if the column value is 3 then subtract one
if(co == 3)
co--;
// Checks if the current index position of the matrix is null
if (ticTacToeBoard[ro][co]==' ')
{
temp = ticTacToeBoard[ro][co];
testBoard[ro][co] = 'O';
if (!vulnerableCondition(testBoard))
break;
testBoard[ro][co] = temp;
}// End of if condition
}// End of for loop
// Checks if the column is greater than zero
if (column > 0)
{
// Decides where to put the 'O' symbol for column
if (ticTacToeBoard[emptyRow(column-1)][column-1] !='X')
ticTacToeBoard[emptyRow(column-1)][column-1] = 'O';
return;
}// End of for loop
if (row > 0)
{
if (ticTacToeBoard[row-1][emptyColumn(row-1)] !='X')
ticTacToeBoard[row-1][emptyColumn(row-1)] = 'O';
return;
}// End of for loop
// Checks if diagonal is one for left diagonal
if (diagonal == 1 )
{
// Checks if the left diagonal symbol is not 'X' then set it to 'O'
if (ticTacToeBoard[0][0] != 'X')
ticTacToeBoard[0][0] = 'O';
if (ticTacToeBoard[1][1] != 'X')
ticTacToeBoard[1][1] = 'O';
if (ticTacToeBoard[2][2] != 'X')
ticTacToeBoard[2][2] = 'O';
return;
}// End of for loop
// Checks if diagonal is two for right diagonal
if (diagonal == 2 )
{
// Checks if the right diagonal symbol is not 'X' then set it to 'O'
if (ticTacToeBoard[0][2] != 'X')
ticTacToeBoard[0][2] = 'O';
if (ticTacToeBoard[1][1] != 'X')
ticTacToeBoard[1][1] = 'O';
if (ticTacToeBoard[2][0] != 'X')
ticTacToeBoard[2][0] = 'O';
return;
}// End of if condition
// Checks if the row is 3 then subtract one
if(ro == 3)
ro--;
if (ticTacToeBoard[ro][co] != 'X')
ticTacToeBoard[ro][co] = 'O';
}// End of function
// Function to identifying winner
char check()
{
// Check rows
for(int ro = 0; ro < 3; ro++)
if(ticTacToeBoard[ro][0] == ticTacToeBoard[ro][1] && ticTacToeBoard[ro][0] == ticTacToeBoard[ro][2])
return ticTacToeBoard[ro][0];
// Check columns
for(int ro = 0; ro < 3; ro++)
if(ticTacToeBoard[0][ro] == ticTacToeBoard[1][ro] && ticTacToeBoard[0][ro] == ticTacToeBoard[2][ro])
return ticTacToeBoard[0][ro];
// Check left diagonals
if(ticTacToeBoard[0][0] == ticTacToeBoard[1][1] && ticTacToeBoard[1][1] == ticTacToeBoard[2][2])
return ticTacToeBoard[0][0];
// Check right diagonals
if(ticTacToeBoard[0][2] == ticTacToeBoard[1][1] && ticTacToeBoard[1][1] == ticTacToeBoard[2][0])
return ticTacToeBoard[0][2];
return ' ';
}// End of function
// Function to return if still some vacant places are there in the board to move
boolean finished(char Board[][])
{
// Loops 3 times for row
for (int ro = 0; ro < 3; ++ro)
{
// Loops 3 times for column
for (int co = 0; co < 3; ++co)
{
// Checks if the current row and column index contains null value then return true
if (Board[ro][co] == ' ')
return false;
}// End of inner for loop
}// End of outer for loop
// Otherwise return true for game to continue
return true;
}// End of function
// Reset the row, column and diagonal values for next game
void reset()
{
row = 0;
column = 0;
diagonal = 0;
}// End of function
// Returns if valid position otherwise returns false
boolean validMove(int row, int col)
{
// Initial status is false
boolean status = false;
// Checks if row is between 0 - 2 and column is between 0 - 2
if((row >= 0 && row <= 2) && (col >= 0 && col <= 2))
{
// Checks if the current row and column index position of the board is not empty
if (ticTacToeBoard[row][col] == ' ')
// Set the status to true for valid position
status = true;
}// End of if condition
// Otherwise set the status to false for invalid move
else
status = false;
// Returns the status
return status;
}// End of function
// Function for players move
void playerMove()
{
// Creates an object of the Scanner class
Scanner sc = new Scanner(System.in);
int rr = 0, cc = 0;
// Loops till valid index position entered by the user
do
{
// Accepts row and column number for player
System.out.print(" Enter the row and column index position: ");
rr = sc.nextInt();
cc = sc.nextInt();
// Calls the function to check valid position
// If valid come out of the loop
if(validMove(rr, cc))
break;
// Otherwise display error message and continue
else
System.out.print(" Invalid move! Try again.");
}while(true);// End of do - while loop
// Assigns the symbol at rr and cc index position of the board
ticTacToeBoard[rr][cc] = 'X';
}// End of the function
}// End of class Game
// Driver class GameInteraction derived from Board
public class GameInteraction extends Board
{
// main function definition
public static void main(String ss[])
{
char done; char c;
// Assigns true to continue
boolean CONTINUE = true;
// Creates an object of the class TicTacToe3x3
Game tt = new Game();
Scanner sc = new Scanner(System.in);
// Loops till CONTINUE value is true
while (CONTINUE)
{
System.out.printf("Computer vs. Human Tic Tac Toe. ");
System.out.printf("Computer will be playing against the Human as 'O' ");
done = ' ';
// Calls the function to create board for playing
createBoard();
// Loops till user choice to continue
do
{
// Calls the function to display the board
displayBoard();
System.out.printf(" ");
// Calls the function for player move
tt.playerMove();
// Calls the function to check winner
done = tt.check();
// Checks if winner found
if(done != ' ')
break;
// Calls the function for Computer Two move
tt.computerMove();
// Calls the function to check winner
done = tt.check();
// Checks if winner found
if(done!= ' ')
break;
// Calls the function to check the board whether there is any vacant space is available or not to move
if (tt.finished(ticTacToeBoard))
{
// Calls the function to display current status of the board
displayBoard();
System.out.printf(" ");
if(done != 'X' && done != 'O')
System.out.printf("Game Draw ");
break;
}// End of if condition
// Reset the board for next game
tt.reset();
} while(done == ' ');
// Checks if done value is 'X' Computer one won
if(done=='X')
System.out.printf("Player Won! ");
// Otherwise Computer two won the game
else if(done == 'O')
System.out.printf("Computer Won ");
// Calls the function to display final board values
displayBoard();
// Accepts user choice to whether continue or not
System.out.printf("Play again? Y/N ");
c = sc.next().charAt(0);
// If user choice is 'N or 'n'
if ( c=='N' || c=='n')
// Set the CONTINUE to false to stop the game
CONTINUE = false;
// Calls the function to reset the board for next game
tt.reset();
}// End of while loop
sc.close();
}// End of main function
}// End of class
Sample Output:
Computer vs. Human Tic Tac Toe.
Computer will be playing against the Human as 'O'
| |
---|----|---
| |
---|----|---
| |
Enter the row and column index position: 0
0
X | O |
---|----|---
| |
---|----|---
| |
Enter the row and column index position: 1
0
X | O |
---|----|---
X | |
---|----|---
O | |
Enter the row and column index position: 1
1
X | O |
---|----|---
X | X | O
---|----|---
O | |
Enter the row and column index position: 2
2
Player Won!
X | O |
---|----|---
X | X | O
---|----|---
O | | X
Play again? Y/N
y
Computer vs. Human Tic Tac Toe.
Computer will be playing against the Human as 'O'
| |
---|----|---
| |
---|----|---
| |
Enter the row and column index position: 0
0
X | O |
---|----|---
| |
---|----|---
| |
Enter the row and column index position: 2
1
X | O | O
---|----|---
| |
---|----|---
| X |
Enter the row and column index position: 1
2
X | O | O
---|----|---
O | | X
---|----|---
| X |
Enter the row and column index position: 1
3
Invalid move! Try again.
Enter the row and column index position: 1
2
Invalid move! Try again.
Enter the row and column index position: 1
1
X | O | O
---|----|---
O | X | X
---|----|---
| X | O
Enter the row and column index position: 0
2
Invalid move! Try again.
Enter the row and column index position: 2
0
X | O | O
---|----|---
O | X | X
---|----|---
X | X | O
Game Draw
X | O | O
---|----|---
O | X | X
---|----|---
X | X | O
Play again? Y/N
n