import java.util.Vector;

/**
 * A general representation for a discrete game node.
 * Creation date: (10/6/00 12:15:19 PM)
 * @author: Todd Neller
 */
public abstract class GameNode implements Cloneable {
    /** constant integers designating player MAXimizing and
        MINimizing utility */
    static final int MAX = 0, MIN = 1;

    /** undefined move constant */
    static final int UNDEFINED_MOVE = -1;

    /** first player MAXimizer by default */
    protected int player = MAX;

    /** previous move applied to reach this node. */
    public int prevMove = UNDEFINED_MOVE;

    /** variable <code>parent</code> - parent of this game node */
    public GameNode parent = null;

    /**
     * <code>getPlayer</code> - return the current player
     * (GameNode.MAX or GameNode.MIN).
     *
     * @return an <code>int</code> value GameNode.MAX or
     * GameNode.MIN */
    public int getPlayer() {
	return player;
    }

    /**
     * <code>expand</code> - return a Vector of all possible next
     * game states
     *
     * @return a <code>Vector</code> of all possible next game
     * states */
    public Vector expand() {
	int[] moves = getLegalMoves();
	Vector children = new Vector();
	for (int i=0; i<moves.length; i++) {
	    GameNode newNode = childClone();
	    newNode.makeMove(moves[i]);
	    children.add(newNode);
	}
	return children;
    }

    /**
     * <code>childClone</code> - returns a clone of this node
     * that has been made a child of this node and has a depth
     * one greater than this.
     *
     * @return a <code>SearchNode</code> value */
    public GameNode childClone() 
    {
	GameNode child = (GameNode) clone();
	child.parent = this;
	return child;
    }

    /**
     * <code>clone</code> - see Main (pp. 76-80)
     *
     * @return an <code>Object</code> value
     */
    public Object clone() 
    {
	try {
	    return super.clone();
	}
	catch (CloneNotSupportedException e) {
	    throw new RuntimeException ("This class does not implement Cloneable.");
	}
    }    

    /**
     * Return result of terminal state test.
     * Creation date: (10/6/00 12:33:21 PM)
     * @return boolean
     */
    public abstract boolean gameOver();

    /**
     * Set game to initial state.
     * Creation date: (10/6/00 12:22:05 PM)
     */
    public abstract void initialState();

    /**
     * Return an array of integers encoding legal moves for current state.
     * Creation date: (10/6/00 12:24:32 PM)
     * @return int[]
     */
    public abstract int[] getLegalMoves();

    /**
     * Assuming move is a legal move (see legalMoves()), make the appropriate
     * change to the game state and update the player.
     * Creation date: (10/6/00 12:34:41 PM)
     * @param move int
     */
    public abstract void makeMove(int move);


    /**
     * Return the estimated utility of the current game position, unless game is over.  
     * If game is over, return actual utility.
     * Player MAX maximizes this; player MIN minimizes this.
     * Creation date: (10/6/00 12:36:49 PM)
     * @return double
     */
    public abstract double utility();

}
