// project3 solutions

public class p3sp01 {
    
    /* 9 variables for board state. r1c1 keeps the cell
       in 1st row, 1st column, etc. " " indicates blank cell. */
    
    static String r1c1 = " ";
    static String r1c2 = " ";
    static String r1c3 = " ";
    static String r2c1 = " ";
    static String r2c2 = " ";
    static String r2c3 = " ";
    static String r3c1 = " ";
    static String r3c2 = " ";
    static String r3c3 = " ";
    static int count;	// number of moves made so far
    final static String player1 = "X"; // player 1's mark
    final static String player2 = "O"; // player 2's mark
    
    // Main method.
    
    public static void main(String[] args) {
	
	TokenReader in = new TokenReader(System.in);
	boolean stop = false;
	String ans;
	System.out.println("Welcome to Tic Tac Toe!");

	// Repeat playing game (by calling playGame)
	// while the user wants to.
	
	while(!stop) {
		// play a game
	    playGame(in);
	    // asks user for playing again..
	    System.out.print("Do you wish to continue? [y,n] ");
	    ans = in.readString();
	    if (ans.equals("n")) 
		stop = true;
	    else {
		System.out.println("OK. Continuing...");
		// initialization for next game
		r1c1=r1c2=r1c3=r2c1=r2c2=r2c3=r3c1=r3c2=r3c3=" ";
		count = 0;
	    }
	}
    }

	// Main part of running the game. this method alternates
	// between player 1 and 2 to take their moves in turn
	// until either one wins or the game ends in a draw.
	
    public static void playGame(TokenReader in) {
	takeTurn(in,1,player1);
	while(count < 9) { // count starts at 0.
	    if (checkWin()) break; // check if player 1 won..
	    takeTurn(in,2,player2);	    
	    if (checkWin()) break; // check if player 2 won..
	    if (count > 9) 
		System.out.println("No more turns left!");
	    else
		takeTurn(in,1,player1);
	}
    }

	// Prompts the user (player 1 or 2, according to variable 'player')
	// to make next move in the form "rowcol". If input is valid, re-prompt
	// until it is valid. And then prints out the board state after the move.
	
    public static void takeTurn(TokenReader in, int player, String entry) {
	count++;
	boolean stop = false;
	while(!stop) {
	    System.out.print("Player "+player+
			     ": Enter position in the form [rowcol]: ");
	    switch( in.readInt() ) {
	    case 11: if (checkSpot(r1c1)) { r1c1=entry; stop=true; } break;
	    case 12: if (checkSpot(r1c2)) { r1c2=entry; stop=true; } break;
	    case 13: if (checkSpot(r1c3)) { r1c3=entry; stop=true; } break;
	    case 21: if (checkSpot(r2c1)) { r2c1=entry; stop=true; } break;
	    case 22: if (checkSpot(r2c2)) { r2c2=entry; stop=true; } break;
	    case 23: if (checkSpot(r2c3)) { r2c3=entry; stop=true; } break;
	    case 31: if (checkSpot(r3c1)) { r3c1=entry; stop=true; } break;
	    case 32: if (checkSpot(r3c2)) { r3c2=entry; stop=true; } break;
	    case 33: if (checkSpot(r3c3)) { r3c3=entry; stop=true; } break;
	    default: System.out.println("What?");
	    }
	}
	drawBoard();
    }
    
    // Returns whether a spot is already chosen or not
    
    public static boolean checkSpot(String spot) {
	boolean test = spot.equals(" ");
	if (!test)
	    System.out.println("Do not pick a spot already chosen!");
	return test;
    }	

	// Prints out the current board
	
    public static void drawBoard() {
	System.out.println("\t+---+---+---+");
	System.out.println("\t| "+r1c1+" | "+r1c2+" | "+r1c3+" |");
	System.out.println("\t+---+---+---+");
	System.out.println("\t| "+r2c1+" | "+r2c2+" | "+r2c3+" |");
	System.out.println("\t+---+---+---+");
	System.out.println("\t| "+r3c1+" | "+r3c2+" | "+r3c3+" |");
	System.out.println("\t+---+---+---+");
    }

	// Check if someone has won the game and prints a message if so

    public static boolean checkWin() {
	boolean flag = 
	    // Check if any row is filled with either X or O
	    (!r1c1.equals(" ") && r1c1.equals(r1c2) && r1c1.equals(r1c3)) ||
	    (!r2c1.equals(" ") && r2c1.equals(r2c2) && r2c1.equals(r2c3)) ||
	    (!r3c1.equals(" ") && r3c1.equals(r3c2) && r3c1.equals(r3c3)) ||
	    // Check if any column is filled with either X or O
	    (!r1c1.equals(" ") && r1c1.equals(r2c1) && r1c1.equals(r3c1)) ||
	    (!r1c2.equals(" ") && r1c2.equals(r2c2) && r1c2.equals(r3c2)) ||
	    (!r1c3.equals(" ") && r1c3.equals(r2c3) && r1c3.equals(r3c3)) ||
	    // Check if any diagonal is filled with either X or O
	    (!r1c1.equals(" ") && r1c1.equals(r2c2) && r1c1.equals(r3c3)) ||
	    (!r1c3.equals(" ") && r1c3.equals(r2c2) && r1c3.equals(r3c1));
	if (flag) System.out.println("I found a winner!");
	return flag;
    }
    
} // class p3sp01
