According to the requirements from my learning platform works fine apart from when the input command is "start easy easy" and the result is draw program doesn't stop and nothing happens after that and I have to force end the program. In all other cases program continues to run unless user types in "exit". Please help and also if you can suggest how to improve my code and in terms of OOP that will be great. Thank you.
import java.util.Arrays;
import java.util.Scanner;
import java.util.Random;
public class Main {
public final static Scanner scan = new Scanner(System.in);
public static Random random = new Random();
public static char[][] gameBoard;
public static String level = "";
public static void main(String[] args) {
// write your code here
menu();
}
public static String[] getParams() {
String[] params = scan.nextLine().split(" ");
return params;
}
public static void menu() {
while (true) {
System.out.println("Input command: ");
String[] params = getParams();
if (params.length == 3) {
if ("start".equals(params[0])) {
level = params[1].equals("easy") ? params[1] : params[2];
start(params[1], params[2]);
continue;
}
} else if (params.length == 1) {
if ("exit".equals(params[0])) {
break;
} else {
System.out.println("Bad parameters!");
continue;
}
} else {
System.out.println("Bad parameters!");
continue;
}
break;
}
}
public static void start(String str1, String str2) {
gameBoard = to2dArray("_________");
drawBoard(gameBoard);
char player1 = 'X';
char player2 = 'O';
if ("user".equals(str1)) {
while (!gameFinished(gameBoard)) {
drawBoard(playerMove(gameBoard, player1));
gameState(gameBoard);
drawBoard(computerMove(gameBoard, player2));
gameState(gameBoard);
}
} else if ("user".equals(str2)) {
while (!gameFinished(gameBoard)) {
gameState(computerMove(gameBoard, player2));
drawBoard(gameBoard);
gameState(playerMove(gameBoard, player1));
drawBoard(gameBoard);
}
} else if ("user".equals(str1) && "user".equals(str2)) {
while (!gameFinished(gameBoard)) {
drawBoard(playerMove(gameBoard, player1));
gameState(gameBoard);
drawBoard(playerMove(gameBoard, player2));
gameState(gameBoard);
}
} else {
while (!gameFinished(gameBoard)) {
drawBoard(computerMove(gameBoard, player1));
gameState(gameBoard);
drawBoard(computerMove(gameBoard, player2));
gameState(gameBoard);
}
}
}//startGame method
public static int[] getRandomNumber() {
int[] computerCoords = new int[2];
while (true) {
int a = random.nextInt((3 - 1) + 1) + 1;
int b = random.nextInt((3 - 1) + 1) + 1;
if (gameBoard[a - 1][b - 1] == 'X' || gameBoard[a - 1][b - 1] == 'O') {
continue;
} else {
computerCoords[0] = a;
computerCoords[1] = b;
break;
}
}
return computerCoords;
}
public static char[][] computerMove(char[][] gameBoard, char computer) {
int[] arr = getRandomNumber();
int row = arr[0] - 1;
int col = arr[1] - 1;
if (!gameFinished(gameBoard)) {
System.out.println("Making move level \"" + level + "\"");
gameBoard[row][col] = computer;
}
return gameBoard;
}
public static char[][] playerMove(char[][] gameBoard, char player) {
int index = 0;
int row, column;
while (true) {
System.out.println("Enter the coordinates: ");
String[] coordinates = scan.nextLine().split(" ");
try {
row = Integer.parseInt(coordinates[0]);
column = Integer.parseInt(coordinates[1]);
if ((row < 1 || column < 1) || (row > 3 || column > 3)) {
System.out.println("Coordinates should be from 1 to 3!");
continue;
}
row -= 1;
column -= 1;
if (gameBoard[row][column] != '_') {
System.out.println("This cell is occupied! Choose another one!");
continue;
}
gameBoard[row][column] = player;
return gameBoard;
} catch (NumberFormatException e) {
System.out.println("You should enter numbers!");
continue;
}
}//while loop ends here
}// playerMove() ends
public static char[][] to2dArray(String s) {
char[][] twoDArray = new char[3][3];
int index = 0;
for (int i = 0; i < twoDArray.length; i++) {
for (int j = 0; j < twoDArray[i].length; j++) {
twoDArray[i][j] = s.charAt(index);
index++;
}
}
return twoDArray;
}// to2dArray method
public static void drawBoard(char[][] arr) {
System.out.println("---------");
for (int i = 0; i < arr.length; i++) {
System.out.print("| ");
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] == '_') {
System.out.print(" " + " ");
} else {
System.out.print(arr[i][j] + " ");
}
}
System.out.println("|");
}
System.out.println("---------");
}//end drawBoard method
public static boolean xWon (char[][] gameBoard) {
char[] xWins = {'X', 'X', 'X'};
char[][] winningCombos = {
{gameBoard[0][0], gameBoard[0][1], gameBoard[0][2]}, //horizontal
{gameBoard[1][0], gameBoard[1][1], gameBoard[1][2]}, //horizontal
{gameBoard[2][0], gameBoard[2][1], gameBoard[2][2]}, //horizontal
{gameBoard[0][0], gameBoard[1][0], gameBoard[2][0]}, //vertical
{gameBoard[0][1], gameBoard[1][1], gameBoard[2][1]}, //vertical
{gameBoard[0][2], gameBoard[1][2], gameBoard[2][2]}, //vertical
{gameBoard[0][0], gameBoard[1][1], gameBoard[2][2]}, //diagonal
{gameBoard[0][2], gameBoard[1][1], gameBoard[2][0]} //diagonal
};
for (char[] charArray : winningCombos) {
if (Arrays.equals(xWins, charArray)) {
return true;
}
}
return false;
}// end xWon method
public static boolean oWon (char[][] gameBoard) {
char[] oWins = {'O', 'O', 'O'};
char[][] winningCombos = {
{gameBoard[0][0], gameBoard[0][1], gameBoard[0][2]}, //horizontal
{gameBoard[1][0], gameBoard[1][1], gameBoard[1][2]}, //horizontal
{gameBoard[2][0], gameBoard[2][1], gameBoard[2][2]}, //horizontal
{gameBoard[0][0], gameBoard[1][0], gameBoard[2][0]}, //vertical
{gameBoard[0][1], gameBoard[1][1], gameBoard[2][1]}, //vertical
{gameBoard[0][2], gameBoard[1][2], gameBoard[2][2]}, //vertical
{gameBoard[0][0], gameBoard[1][1], gameBoard[2][2]}, //diagonal
{gameBoard[0][2], gameBoard[1][1], gameBoard[2][0]} //diagonal
};
for (char[] charArray : winningCombos) {
if (Arrays.equals(oWins, charArray)) {
return true;
}
}
return false;
}// end oWon method
public static boolean hasEmptyCells(char[][] gameBoard) {
for (char[] arr : gameBoard) {
for (char ch : arr) {
if (ch == '_') {
return true;
}
}
}
return false;
} //end of hasEmptyCells method;
public static boolean gameFinished(char[][] gameBoard) {
if (xWon(gameBoard) || oWon(gameBoard) || draw(gameBoard)) {
return true;
}
return false;
} //end of gameFinished method.
public static boolean draw(char[][] gameBoard) {
if(!xWon(gameBoard) && !oWon(gameBoard) && !hasEmptyCells(gameBoard)) {
return true;
}
return false;
}
public static char[][] gameState(char[][] gameBoard) {
if (xWon(gameBoard)) {
System.out.println("X wins");
return gameBoard;
} else if (oWon(gameBoard)) {
System.out.println("O wins");
return gameBoard;
} else if (draw(gameBoard)) {
System.out.println("Draw");
return gameBoard;
}
return gameBoard;
}//gameState method
}// Main class
The draw happens halfway into this:
while (!gameFinished(gameBoard)) {
drawBoard(computerMove(gameBoard, player1));
gameState(gameBoard);
// Result is now Draw
drawBoard(computerMove(gameBoard, player2));
gameState(gameBoard);
}
You try to generate another computerMove
after the first one, but that is impossible, because the board is already full.
A possible solution woud be to check gameFinished
before attempting another move