import java.util.Scanner;

public class TicTacToe
{
	/**
	 *  A program to play tic-tac-toe against the user.
	 *
	 *  @author mike slattery
	 */
	static int[] board = new int[10]; // using board[1],...,board[9]
	                           // in pattern:
	                           //   1 | 2 | 3
	                           //  ---+---+---
	                           //   4 | 5 | 6
	                           //  ---+---+---
	                           //   7 | 8 | 9
	                           // Marks are recorded with 0
	                           // for empty square, 1 for computer,
	                           // and 10 for user.
	static int[][] inARow = {{1,2,3},
	                  {4,5,6}, // straight-line combinations
	                  {7,8,9},
	                  {1,4,7},
	                  {2,5,8},
	                  {3,6,9},
	                  {1,5,9},
	                  {3,5,7}};
	static Scanner keyboard = new Scanner(System.in);

	public static void main(String[] args)
	{
		int move;

		System.out.println("Welcome to Las Vegas for the\n"+
		           "World Series of TicTacToe!!!");
		// Clear the board:
		for (int i = 1; i <= 9; i++)
			board[i] = 0;
		// Let's play:
		do
		{
			move = getComputerMove();
			// Record move on board and tell the player
			board[move] = 1;
			System.out.println("I move in square "+move);
			// A really cheap display:
			System.out.println("The board is");
			System.out.println(board[1]+"   "+board[2]+"   "+board[3]);
			System.out.println(board[4]+"   "+board[5]+"   "+board[6]);
			System.out.println(board[7]+"   "+board[8]+"   "+board[9]);
			if (!gameOver())
			{
				move = getUserMove();
				// Record move on board
				board[move] = 10;
			}
		}while (!gameOver());
		// Print who won:
		if (lookFor(3) >= 0)
		  System.out.println("I won!!");
		else if (lookFor(30) >= 0)
		  System.out.println("You won! Good game.");
		else
		  System.out.println("Cats game!");
	}

	static boolean gameOver()
	{
		if ((lookFor(3) >= 0)||(lookFor(30) >= 0))
			return true;
		else
		{
			// See if it's a tie (all squares taken
			// with no winner)
			for(int i = 1; i <= 9; i++)
			{
				if (board[i]==0)
				  return false;
			}
			return true;
		}
	}

	static int getUserMove()
	{
		boolean badInput;
		int move;

		do
		{
			badInput = false;
			System.out.print("Your move? ");
			move = keyboard.nextInt();
			if ((move < 1) || (move > 9))
			{
				System.out.println("We only have squares 1 to 9");
				System.out.println("Please choose one of those");
				badInput = true;
			}
			else if (board[move] != 0)
			{
				System.out.println("Square "+move+" is already taken");
				System.out.println("Please choose a different square");
				badInput = true;
			}
		} while (badInput);

		return move;
	}

	static int getComputerMove()
	{
		int row;
		int move;

		row = lookFor(2);
		if (row >= 0)
		{
			return findEmpty(row);
		}
		// We're skipping an "else" here since if the
		// if condition was true, we've already returned
		// (In other words, this is "else" but we don't
		//  need to say so).  This keeps indentation manageable.
		row = lookFor(20);
		if (row >= 0)
		{
			return findEmpty(row);
		}
		row = lookFor(1);
		if (row >= 0)
		{
			return findEmpty(row);
		}
		row = lookFor(10);
		if (row >= 0)
		{
			return findEmpty(row);
		}
		// find first empty square
		for (int i = 1; i <= 9; i++)
		{
			if (board[i] == 0)
			{
				return i;
			}
		}
		System.out.println("Something strange happened - this should never print!");
		return 999; // make the compiler happy
	}

	static int findEmpty(int row)
	{
		// Find a value, empty, in inARow[row]
		// such that board[empty] == 0.
		int empty;

		for (int i = 0; i < 3; i++)
		{
			empty = inARow[row][i];
			if (board[empty] == 0)
				return empty;
		}
		System.out.println("Something strange happened - this should never print!");
		return 999; // make the compiler happy
	}

	static int lookFor(int val)
	{
		// find an index i so that the board values
		// corresponding to the locations in inARow[i]
		// add up to val.
		// If no such i, return -1
		for(int i = 0; i < inARow.length; i++)
		{
			int sum = 0;
			for(int j = 0; j < 3; j++)
			{
				int place = inARow[i][j];
				sum += board[place];
			}
			if (sum == val)
				return i;
		}
		return -1;
	}
}
