1  /**
  2     A path in a maze is defined by a starting (row, column) 
  3     position and a direction (NORTH, EAST, SOUTH, or WEST).
  4     A path starts out with the same starting and ending position
  5     and direction. It can be extended as the maze is traversed,
  6     until it reaches an exit, intersection, or dead end. 
  7  
  8     Intuitively, think of the path as starting at an intersection
  9     and then moving forward, potentially turning along the 
 10     way, until it reaches another intersection. 
 11  */
 12  public class Path
 13  {
 14     public static final int NORTH = 0;
 15     public static final int EAST = 1;
 16     public static final int SOUTH = 2;
 17     public static final int WEST = 3;
 18  
 19     private static final int[] ROW_OFFSETS = { -1, 0, 1, 0 };
 20     private static final int[] COLUMN_OFFSETS = { 0, 1, 0, -1 };
 21  
 22     private int startingRow;
 23     private int startingColumn;
 24     private int startingDirection;
 25     private int endingRow;
 26     private int endingColumn;
 27     private int endingDirection;
 28     
 29     /**
 30        Constructs a path with a given position and direction
 31        @param row the starting row
 32        @param column the starting column
 33        @param direction the starting direction
 34     */
 35     public Path(int row, int column, int direction)
 36     {
 37        startingRow = row;
 38        startingColumn = column;
 39        startingDirection = direction;
 40        endingRow = row;
 41        endingColumn = column;
 42        endingDirection = direction;
 43     }
 44  
 45     /**
 46        Moves the ending position of this path one unit in the
 47        current direction.
 48     */
 49     public void move()
 50     {
 51        endingRow = getNextRow();
 52        endingColumn = getNextColumn();
 53     }
 54  
 55     /**
 56        Turns the ending direction of this path clockwise.
 57     */
 58     public void turn()
 59     {
 60        final int DIRECTIONS = 4;
 61        endingDirection = (endingDirection + 1) % DIRECTIONS;  
 62     }
 63  
 64     /**
 65        Gets the ending row of this path.
 66        @return the ending row
 67     */
 68     public int getEndingRow()
 69     {
 70        return endingRow;
 71     }
 72  
 73     /**
 74        Gets the ending column of this path.
 75        @return the ending column
 76     */
 77     public int getEndingColumn()
 78     {
 79        return endingColumn;
 80     }
 81  
 82     /**
 83        Gets the next row of this path if it continues in the ending
 84        direction.
 85        @return the next row
 86     */
 87     public int getNextRow()
 88     {
 89        return endingRow + ROW_OFFSETS[endingDirection];
 90     }
 91  
 92     /**
 93        Gets the next column of this path if it continues in the ending
 94        direction.
 95        @return the next row
 96     */
 97     public int getNextColumn()
 98     {
 99        return endingColumn + COLUMN_OFFSETS[endingDirection];
100     }
101     
102     /**
103        Checks whether two directions are opposites of each other.
104        @param dir1 a direction between 0 and 3
105        @param dir2 a direction between 0 and 3
106        @return true if they are opposites (i.e. 0 and 2, 1 and 3,
107        2 and 0, or 3 and 1)
108     */
109     private static boolean isOpposite(int dir1, int dir2)
110     {
111        return dir1 != dir2 && (dir1 + dir2) % 2 == 0;
112     }
113  
114     /**
115        Checks whether this path is the opposite of another one.
116        @param other another path that ends where this path starts
117        @return true if other is the opposite of this path
118     */
119     public boolean isOpposite(Path other)
120     {
121        return startingRow == other.endingRow
122           && startingColumn == other.endingColumn
123           && isOpposite(startingDirection, other.endingDirection);
124     }
125     
126     public String toString() 
127     {
128        String result = "(" + startingRow + "," + startingColumn 
129           + ")" + "NESW".charAt(startingDirection);
130        if (endingRow != startingRow || endingColumn != startingColumn)
131        {
132  	  result = result + "<->(" + endingRow + "," + endingColumn 
133               + ")"+ "NESW".charAt(endingDirection); 
134        }
135        return result;
136     }
137  }