/** A tic-tac-toe game. */
public class TicTacToe {
  
  /** The tic-tac-toe board. */
  private char[][] board;
  
  /** The board dimension. */
  // This is a constant.  Once it has been initialized
  // it cannot be reassigned.
  public static final int BOARD_SIZE = 3;
  
  /** The blank square. */
  public static final char BLANK_SQUARE = ' ';
    
  /** Create a new tic-tac-toe game. */
  public TicTacToe() {
    this.board = new char[BOARD_SIZE][BOARD_SIZE];
    
    // for each row
    for (int r = 0; r < BOARD_SIZE; r++) {
      
      // for each column
      for (int c = 0; c < BOARD_SIZE; c++) {
        board[r][c] = BLANK_SQUARE;
      }
    }
  }
  
  /**
   * Put mark m at row r and column c.
   * @param m The mark to put on the board.
   * @param r The index of the row.
   * @param c The index of the column.
   */ 
  public void setMark(char m, int r, int c) {  
    if(board[r][c] == BLANK_SQUARE) {
      board[r][c] = m;
    }
  }
  
  /**
   * Get the String representation of this tic-tac-toe
   * game.
   */
  public String toString() {
    String temp = "";
    
    for (int r = 0; r < BOARD_SIZE; r++) {
      for (int c = 0; c < BOARD_SIZE; c++) {
        temp += this.board[r][c] + "|";
      }
      
      temp = temp.substring(0, temp.length() - 1);
      temp += '\n';
      
      for (int i = 0; i < BOARD_SIZE && r != BOARD_SIZE - 1; i++) {
        temp += "- ";
      }
      
      temp = temp.substring(0, temp.length() - 1);
      temp += '\n';
    }
    
    return temp;
  } 
  
  /**
   * Get the character who has won the game across a row,
   * and if nobody has won, then return the blank square. */
  public char rowWinner() {
    char winner = ' ';
    boolean didWin = false;
    
    for (int r = 0; r < BOARD_SIZE && !didWin; r++) {
      didWin = true;
      for (int c = 0; c < BOARD_SIZE - 1 && didWin; c++) {
        if (this.board[r][c] == BLANK_SQUARE 
              || this.board[r][c] != this.board[r][c + 1]) {
          didWin = false;
        }
      }
      
      if (didWin) {
        winner = this.board[r][BOARD_SIZE - 1];
      }
    }
    
    return winner;
  }
  
  /**
   * Get the character who has won the game down a column,
   * and if nobody has won, then return the blank square. */
  public char colWinner() {
    char winner = ' ';
    boolean didWin = false;
    
    for (int c = 0; c < BOARD_SIZE && !didWin; c++) {
      didWin = true;
      for (int r = 0; r < BOARD_SIZE - 1 && didWin; r++) {
        if (this.board[r][c] == BLANK_SQUARE 
              || this.board[r][c] != this.board[r + 1][c]) {
          didWin = false;
        }
      }
      
      if (didWin) {
        winner = this.board[BOARD_SIZE - 1][c];
      }
    }
    
    return winner;
  }
  
  /**
   * Get the character who has won the game along a diagonal,
   * and if nobody has won, then return the blank square. */
  public char diagWinner() {
    char winner = ' ';
    boolean didWin = false;
    
    // from upper-left to lower-right
    for (int r = 0; r < BOARD_SIZE - 1; r++) {
      if (this.board[r][r] == BLANK_SQUARE 
            || this.board[r][r] != this.board[r + 1][r + 1]) {
        didWin = false;
      }
    }
    
    if (didWin) {
      winner = this.board[0][0];
      return winner;
    }
    
    // from upper-right to lower-left
    for (int r = 0; r < BOARD_SIZE - 1; r++) {
      if (this.board[r][BOARD_SIZE - 1 - r] == BLANK_SQUARE) {
        didWin = false;
      } else if (this.board[r][BOARD_SIZE - 1 - r] 
                   != this.board[r + 1][BOARD_SIZE - 2 - r]) {
        didWin = false;
      }
    }
    
    if (didWin) {
      winner = this.board[0][BOARD_SIZE - 1];
    }
    
    return winner;
  }
  
}