Reputation: 33
I have received a project to solve that uses Enums and I am a bit stuck. It's a tic tac toe game that has enums that store the locations of cells in a 3x3 grid table, and enums that store the state of the cells (empty, X, or O). Plus I have an interface for the GameBoard
that returns CellState
: getCellState (CellLocation cellLocation);
My task is to write the Consultant
interface only and I cannot change anything in the code that was provided to me.
I am struggling to check the status of the Board
before each step.
My idea was that X starts the game, I use a for
loop for steps and at each step, I check if nrOfSteps%2==0
. If yes, I set the cellState
to player O. Check if we are at winning position, if we have won or if there's a draw. If not, I will suggest a move.
E.g.
if (nrOfSteps%2!=0){
cState =CellState.OCCUPIED_BY_X;
if (isWon(cState, board)){
throw new IllegalStateException("Player X won!");
} else if (draw(board, locations)){
throw new IllegalStateException("No more empty fields!");
} else
for (int remainingCells = 0; remainingCells <9; remainingCells++) {
if (board.equals(locations[remainingCells]) &&
cState==CellState.EMPTY){
availableCells[index] = locations[remainingCells];
index++;
}
CellLocation cellToTake = availableCells[(int)(Math.random()*
(availableCells.length-1))];
return cellToTake;
}
Now, my problem is that I have tried the following for the isWon
method (partial code validating only the first row for now):
private boolean isWon(CellState player, GameBoard board){
if (board.equals(CellLocation.TOP_LEFT) && cState==player &&
board.equals(CellLocation.TOP_CENTRE) && cState==player &&
board.equals(CellLocation.TOP_RIGHT) && cState==player){
return true;
}
return false;
}
But I have realized that the current Status of the board could not be equal to only one cell as I am checking in the above code. And it obviously cannot be equal to 3 different "only one cell"-s. And I am not even sure if I could be checking if the board had only one cell occupied by player X by this:
board.equals (CellLocation.TOP_LEFT) && cState==player
Could someone please give a tip on how I can incorporate both the CellState
and CellLocation
into one query? Should I use arrays? e.g. CellState[][]
?
Upvotes: 2
Views: 95
Reputation: 680
You can calculate the sums of the cells in the matrix(for each column, row and diagonal). Like this:
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
public class CrossAndZeros {
private static CellState winner;
private static Enum[][] field = new Enum[3][3];
public static void main(String[] args) throws IOException {
for (int i = 0; i < field.length; i++) {
for (int j = 0; j < field[i].length; j++) {
field[i][j] = CellState.values()[new Random().nextInt(3)];
}
}
for (Enum[] enums : field) {
System.out.println(Arrays.toString(enums));
}
System.out.println();
System.out.println("Winner is found: " + isWinnerFound());
System.out.println(winner == null ? "No winner, GAME OVER" : winner);
}
private static boolean isWinnerFound() {
int[] result = calculate();
int count = 0;
for (int win : result) {
if (win == 3) {
winner = CellState.OCCUPIED_BY_X;
return true;
} else if (win == -12) {
winner = CellState.OCCUPIED_BY_O;
return true;
} else if (win == -9 || win == -2 || win == -3) { // This means that the line is spoilt
count++;
}
}
return count == 8; // If all the lines are spoilt, the game is over
}
private static int[] calculate() {
int[] result = new int[8];
for (int i = 0; i < field.length; i++) {
for (int j = 0; j < field[i].length; j++) {
result[i] += getCellOwner(field[j][i]); // a column
result[i + 3] += getCellOwner(field[i][j]); // a row
}
result[field.length * 2] += getCellOwner(field[i][i]); // diagonal
result[field.length * 2 + 1] += getCellOwner(field[i][field.length - i - 1]); // diagonal
}
System.out.println(Arrays.toString(result));
return result;
}
private static int getCellOwner(Enum cell) {
switch ((CellState) cell) {
case OCCUPIED_BY_O:
return -4;
case OCCUPIED_BY_X:
return 1;
case EMPTY:
default:
return 0;
}
}
public enum CellState {
/**
* this cell is occupied by player X
*/
OCCUPIED_BY_X,
/**
* this cell is occupied by player O
*/
OCCUPIED_BY_O,
/**
* this cell is Empty
*/
EMPTY
}
}
Upvotes: 2
Reputation: 33
the CellLocation enum:
public enum CellLocation {
/** The Cell in the top row and leftmost column */
TOP_LEFT,
/** The Cell in the top row and centre column */
TOP_CENTRE,
/** The Cell in the top row and rightmost column */
TOP_RIGHT,
/** The Cell in the centre row and leftmost column */
CENTRE_LEFT,
/** The Cell in the centre row and centre column */
CENTRE_CENTRE,
/** The Cell in the centre row and rightmost column */
CENTRE_RIGHT,
/** The Cell in the bottom row and leftmost column */
BOTTOM_LEFT,
/** The Cell in the bottom row and centre column */
BOTTOM_CENTRE,
/** The Cell in the bottom row and rightmost column */
BOTTOM_RIGHT;
}
the CellState enum:
public enum CellState {
/** this cell is occupied by player X */
OCCUPIED_BY_X,
/** this cell is occupied by player O */
OCCUPIED_BY_O,
/** this cell is Empty */
EMPTY;
}
Upvotes: 1