// PlayGame.java
//
// Still needs 
//    installation of timing package (here or in another class)
//    repeated plays

import game.*;

/**
 * Driver for playing games - any two players (implementations of
 * the Player interface) can play any game (implementation of the Game
 * interface).
 *
 * Written (in Pascal) by Ethan Bolker, April 1984, for Math 301.
 *  modified October 1984, October 1986, October 1987 for CS310
 *  converted to C April 1990 for CS310 by ?
 *  modified Oct 1993 to restore calls to timing package
 *  modified Nov 1995 to restore calls to timing package!
 *  cleaned up by Dina Goldin, Nov. 1999
 *  modified to use ARM package (~eb/arm) by Szymon Jaroszewicz Mar 2002
 *
 *  converted from C to Java November 2002 - January 2003
 */

public class PlayGame 
{
    private static Terminal t = new Terminal(); 
    private static Game game = null;

    /**
     * Play the game.
     *
     * If no computer player is specified, it's BackTrack.
     *
     * @param args Game and zero, one or two Players
     */

    public  static void main( String[] args )
    {
	String gameName = null;
	Player one = new HumanPlayer();
	Player two = new Backtrack();


	if (args.length == 0) {
	    System.out.println( 
	       "usage: java PlayGame GameName <ComputerPlayer>");
	    System.exit(0);
	}
	       
	try { 
	    gameName = args[0];
	    game = (Game)(Class.forName(gameName).newInstance()); 
	    if (args.length > 1) {
		two = (Player)(Class.forName(args[1]).newInstance());
	    }
	}
	catch (Exception e) { // many possibilities for error
	    System.err.println(e);
	    System.exit(1);
	}

	t.println("Pit your wits against the machine playing " 
		  + game.getName() );
	if (t.readYesOrNo("Do you need help?")) {
	    t.println(game.getHelp());
	}

	Player winner = playOneGame( game, one, two );

	if ( winner != null ) {
	    t.println("winner is " + winner);
	}
	else {
	    t.println("game is a draw");
	}
    }

    /** 
     * Play one game.
     *
     * @param g the Game.
     * @param one a Player
     * @param two another Player
     *
     * @return the winner of the Game.
     */
    private static Player playOneGame(Game g, Player one, Player two) 
    {
	Player firstPlayer;
	Player secondPlayer;
	Player winner;

	t.println(g);
	if (t.readYesOrNo("Do you wish to move first?")) {
	    one.setPlayerNumber(Game.FIRST_PLAYER);
	    two.setPlayerNumber(Game.SECOND_PLAYER);
	}
	else {
	    two.setPlayerNumber(Game.FIRST_PLAYER);
	    one.setPlayerNumber(Game.SECOND_PLAYER);
	}

	while( !g.gameOver() ) {
	    Player player =
		(g.whoseTurn() == one.getPlayerNumber()) ? one : two ;
	    Move m;
	    if ( player.isInteractive() ) {
		t.println("Your turn.");
		m = getMoveInteractively(g);
	    }
	    else {
		t.println("\nMy turn. I'm thinking ...\n");
		m = ((ComputerPlayer)player).findbest(g);
		t.println("my move is " + m);
	    }
	    try {
		g.make( m );
	    }
	    catch( IllegalMoveException e ) {
		t.println("illegal move");
	    }
	    if ( !player.isInteractive() ) {
		t.println( g );
	    }
	}
	if (g.winner() == one.getPlayerNumber() ) {
	    return one;
	}
	if (g.winner() == two.getPlayerNumber() ) {
	    return two;
	}
	return null; // game is a draw
    }	    
    

    public static Move getMoveInteractively( Game g ) 
    {
	Move m;
	String s = "";
	while (true) {
	    try {
		s = t.readLine("your move: ").trim();
		if (s.startsWith("help")) {
		    game.getHelp();
		    t.println("legal moves: " + g.getMoves());
		    continue;
		}
		m = g.parseMove(s);
		return m;
	    }
	    catch(IllegalMoveException e) {
		t.println("illegal move: " + s);
	    }
	    catch(NoSuchMoveException e) {
		t.println("no such move: " + s);
	    }
	    catch(GameException e) {
	    }
	}
    }
}







