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 }