import java.util.Random;

public class Direction {
    // OVERVIEW: Immutable type for representing a compass direction.
    //   A direction is one of: N, NE, E, SE, S, SW, W, NW.

    // Rep:
    private int northsouth; 
    private int eastwest;

    // RI (c) =
    //      (c.northsouth == -1 || c.northsouth == 0 || c.northsouth == 1)
    //   && (c.eastwest == -1 || c.eastwest == 0 || c.eastwest == 1)
    //   && (c.northsouth != 0 || c.eastwest != 0)

    //@invariant northsouth >= -1 && northsouth <= 1
    //@invariant eastwest >= -1 && eastwest <= 1
    //@invariant northsouth != 0 || eastwest != 0

    static final public Direction NORTH = new Direction (1, 0);
    static final public Direction NORTHEAST = new Direction (1, 1);
    static final public Direction EAST = new Direction (0, 1);
    static final public Direction SOUTHEAST = new Direction (-1, 1);
    static final public Direction SOUTH = new Direction (-1, 0);
    static final public Direction SOUTHWEST = new Direction (-1, -1);
    static final public Direction WEST = new Direction (0, -1);
    static final public Direction NORTHWEST = new Direction (1, -1);

    // Private class variable for generating random numbers.
    static private /*@non_null@*/ Random random = new Random ();

    public Direction (int ns, int ew)
	//@requires ns >= -1 && ns <= 1
	//@requires ew >= -1 && ew <= 1
	//@requires ns != 0 || ew != 0
	// EFFECTS: Creates a new direction with northerly direction ns and easterly direction ew.
    {
	northsouth = ns;
	eastwest = ew;
    }

    public String toString ()
    {
	String res;

	switch (northsouth) 
	    {
	    case 1:  res = "north"; break;
	    case -1: res = "south"; break;
	    default: res = ""; break;
	    }

	switch (eastwest) 
	    {
	    case 1: res += "east"; break;
	    case -1: res += "west"; break;
	    default: break;
	    }

	return res;
    }

    public int northerlyDirection () {
	return northsouth;
    }

    public int easterlyDirection () {
	return eastwest;
    }

    static public Direction randomDirection () {
	// EFFECTS: Returns a random direction.
	int dir = random.nextInt (8);

	switch (dir) {
	case 0: return NORTH;
	case 1: return NORTHEAST;
	case 2: return EAST;
	case 3: return SOUTHEAST;
	case 4: return SOUTH;
	case 5: return SOUTHWEST;
	case 6: return WEST;
	case 7: return NORTHWEST;	 
	}
	
	throw new RuntimeException ("BUG: This should never be reached!");
    } //@nowarn Exception // Unexpected RuntimeException is okay here.
}