public class TicTacToe {
  
  // This is a constant.
  // Constant names are all uppercase.
  // Constants cannot be reassigned once
  // they have been initialized.
  public 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 (!(row > 2 || col > 2 || row < 0 || col < 0)) {
      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;
  }
  /** Get the value at the row and column of the
   *  TicTacToe board.
   * @param row the row position.
   * @param col the column position.
   */
  public char getMark(int row, int col) {
    return board[row][col];
  }
  
  /** Return the mark of the current player */
  public char getWho() {
    return who;
  }
  
  /**
   * Check for a winner and 
   * return true if three occurences of current player who
   * are found in a row, column or  diagonal.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean runOfThree() {
    return rowOfThree() ||
      colOfThree() || 
      diagOfThree();
  }
  
  /**
   * 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() {
    int i;
    for (i = 0; i < BOARD_SIZE && !checkRow(i) ; i++) {
    }
    return i != BOARD_SIZE;
  }
  
   /**
   * Verify if three occurences of current player who
   * are found in the row .
   * @param row the row to be checked.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean checkRow(int row) {
    int col = 0;
    for (int i = 0; i < BOARD_SIZE; i++) {
      if (board[row][ i] == who) {
        col++;
      }
    }
    return col == BOARD_SIZE;
  }
  
    /**
   * Verify if three occurences of current player who
   * are found in any of the columns.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean colOfThree() {
    int i;
    for (i = 0; i < BOARD_SIZE && !checkCol(i) ; i++) {
    }
    return i != BOARD_SIZE;
  }

  /**
   * Verify if three occurences of current player who
   * are found in the column.
   * @param col the column to be checked.
   * @return true if a run of three is found, otherwise return false.
   */
public boolean checkCol(int col) {
    int row = 0;
    for (int i = 0; i < BOARD_SIZE; i++) {
      if (board[i][col] == who) {
        row++;
      }
    }
    return row == BOARD_SIZE;
  }
  
   /**
   * Verify if three occurences of current player who
   * are found along either diagonal.
   * @return true if a run of three is found, otherwise return false.
   */
  public boolean diagOfThree() {
    int diag1 = 0;
    int diag2 = 0;
    
    for (int i = 0; i < BOARD_SIZE; i++) {
      if (board[i][i] == who) {
        diag1++;
      }
      if (board[i][BOARD_SIZE -1 -i] == who) {
        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;
  }
                                 
}   


