diff options
Diffstat (limited to 'src/ch/epfl/maze')
-rw-r--r-- | src/ch/epfl/maze/physical/zoo/Panda.java | 125 | ||||
-rw-r--r-- | src/ch/epfl/maze/util/Trail.java | 79 |
2 files changed, 196 insertions, 8 deletions
diff --git a/src/ch/epfl/maze/physical/zoo/Panda.java b/src/ch/epfl/maze/physical/zoo/Panda.java index c168d97..fecec84 100644 --- a/src/ch/epfl/maze/physical/zoo/Panda.java +++ b/src/ch/epfl/maze/physical/zoo/Panda.java | |||
@@ -1,23 +1,128 @@ | |||
1 | package ch.epfl.maze.physical.zoo; | 1 | package ch.epfl.maze.physical.zoo; |
2 | 2 | ||
3 | import ch.epfl.maze.physical.Animal; | 3 | import ch.epfl.maze.physical.Animal; |
4 | import ch.epfl.maze.physical.ProbabilisticAnimal; | ||
4 | import ch.epfl.maze.util.Direction; | 5 | import ch.epfl.maze.util.Direction; |
6 | import ch.epfl.maze.util.Trail; | ||
5 | import ch.epfl.maze.util.Vector2D; | 7 | import ch.epfl.maze.util.Vector2D; |
6 | 8 | ||
9 | import java.util.ArrayList; | ||
10 | import java.util.Arrays; | ||
11 | import java.util.stream.Collectors; | ||
12 | |||
7 | /** | 13 | /** |
8 | * Panda A.I. that implements Trémeaux's Algorithm. | 14 | * Panda A.I. that implements Trémeaux's Algorithm. |
15 | * | ||
16 | * @author Pacien TRAN-GIRARD | ||
9 | */ | 17 | */ |
10 | public class Panda extends Animal { | 18 | public class Panda extends ProbabilisticAnimal { |
19 | |||
20 | private final Trail trail; | ||
11 | 21 | ||
12 | /** | 22 | /** |
13 | * Constructs a panda with a starting position. | 23 | * Constructs a panda with a starting position. |
14 | * | 24 | * |
15 | * @param position Starting position of the panda in the labyrinth | 25 | * @param position Starting position of the panda in the labyrinth |
16 | */ | 26 | */ |
17 | |||
18 | public Panda(Vector2D position) { | 27 | public Panda(Vector2D position) { |
19 | super(position); | 28 | super(position); |
20 | // TODO | 29 | this.trail = new Trail(); |
30 | } | ||
31 | |||
32 | /** | ||
33 | * Checks if the current position is an intersection given the possible choices. | ||
34 | * | ||
35 | * @param choices An array of possible Directions | ||
36 | * @return T(the current position is an intersection) | ||
37 | */ | ||
38 | private boolean isIntersection(Direction[] choices) { | ||
39 | return choices.length > 2; | ||
40 | } | ||
41 | |||
42 | /** | ||
43 | * Get the Marking at the adjacent position given the Direction. | ||
44 | * | ||
45 | * @param dir The Direction from the current position | ||
46 | * @return The Marking | ||
47 | */ | ||
48 | private Trail.Marking getMarkingAtDirection(Direction dir) { | ||
49 | Vector2D pos = this.getPosition().addDirectionTo(dir); | ||
50 | return this.trail.getMarking(pos); | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Checks if all Direction choices are leading to the given Marking. | ||
55 | * | ||
56 | * @param choices An array of possible Directions | ||
57 | * @param marking The Marking | ||
58 | * @return T(all choices are leading to positions with the given Marking) | ||
59 | */ | ||
60 | private boolean allChoicesLeadingTo(Direction[] choices, Trail.Marking marking) { | ||
61 | return (new ArrayList<>(Arrays.asList(choices))) | ||
62 | .stream() | ||
63 | .allMatch(dir -> this.getMarkingAtDirection(dir) == marking); | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * Selects the Direction choices leading to the given Marking. | ||
68 | * | ||
69 | * @param choices An array of possible Directions | ||
70 | * @param marking The Marking | ||
71 | * @return An array of choices leading to the given Marking | ||
72 | */ | ||
73 | private Direction[] selectDirectionsWithMarking(Direction[] choices, Trail.Marking marking) { | ||
74 | return (new ArrayList<>(Arrays.asList(choices))) | ||
75 | .stream() | ||
76 | .filter(dir -> this.getMarkingAtDirection(dir) == marking) | ||
77 | .collect(Collectors.toList()) | ||
78 | .toArray(new Direction[0]); | ||
79 | } | ||
80 | |||
81 | /** | ||
82 | * Selects the best choices according to the neighbours Markings. | ||
83 | * | ||
84 | * @param choices An array of possible Directions | ||
85 | * @return An array of smart choices | ||
86 | */ | ||
87 | private Direction[] selectBestDirections(Direction[] choices) { | ||
88 | // special case | ||
89 | if (this.isIntersection(choices) && this.allChoicesLeadingTo(choices, Trail.Marking.AVOID_MARKING)) | ||
90 | return new Direction[]{this.currentDirection.reverse()}; | ||
91 | |||
92 | // general case | ||
93 | for (Trail.Marking mark : Trail.Marking.ALL) { | ||
94 | Direction[] smartChoices = this.selectDirectionsWithMarking(choices, mark); | ||
95 | if (smartChoices.length > 0) return smartChoices; | ||
96 | } | ||
97 | |||
98 | // panda is trapped :( | ||
99 | return new Direction[]{}; | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * Determines if the current position should be marked according to the rules of the <i>Trémeaux's Algorithm</i>, | ||
104 | * avoiding intersections over-marking. | ||
105 | * | ||
106 | * @param choices An array of possible Directions | ||
107 | * @param choice The selected Direction | ||
108 | * @return T(the current position should be marked) | ||
109 | */ | ||
110 | private boolean shouldMarkCurrentPosition(Direction[] choices, Direction choice) { | ||
111 | return !(this.isIntersection(choices) | ||
112 | && this.trail.getMarking(this.getPosition()) == Trail.Marking.AVOID_MARKING | ||
113 | && this.getMarkingAtDirection(choice) == Trail.Marking.NO_MARKING); | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * Marks the current position according to the rules of the <i>Trémeaux's Algorithm</i>. | ||
118 | * | ||
119 | * @param choices An array of possible Direction to take | ||
120 | */ | ||
121 | private void markCurrentPosition(Direction[] choices) { | ||
122 | if (choices.length == 1 && this.allChoicesLeadingTo(choices, Trail.Marking.AVOID_MARKING)) // dead end | ||
123 | this.trail.markPosition(this.getPosition(), Trail.Marking.NO_GO_MARKING); | ||
124 | else | ||
125 | this.trail.markPosition(this.getPosition()); | ||
21 | } | 126 | } |
22 | 127 | ||
23 | /** | 128 | /** |
@@ -26,16 +131,20 @@ public class Panda extends Animal { | |||
26 | * colors). It will prefer taking the least marked paths. Special cases | 131 | * colors). It will prefer taking the least marked paths. Special cases |
27 | * have to be handled, especially when the panda is at an intersection. | 132 | * have to be handled, especially when the panda is at an intersection. |
28 | */ | 133 | */ |
29 | |||
30 | @Override | 134 | @Override |
31 | public Direction move(Direction[] choices) { | 135 | public Direction move(Direction[] choices) { |
32 | // TODO | 136 | Direction[] smartChoices = this.selectBestDirections(choices); |
33 | return Direction.NONE; | 137 | Direction choice = super.move(smartChoices); |
138 | |||
139 | if (this.shouldMarkCurrentPosition(choices, choice)) | ||
140 | this.markCurrentPosition(choices); | ||
141 | |||
142 | return choice; | ||
34 | } | 143 | } |
35 | 144 | ||
36 | @Override | 145 | @Override |
37 | public Animal copy() { | 146 | public Animal copy() { |
38 | // TODO | 147 | return new Panda(this.getPosition()); |
39 | return null; | ||
40 | } | 148 | } |
149 | |||
41 | } | 150 | } |
diff --git a/src/ch/epfl/maze/util/Trail.java b/src/ch/epfl/maze/util/Trail.java new file mode 100644 index 0000000..351db8f --- /dev/null +++ b/src/ch/epfl/maze/util/Trail.java | |||
@@ -0,0 +1,79 @@ | |||
1 | package ch.epfl.maze.util; | ||
2 | |||
3 | import java.util.HashMap; | ||
4 | import java.util.Map; | ||
5 | |||
6 | /** | ||
7 | * A trail keeping track on positional markings. | ||
8 | * | ||
9 | * @author Pacien TRAN-GIRARD | ||
10 | */ | ||
11 | public class Trail { | ||
12 | |||
13 | public enum Marking { | ||
14 | NO_MARKING, | ||
15 | AVOID_MARKING, | ||
16 | NO_GO_MARKING; | ||
17 | |||
18 | public static Marking DEFAULT = NO_MARKING; | ||
19 | public static Marking[] ALL = new Marking[]{NO_MARKING, AVOID_MARKING, NO_GO_MARKING}; | ||
20 | |||
21 | /** | ||
22 | * Returns the next Marking. | ||
23 | * | ||
24 | * @return The next Marking | ||
25 | */ | ||
26 | public Marking getNext() { | ||
27 | switch (this) { | ||
28 | case NO_MARKING: | ||
29 | return AVOID_MARKING; | ||
30 | case AVOID_MARKING: | ||
31 | return NO_GO_MARKING; | ||
32 | case NO_GO_MARKING: | ||
33 | return NO_GO_MARKING; | ||
34 | default: | ||
35 | return AVOID_MARKING; | ||
36 | } | ||
37 | } | ||
38 | } | ||
39 | |||
40 | private final Map<Vector2D, Marking> trail; | ||
41 | |||
42 | /** | ||
43 | * Constructs a new blank Trail. | ||
44 | */ | ||
45 | public Trail() { | ||
46 | this.trail = new HashMap<>(); | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * Get the marking at the given position. | ||
51 | * | ||
52 | * @param position The positional Vector | ||