package cisc181.mylab_4;

// Christopher Rasmussen
// copyright 2017
// University of Delaware
// CISC181

import java.util.Scanner;

public class TicTacToe {

  static enum OpponentStrategy {
    RANDOM_MOVE, MONTE_CARLO_MOVE, HUMAN_MOVE
  }

  static Scanner S;

  // set up and run multiple games

  void run_tournament() {

    S = new Scanner(System.in);
    char c;
    OpponentStrategy strategy;

    System.out.println("Welcome to Tic-Tac-Toe...");
    while (true) {

      // get user preferences for game

      System.out.println("Enter 1 for random opponent, 2 for Monte Carlo opponent, 3 for human head-to-head, and Q to quit");
      c = S.next().charAt(0);
      if (c == 'q' || c == 'Q')
        break;
      else if (c == '1')
        strategy = OpponentStrategy.RANDOM_MOVE;
      else if (c == '2')
        strategy = OpponentStrategy.MONTE_CARLO_MOVE;
      else if (c == '3'){
        runGame(true, OpponentStrategy.HUMAN_MOVE);
        continue;
      }
      else {
        System.out.println("Invalid choice");
        continue;
      }

      // only should be here if opponent is computer

      System.out.println("Enter X to go first, O to let computer play first");
      c = S.next().charAt(0);
      runGame(c == 'x' || c == 'X', strategy);

    }
    System.out.println("Thanks for playing!");
  }

  // handle a single game of tic-tac-toe

  static void runGame(boolean humanGoesFirst, OpponentStrategy strategy) {

    TicTacToeBoard curBoard = new TicTacToeBoard();
    TicTacToeBoard.Piece humanPlayer, winningPlayer, curPlayer;
    int aiMoveIndex, humanMoveIndex;
    char curPlayerName;

    // who goes first

    if (humanGoesFirst)
      humanPlayer = TicTacToeBoard.Piece.X;
    else
      humanPlayer = TicTacToeBoard.Piece.O;

    // X always goes first

    curPlayer = TicTacToeBoard.Piece.X;
    curPlayerName = 'X';

    // keep going until there is a winner or board is full

    while ((winningPlayer = curBoard.checkWin()) == TicTacToeBoard.Piece.NONE) {

      // if board is full, we are done

      if (curBoard.full()) {
        winningPlayer = TicTacToeBoard.Piece.NONE;
        break;
      }

      // print board before move

      curBoard.print();

      // if human, ask for their move with keyboard input until valid one is provided

      if (curPlayer == humanPlayer || strategy == OpponentStrategy.HUMAN_MOVE) {
        while (true) {
          System.out.printf("%c's turn\n", curPlayerName);
          System.out.println("Enter a move (0-8): ");
          humanMoveIndex = S.nextInt();
          if (!curBoard.attemptMove(humanMoveIndex, curPlayer))
            System.out.println("Invalid move!");
          else
            break;
        }
      }

      // computer player

      else {
        if (strategy == OpponentStrategy.RANDOM_MOVE)
          aiMoveIndex = curBoard.chooseRandomMove();
        else if (strategy == OpponentStrategy.MONTE_CARLO_MOVE)
          aiMoveIndex = curBoard.chooseMonteCarloMove(curPlayer, 50000);
        else {
          System.out.println("Unknown AI strategy -- ending game");
          return;
        }
        System.out.printf("Computer is %c; it plays: %d\n", curPlayerName, aiMoveIndex);
        curBoard.attemptMove(aiMoveIndex, curPlayer);
      }

      // switch to the other player

      if (curPlayer == TicTacToeBoard.Piece.X) {
        curPlayer = TicTacToeBoard.Piece.O;
        curPlayerName = 'O';
      }
      else {
        curPlayer = TicTacToeBoard.Piece.X;
        curPlayerName = 'X';
      }
    }

    // show the final board

    curBoard.print();

    // report final results

    if (winningPlayer == TicTacToeBoard.Piece.NONE) {
      System.out.println("Cat's game");
    }
    else {
      if (winningPlayer == TicTacToeBoard.Piece.X)
        System.out.println("X wins!");
      else
        System.out.println("O wins!");
    }
  }
}
