
public class TicTacToe {
  
  // This is a constant.
  // Constant names are all uppercase.
  // Constants cannot be reassigned once
  // they have been initialized.
  private static final int BOARD_SIZE = 3;
 
  /** An empty square on the board. */
  private static final char BLANK_SQUARE = ' ';
  
  /** The letter representing player one. */
  private static final char PLAYER_ONE = 'X';
  
  /** The letter representing player two. */
  private static final char PLAYER_TWO = 'O';
  
  /** The tic-tac-toe board. */
  private char [] [] board;
  
  /** Whos turn is it */
  private char who;
  
  
  /** 
   * Create a new tic tac toe board. 
   */
  public TicTacToe() {
    board = new char[BOARD_SIZE] [BOARD_SIZE];
    for (int i = 0; i < BOARD_SIZE; i++) {
      for (int j = 0; j < BOARD_SIZE; j++) {
        board[i][j] = BLANK_SQUARE;
      }  
    }
    this.who = PLAYER_ONE;  // initialize the first player to X
  }
  
  /**
   * Set a mark on the board.
   */
  public boolean setMark(int row, int col) {
    boolean result = false;
    if ( board [row] [col] == BLANK_SQUARE) {
      result = true;
      board [row] [col] = who;
      this.switchTurn();
    }
    return result;
  }
  
  /** 
   * Change the player "who" to the player that is not currently "who".  This
   * alternates players, and is used to manage who's turn it is.
   */ 
  public void switchTurn() {
    if (this.who == PLAYER_ONE) {
      this.who = PLAYER_TWO; 
    } else {
      this.who = PLAYER_ONE;
    }
  }
  /** 
   * Displaying the board.
   * We want the board to look like a reall tic-tac-toe cross-hatch
   * As we add values, they will fill in the spaces:
   * | | 
   *_ _ _
   * | |
   *_ _ _
   * | | 
   */
  public String toString() {
    String result = "";
    for (int i = 0; i < BOARD_SIZE; i++) {
       result+= board[i][0];
       for (int j = 1; j < BOARD_SIZE; j++) {
         result += "|" + board[i][j];
       }
       result += "\n";
       if (i <  BOARD_SIZE - 1) {
         result += "_ _ _\n";
       }
    }
    return result;
  }
  
  /**
   * Check for a winner and 
   * return true if three occurences of
   * char c are found in a row, column or 
   * diagonal.
   * @param c the mark (character) to be checked.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean runOfThree(char c) {
    return rowOfThree(c) ||
      colOfThree(c) || 
      diagOfThree(c);
  }
  
  /**
   * Verify if three occurences of character c
   * are found in any of the rows.
   * @param c the mark to be checked.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean rowOfThree(char c) {
    int i;
    for (i = 0; i < BOARD_SIZE && !checkRow(i, c) ; i++) {
    }
    return i != BOARD_SIZE;
  }
  
   /**
   * Verify if three occurences of character c
   * are found in the row .
   * @param c the mark to be checked.
   * @param row the row to be checked.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean checkRow(int row, char c) {
    int col = 0;
    for (int i = 0; i < BOARD_SIZE; i++) {
      if (board[row][ i] == c) {
        col++;
      }
    }
    return col == BOARD_SIZE;
  }
  
    /**
   * Verify if three occurences of character c
   * are found in any of the columns.
   * @param c the mark to be checked.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean colOfThree(char c) {
    int i;
    for (i = 0; i < BOARD_SIZE && !checkCol(i, c) ; i++) {
    }
    return i != BOARD_SIZE;
  }

  /**
   * Verify if three occurences of character c
   * are found in the column.
   * @param c the mark to be checked.
   * @param col the column to be checked.
   * @return true if a run of three is found, otherwise return false.
   */
public boolean checkCol(int col, char c) {
    int row = 0;
    for (int i = 0; i < BOARD_SIZE; i++) {
      if (board[i][col] == c) {
        row++;
      }
    }
    return row == BOARD_SIZE;
  }
  
   /**
   * Verify if three occurences of character c
   * are found along either diagonal.
   * @param c the mark to be checked.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean diagOfThree(char c) {
    int diag1 = 0;
    int diag2 = 0;
    
    for (int i = 0; i < BOARD_SIZE; i++) {
      if (board[i][i] == c) {
        diag1++;
      }
      if (board[i][BOARD_SIZE -1 -i] == c) {
        diag2 ++;
      }
    }
    return diag1 == BOARD_SIZE || diag2 == BOARD_SIZE;
  }
  
  /** 
   * Check if the game is over because all spaces are
   * filled.
   * @return true if there are no more blank spaces on the board, 
   * otherwise return false.
   */ 
  public boolean checkDraw() {
    int blanks = 0;
    for (int i = 0; i < BOARD_SIZE; i ++) {
      for (int j = 0; j < BOARD_SIZE; j++) {
        if (board[i][j] == BLANK_SQUARE) {
          blanks ++;
        }
      }
    }
    return blanks == 0;
  }
                                 
}   

