```

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.
//	 If the streaker is the one in motion, they only move in the S, SW, or SE directions.

// 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.
}

static public Direction streakerDirCabell () {
//EFFECTS: Returns a random direction toward Cabell Hall,
//			which is either South, Southeast, or Southwest.
int dir= random.nextInt(3);

switch (dir) {
case 0: return SOUTH;
case 1: return SOUTHEAST;
case 2: return SOUTHWEST;
}

throw new RuntimeException ("BUG: This should never be reached!");
} //@nowarn Exception // Unexpected RuntimeException is okay here.
}

```