I had a Tic Tac Toe assignment for class and the program seems to work fine but I feel like the exception/input handling could be done in a much better way. Is this a good way to approach the structure of the app? Is it okay to use try
/catch
a lot like in here or is it better to try and avoid it?
Really newbie question but I'd love your feedback, thanks!
public class TicTacToeApp {
static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
char[] gameBoard = new char[9];
Arrays.fill(gameBoard, ' ');
char playerOne = ' ';
char playerTwo = ' ';
System.out.println("Welcome to Tic-Tac-Toe!");
try {
playerOne = getPlayerOne(playerOne);
playerTwo = getPlayerTwo(playerOne);
System.out.println("Player one plays with: " + playerOne);
System.out.println("Player two plays with: " + playerTwo);
displayBoard(gameBoard);
do {
System.out.println(playerOne + "'s turn: choose a position from 1-9");
getPosition(gameBoard, playerOne);
displayBoard(gameBoard);
if (gameOver(gameBoard, playerOne, playerTwo)) break;
System.out.println(playerTwo + "'s turn: choose a position from 1-9");
getPosition(gameBoard, playerTwo);
displayBoard(gameBoard);
} while (!gameOver(gameBoard, playerOne, playerTwo));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
/** Displays the board in the console
*
* @param gameBoard The char[] used for the game
*/
public static void displayBoard(char[] gameBoard) {
System.out.println(gameBoard[0] + " | " + gameBoard[1] + " | " + gameBoard[2]);
System.out.println("---------");
System.out.println(gameBoard[3] + " | " + gameBoard[4] + " | " + gameBoard[5]);
System.out.println("---------");
System.out.println(gameBoard[6] + " | " + gameBoard[7] + " | " + gameBoard[8]);
}
/** Gets the mark choice for player one, 'X' or 'O'
*
* @param playerOne the player to be assigned with a mark
* @return the mark that playerOne will play with
*/
public static char getPlayerOne(char playerOne) {
System.out.println("Player one please pick 'X' or 'O' ");
while (playerOne != 'X' && playerOne != 'O') {
playerOne = in.nextLine().toUpperCase().charAt(0);
if (playerOne != 'X' && playerOne != 'O') {
System.out.println("Please pick either X or O");
}
}
return playerOne;
}
/** Assigns the remaining mark to player two
*
* @param playerOne the mark player one has chosen
* @return the mark that remains for player two
*/
public static char getPlayerTwo(char playerOne) {
if (playerOne == 'X') return 'O';
else return 'X';
}
/** Checks for victory conditions for either player
*
* @param gameBoard the char[] used for the game
* @param player the player to check for
* @return true if the player has won, false otherwise
*/
public static boolean isVictory(char[] gameBoard, char player) {
return ((gameBoard[0] == player) && (gameBoard[1] == player) && (gameBoard[2] == player)) ||
((gameBoard[3] == player) && (gameBoard[4] == player) && (gameBoard[5] == player)) ||
((gameBoard[6] == player) && (gameBoard[7] == player) && (gameBoard[8] == player)) ||
((gameBoard[0] == player) && (gameBoard[3] == player) && (gameBoard[6] == player)) ||
((gameBoard[1] == player) && (gameBoard[4] == player) && (gameBoard[7] == player)) ||
((gameBoard[2] == player) && (gameBoard[5] == player) && (gameBoard[8] == player)) ||
((gameBoard[0] == player) && (gameBoard[4] == player) && (gameBoard[8] == player)) ||
((gameBoard[2] == player) && (gameBoard[4] == player) && (gameBoard[6] == player));
}
/** Assigns a mark to a position on the board
*
* @param gameBoard the char[] used for the game
* @param player the player whose turn it is to place a mark
*/
public static void getPosition(char[] gameBoard, char player) {
int position = 1;
do {
try {
position = Integer.parseInt(in.nextLine());
if (position < 1 || position > 9) {
System.out.println("Please enter a number from 1-9");
position = Integer.parseInt(in.nextLine());
}
if (gameBoard[position - 1] != ' ') {
throw new IllegalArgumentException("Position is occupied. Please choose another position");
} else {
gameBoard[position - 1] = player;
break;
}
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
} while (gameBoard[position - 1] != ' ');
}
/** Checks if the board is full
*
* @param gameBoard the char[] used for the game
* @return true if the board is full, false otherwise
*/
public static boolean fullBoard(char[] gameBoard) {
for (char c : gameBoard) {
if (c == ' ') {
return false;
}
}
return true;
}
/** Checks for end of game conditions (victory or draw)
*
* @param gameBoard the char[] used for the game
* @param playerOne First player
* @param playerTwo second player
* @return True and a message if the game has ended, False otherwise
*/
public static boolean gameOver(char[] gameBoard, char playerOne, char playerTwo) {
boolean gameOver = false;
if (isVictory(gameBoard, playerOne)) {
System.out.println(playerOne + "'s win!");
gameOver = true;
} else if (isVictory(gameBoard, playerTwo)) {
System.out.println(playerTwo + "'s win!");
gameOver = true;
} else if (fullBoard(gameBoard)) {
System.out.println("Game ended in a draw");
gameOver = true;
}
return gameOver;
}
}