I need to create a method to check wether the tictactoe game is PLAYING, DRAW, XWIN or OWIN. However, I am having difficulty writing the code to check if X or O has won, given that the size of the gameboard and the size needed to win (sizeWin) are changing according to the user's input. AND I am forced to use a 1D array for the game board. I simply do not know where to go from here. My latest idea was to use nested for loops to check for a win by row, column or diagonal but I'm not sure how to implement it. If anyone has any tips on how to approach this problem or has any other solutions I would be very grateful
private void setGameState(int i) {
// Check rows
getLines();
getColumns();
getSizeWin();
for (row = 0; row == lines; row++) {
for (col = 0; col == columns; col++) {
}
}
}
public TicTacToeGame(int lines, int columns, int sizeWin) {
// linesXcolumns game, starts with X, need sizeWin in a line/column/diag to win
this.lines = lines;
this.columns = columns;
CellValue currentCellValue = CellValue.X;
this.sizeWin = sizeWin;
// Creating board according to given size
int size = lines * columns;
this.board = new CellValue[size];
// Setting up board to be empty
for (int i = 0; i < size; i++) {
board[i] = CellValue.EMPTY;
}
}
PS. If someone were to call the operator TicTacToe(3,4,3), a game board of 3 lines and 4 columns would print. And the number of X's or O's to win would be 3.
CAM$ java TicTacToe 3 4 3
| | |
---------------
| | |
---------------
| | |
It is a little more complicated than it looks but after you get it it's simple. I've made a function that works just fine:
private static String checkGameState() {
// Looking for errors.
if (rowCount <= 0 || columnCount <= 0) {
return "ERROR: Illegal board size: " + rowCount + "*" + columnCount;
}
if (boradContent.length != rowCount * columnCount) {
return "ERROR: boradContent not compatible with rowSize and columnSize.";
}
if (sizeWin > rowCount && sizeWin > columnCount) {
return "ERROR: Board is too small for this sizeWin: " + sizeWin + ".";
}
String gameState = "PLAYING";
// Checking rows
for (int i = 0; i < rowCount; i++) {
char currentChar = getField(i, 0);
int score = 1;
for (int j = 1; j < columnCount; j++) {
if (currentChar == getField(i, j)) {
score++;
if (score >= sizeWin) {
if (gameState.equals("PLAYING")) {
gameState = currentChar + "WIN";
} else if (!gameState.equals(currentChar + "WIN")) {
gameState = "DRAW";
return gameState;
}
}
} else {
if (j > columnCount - sizeWin) {
break;
}
score = 1;
currentChar = getField(i, j);
}
}
}
// Checking columns
for (int j = 0; j < columnCount; j++) {
char currentChar = getField(0, j);
int score = 1;
for (int i = 1; i < rowCount; i++) {
if (currentChar == getField(i, j)) {
score++;
if (score >= sizeWin) {
if (gameState.equals("PLAYING")) {
gameState = currentChar + "WIN";
} else if (!gameState.equals(currentChar + "WIN")) {
gameState = "DRAW";
return gameState;
}
}
} else {
if (j > rowCount - sizeWin) {
break;
}
score = 1;
currentChar = getField(i, j);
}
}
}
// Checking diagonally
// Checking diagonally - from top-left to bottom-right
for (int i = 0; i < rowCount - sizeWin + 1; i++) {
for (int j = 0; j < columnCount - sizeWin + 1; j++) {
char currentChar = getField(i, j);
int score = 1;
for (int k = 1; k < sizeWin; k++) {
if (currentChar == getField(i + k, j + k)) {
score++;
if (score >= sizeWin) {
if (gameState.equals("PLAYING")) {
gameState = currentChar + "WIN";
} else if (!gameState.equals(currentChar + "WIN")) {
gameState = "DRAW";
return gameState;
}
}
} else {
break;
}
}
}
}
// Checking diagonally - from top-right to bottom-left
for (int i = 0; i < rowCount - sizeWin + 1; i++) {
for (int j = sizeWin -1; j < columnCount; j++) {
char currentChar = getField(i, j);
int score = 1;
for (int k = 1; k < sizeWin; k++) {
if (currentChar == getField(i + k, j - k)) {
score++;
if (score >= sizeWin) {
if (gameState.equals("PLAYING")) {
gameState = currentChar + "WIN";
} else if (!gameState.equals(currentChar + "WIN")) {
gameState = "DRAW";
return gameState;
}
}
} else {
break;
}
}
}
}
return gameState;
}
It is worth to mention that the rowCount, columnCount, sizeWin and boradContent variables are class level variables and i used a getField(int X, int Y)
method that is not a very complicated thing but is more useful. It just converts the given field coordinates to the place in a 1D array and returns it's content:
private static char getField(int X, int Y) {
return boradContent[X * columnCount + Y];
}