summaryrefslogtreecommitdiff
path: root/src/ch/epfl/maze/util/Direction.java
blob: b3f2e9c738bd275739e8fffdc60179a75e6b2b4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
package ch.epfl.maze.util;

import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;

/**
 * Directions that an animal can take to move. They represent the four cardinal
 * points ({@code DOWN, UP, RIGHT, LEFT}) from the frame of reference of the
 * labyrinth, plus a default one : {@code NONE}.
 *
 * @author EPFL
 * @author Pacien TRAN-GIRARD
 */
public enum Direction {
    DOWN, UP, RIGHT, LEFT, NONE;

    /**
     * A set of all the possible directions that can be taken.
     */
    public static final Set<Direction> MOVING_DIRECTIONS = Collections.unmodifiableSet(EnumSet.of(
            Direction.DOWN,
            Direction.UP,
            Direction.RIGHT,
            Direction.LEFT
    ));

    /**
     * Returns the integer value of the direction
     *
     * @return Integer value of the direction
     */
    public int intValue() {
        switch (this) {
            case DOWN:
                return 0;

            case UP:
                return 1;

            case RIGHT:
                return 2;

            case LEFT:
                return 3;

            case NONE:
            default:
                return 4;
        }
    }

    /**
     * Converts the direction into an orthonormal vector, when possible.
     *
     * @return Orthonormal {@code Vector2D} that represents the direction.
     */
    public Vector2D toVector() {
        switch (this) {
            case DOWN:
                return new Vector2D(0, 1);

            case UP:
                return new Vector2D(0, -1);

            case RIGHT:
                return new Vector2D(1, 0);

            case LEFT:
                return new Vector2D(-1, 0);

            case NONE:
            default:
                return new Vector2D(0, 0);
        }
    }

    /**
     * Reverses the direction.
     *
     * @return The opposite direction.
     */
    public Direction reverse() {
        switch (this) {
            case DOWN:
                return UP;

            case UP:
                return DOWN;

            case RIGHT:
                return LEFT;

            case LEFT:
                return RIGHT;

            case NONE:
            default:
                return NONE;
        }
    }

    /**
     * Determines whether the argument is the opposite of another.
     *
     * @param d The direction to compare with
     * @return <b>true</b> if the direction is the opposite the argument,
     * <b>false</b> otherwise
     */
    public boolean isOpposite(Direction d) {
        return this == d.reverse();
    }

    /**
     * Converts the argument relative to the frame of reference given by the
     * direction that calls the method.
     *
     * @param dir The direction to convert
     * @return The direction converted to the frame of reference given by the
     * direction called.
     */
    public Direction relativeDirection(Direction dir) {
        switch (this) {
            case DOWN:
                return dir.reverse();

            case UP:
                return dir;

            case RIGHT:
                return dir.rotateLeft();

            case LEFT:
                return dir.rotateRight();

            case NONE:
            default:
                return NONE;
        }
    }

    /**
     * Converts the argument back to the frame of reference of the labyrinth
     *
     * @param dir The direction to convert back
     * @return The direction converted back to the frame of reference of the
     * labyrinth
     */
    public Direction unRelativeDirection(Direction dir) {
        switch (this) {
            case DOWN:
                return dir.reverse();

            case UP:
                return dir;

            case RIGHT:
                return dir.rotateRight();

            case LEFT:
                return dir.rotateLeft();

            case NONE:
            default:
                return NONE;
        }
    }

    /**
     * Rotates the direction to the right.
     *
     * @return The rotated direction to the right
     */
    public Direction rotateRight() {
        switch (this) {
            case DOWN:
                return LEFT;

            case UP:
                return RIGHT;

            case RIGHT:
                return DOWN;

            case LEFT:
                return UP;

            case NONE:
            default:
                return NONE;
        }
    }

    /**
     * Rotates the direction to the left.
     *
     * @return The rotated direction to the left
     */
    public Direction rotateLeft() {
        switch (this) {
            case DOWN:
                return RIGHT;

            case UP:
                return LEFT;

            case RIGHT:
                return UP;

            case LEFT:
                return DOWN;

            case NONE:
            default:
                return NONE;
        }
    }

    /**
     * Applies the change of coordinates relative to the frame of reference
     * of the direction that calls the method to all the directions in the
     * argument.
     *
     * @param dir The array of directions to convert
     * @return The directions converted to the frame of reference given by the
     * direction which calls the method
     */
    public Direction[] relativeDirections(Direction[] dir) {
        Direction[] relativeDirections = new Direction[dir.length];

        for (int i = 0; i < dir.length; i++) {
            relativeDirections[i] = this.relativeDirection(dir[i]);
        }

        return relativeDirections;
    }

}