package tictactoe;

public class TicTacToe {
  private char[][] board; // the tic-tac-toe board
  private char turn; // whose turn is it?
  private boolean gameEnded; // is the game over?
  private char winner; // indicates the winner

  public final char PLAYERX = 'X';
  public final char PLAYERO = 'O';
  public final char BLANK = '-';
  public final char DRAW = 'D';

  public TicTacToe() {
    gameEnded = false;
    winner = BLANK;
    board = new char[3][3];
    for (int r = 0; r < board.length; r++) {
      for (int c = 0; c < board[r].length; c++) {
        board[r][c] = BLANK;
      }
    }
    turn = PLAYERX;
  }

  public String toString() {
    gameOver();
    String result = "\ngameEnded = " + gameEnded + "\n";
    for (int r = 0; r < board.length; r++) {
      for (int c = 0; c < board[r].length; c++) {
        result += board[r][c];
      }
      result += "\n";
    }
    return result;
  }

  // returns true if the move was successful
  public boolean move(int r, int c) {
    gameOver();
    if (gameEnded) {
      return false;
    }
    if (r < 0) {
      return false;
    }
    if (r >= board.length) {
      return false;
    }
    if (c < 0) {
      return false;
    }
    if (c >= board[r].length) {
      return false;
    }
    if (board[r][c] != BLANK) {
      return false;
    }
    board[r][c] = turn;
    if (turn == PLAYERX) {
      turn = PLAYERO;
    }
    else {
      turn = PLAYERX;
    }
    return true;
  }

  // return true if the game is over
  // sets the winner of the game
  public boolean gameOver() {
    int countX, countO;
    // do loops over row, column, or diagonal
    // test if countX == 3 or countO == 3

    // check the rows
    for (int r = 0; r < 3; r++) {
      countX = countO = 0;
      for (int c = 0; c < 3; c++) {
        char mark = board[r][c];
        if (mark == PLAYERX) {
          countX++;
        }
        else if (mark == PLAYERO) {
          countO++;
        }
      }
      if (countX == 3) {
        gameEnded = true;
        winner = PLAYERX;
      }
      else if (countO == 3) {
        gameEnded = true;
        winner = PLAYERO;
      }
    }

    // check the columns
    for (int c = 0; c < 3; c++) {
      countX = countO = 0;
      for (int r = 0; r < 3; r++) {
        char mark = board[r][c];
        if (mark == PLAYERX) {
          countX++;
        }
        else if (mark == PLAYERO) {
          countO++;
        }
      }
      if (countX == 3) {
        gameEnded = true;
        winner = PLAYERX;
      }
      else if (countO == 3) {
        gameEnded = true;
        winner = PLAYERO;
      }
    }

    // check one diagonal
    countX = countO = 0;
    for (int r = 0, c = 0; r < 3; r++, c++) {
      char mark = board[r][c];
      if (mark == PLAYERX) {
        countX++;
      }
      else if (mark == PLAYERO) {
        countO++;
      }
    }
    if (countX == 3) {
      gameEnded = true;
      winner = PLAYERX;
    }
    else if (countO == 3) {
      gameEnded = true;
      winner = PLAYERO;
    }

    // check the other diagonal
    countX = countO = 0;
    for (int r = 0, c = 2; r < 3; r++, c--) {
      char mark = board[r][c];
      if (mark == PLAYERX) {
        countX++;
      }
      else if (mark == PLAYERO) {
        countO++;
      }
    }
    if (countX == 3) {
      gameEnded = true;
      winner = PLAYERX;
    }
    else if (countO == 3) {
      gameEnded = true;
      winner = PLAYERO;
    }

    // check for a tie
    if (! gameEnded) {
      int countBlank = 0;
      for (int r = 0; r < 3; r++) {
        for (int c = 0; c < 3; c++) {
          if (BLANK == board[r][c]) {
            countBlank++;
          }
        }
      }
      if (countBlank == 0) {
        gameEnded = true;
        winner = DRAW;
      }
    }

    return gameEnded;
  }
}
