/**
   * Respond to when user pressed on the PlayButton.
   *
   * @param e the Event that initiates the play of a game.
   */
  public void actionPerformed(ActionEvent e) {
    setup();

    // now that players are set up, we need to have the XPlayer be the current Player
    controller.reset();

    // if xType is computer, have him go first now
    if (computerGoesFirst) {
      controller.playTurn();
    }

    if (computerPlaysSelf) {
      int i = 0;
      while (controller.playTurn() == GameController.IN_PROGRESS) {
        // prevent infinite loop by arbitrarily halting after
        // 100 turns. Note the use of PRE-increment within if
        if (++i > 100) {
          break;
        }
      }

      int state = controller.getCurrentState();
      switch (state) {
        case GameController.DRAW:
          applet.output("Game is drawn");
          break;

        case GameController.X_WINS:
          applet.output("X Wins!");
          break;

        case GameController.O_WINS:
          applet.output("O Wins!");
          break;
      }
    }

    // refresh view
    applet.repaint();
  }
  /**
   * React only to MouseClicked Events (where user presses and releases).
   *
   * <p>Can't be called until after the mousePlayer has been properly initialized.
   *
   * @param e the MouseEvent created by user.
   */
  public void mouseClicked(MouseEvent e) {
    // no game set up yet.
    if (controller == null) {
      return;
    }

    // prevent any action for a game that isn't in progress.
    if (controller.getCurrentState() != GameController.IN_PROGRESS) {
      return;
    }

    // If no human player (i.e., computer vs. computer) do nothing
    if (humanPlayer == null) {
      return;
    }

    // leave if it is not OUR turn.
    if ((controller.getCurrentTurn() == GameController.XTURN)
        && (humanPlayer.getMark() != Player.XMARK)) {
      return;
    }
    if ((controller.getCurrentTurn() == GameController.OTURN)
        && (humanPlayer.getMark() != Player.OMARK)) {
      return;
    }

    int x = e.getX();
    int y = e.getY();

    // invert the calculations from drawSpot()
    Cell cell = controller.interpretXY(x, y);
    Move m = controller.interpretMove(cell, humanPlayer);

    if (m == null) {
      applet.output("Invalid move. Try again");
      return;
    }

    // once we set the move for the player, it will be retrieved
    // by the controller who then asks the player for his next
    // move. Pretty tricky, huh?
    humanPlayer.setMove(m);
    int rc = controller.playTurn();

    // refresh to ensure that move is visible again.
    applet.repaint();

    if (rc != GameController.IN_PROGRESS) {
      if (rc == GameController.DRAW) {
        applet.output("Game is drawn");
      } else {
        applet.output("Game over. You Win!");
      }
    } else {
      // update humanPlayer and deal with auto-play
      Player currentPlayer;
      int turn = controller.getCurrentTurn();
      if (turn == GameController.XTURN) {
        currentPlayer = (Player) controller.getXPlayer();
      } else {
        currentPlayer = (Player) controller.getOPlayer();
      }

      if (currentPlayer instanceof MousePlayer) {
        humanPlayer = (MousePlayer) currentPlayer;
        return;
      }

      // since the current player is NOT human, we auto play.
      rc = controller.playTurn();
      if (rc != GameController.IN_PROGRESS) {
        if (rc == GameController.DRAW) {
          applet.output("Game is drawn");
        } else {
          applet.output("Game over. You Lose!!!!!");
        }
      }
    }
  }