import java.util.Scanner; /** * Implements the game of Tic Tac Toe * @author alchambers */ public class TicTacToe { private static final int SIZE = 3; private static final int CELL_SIZE = 3; private static final int NUM_VERT_BARS = 4; private int row; // the row of the current player's move private int col; // the column of the current player's move private Scanner scan; private String[][] board; /** * Starts a new game of Tic Tac Toe */ public TicTacToe(){ row = -1; col = -1; scan = new Scanner(System.in); board = new String[SIZE][SIZE]; } /** * Plays a game of Tic Tac Toe */ public void play(){ printWelcomeMessage(); drawBoard(); String currPlayer = "x"; while(true){ System.out.println("Player " + currPlayer + " turn"); takeTurn(currPlayer); if(win(currPlayer)){ break; } // Switch to the next player if(currPlayer.equals("x")){ currPlayer = "o"; } else{ currPlayer = "x"; } } printWinMessage(currPlayer); } /*********************************************************** * Private Methods for implementing each turn of the game ***********************************************************/ /** * Reads the user's move from the keyboard and stores the * row and column in instance variables. */ private void getMove(){ while(!validIndices(row, col) || board[row][col] != null){ System.out.print("Enter row: "); row = scan.nextInt(); System.out.print("Enter col: "); col = scan.nextInt(); System.out.println(); } } /** * Implements one turn in the game * @param mark the player's mark */ private void takeTurn(String mark){ getMove(); board[row][col] = mark; drawBoard(); } /*************************************** * Private Methods for Detecting Wins ***************************************/ /** * Detects a win * @param mark the player's mark * @return true if the player has won, false otherwise */ private boolean win(String mark){ return winRow(mark) || winCol(mark) || winDiag(mark); } private boolean winCol(String mark){ for(int col = 0; col < SIZE; col++){ boolean found = true; for(int row = 0; row < SIZE; row++){ if(board[row][col] == null || !board[row][col].equals(mark)){ found = false; } } if(found){ return found; } } return false; } /** * Checks each row for a win * @param mark the player's mark */ private boolean winRow(String mark){ for(int row = 0; row < SIZE; row++){ boolean found = true; for(int col = 0; col < SIZE; col++){ if(board[row][col] == null || !board[row][col].equals(mark)){ found = false; } } if(found){ return found; } } return false; } /** * Checks for a win in a diagonal position * @param mark player's mark * @return true if player won in main diagonal or off diagonal, false otherwise */ private boolean winDiag(String mark){ boolean mainDiag = true; boolean offDiag = true; for(int i = 0; i < SIZE; i++){ if(board[i][i] == null || !board[i][i].equals(mark)){ mainDiag = false; } if(board[i][SIZE-i-1] == null || !board[i][SIZE-i-1].equals(mark)){ offDiag = false; } } return (mainDiag || offDiag); } /***************************************** * Private Methods for Validating Input *****************************************/ private boolean validMark(String mark){ return mark.equals("x") || mark.equals("o"); } private boolean validIndices(int row, int col){ return (row >= 0 && row < SIZE && col >= 0 && col