diff options
Diffstat (limited to 'src/ch/epfl/maze/simulation/DaedalusSimulation.java')
-rw-r--r-- | src/ch/epfl/maze/simulation/DaedalusSimulation.java | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/src/ch/epfl/maze/simulation/DaedalusSimulation.java b/src/ch/epfl/maze/simulation/DaedalusSimulation.java new file mode 100644 index 0000000..2082772 --- /dev/null +++ b/src/ch/epfl/maze/simulation/DaedalusSimulation.java | |||
@@ -0,0 +1,364 @@ | |||
1 | package ch.epfl.maze.simulation; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.Collections; | ||
5 | import java.util.HashMap; | ||
6 | import java.util.LinkedList; | ||
7 | import java.util.List; | ||
8 | import java.util.Map; | ||
9 | import java.util.TreeMap; | ||
10 | |||
11 | import ch.epfl.maze.graphics.Animation; | ||
12 | import ch.epfl.maze.physical.Animal; | ||
13 | import ch.epfl.maze.physical.Daedalus; | ||
14 | import ch.epfl.maze.physical.Predator; | ||
15 | import ch.epfl.maze.physical.Prey; | ||
16 | import ch.epfl.maze.physical.World; | ||
17 | import ch.epfl.maze.util.Action; | ||
18 | import ch.epfl.maze.util.Direction; | ||
19 | import ch.epfl.maze.util.Vector2D; | ||
20 | |||
21 | /** | ||
22 | * Simulation of a predation environment. Handles the next moves of every | ||
23 | * predator and prey in a Daedalus, as well as the animation by notifying | ||
24 | * changes to it. The simulation finishes when every prey has been caught. | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | public final class DaedalusSimulation implements Simulation { | ||
29 | |||
30 | /* limit to the step counter, over which the animals are considered lost */ | ||
31 | public static final int COUNTER_LIMIT = 10000; | ||
32 | |||
33 | /* simulation components */ | ||
34 | private Daedalus mDaedalus; | ||
35 | private Map<Integer, List<Prey>> mArrivalTimes; | ||
36 | private int mStepCounter; | ||
37 | |||
38 | /* collision check variables */ | ||
39 | private Map<Prey, List<Vector2D>> mPreyMoves; | ||
40 | private Map<Predator, List<Vector2D>> mPredatorMoves; | ||
41 | |||
42 | /** | ||
43 | * Constructs a simulation with a {@code Daedalus} to simulate. | ||
44 | * | ||
45 | * @param daedalus | ||
46 | * The daedalus to simulate | ||
47 | */ | ||
48 | |||
49 | public DaedalusSimulation(Daedalus daedalus) { | ||
50 | mDaedalus = daedalus; | ||
51 | mArrivalTimes = new TreeMap<Integer, List<Prey>>(Collections.reverseOrder()); | ||
52 | mStepCounter = 0; | ||
53 | mPreyMoves = new HashMap<Prey, List<Vector2D>>(); | ||
54 | mPredatorMoves = new HashMap<Predator, List<Vector2D>>(); | ||
55 | } | ||
56 | |||
57 | @Override | ||
58 | public void move(Animation listener) { | ||
59 | if (isOver()) { | ||
60 | return; | ||
61 | } | ||
62 | |||
63 | // clears moves maps | ||
64 | mPreyMoves.clear(); | ||
65 | mPredatorMoves.clear(); | ||
66 | |||
67 | // increments counter | ||
68 | mStepCounter++; | ||
69 | |||
70 | // if counter exceeded the limit, it considers preys safe | ||
71 | if (mStepCounter > COUNTER_LIMIT) { | ||
72 | List<Prey> preys = mDaedalus.getPreys(); | ||
73 | List<Prey> safePreys = new LinkedList<Prey>(); | ||
74 | for (Prey prey : preys) { | ||
75 | mDaedalus.removePrey(prey); | ||
76 | safePreys.add(prey); | ||
77 | } | ||
78 | |||
79 | mArrivalTimes.put(Integer.MAX_VALUE, safePreys); // infinite | ||
80 | return; | ||
81 | } | ||
82 | |||
83 | // asks predators and preys to move | ||
84 | movePredators(listener); | ||
85 | movePreys(listener); | ||
86 | |||
87 | // checks collisions | ||
88 | checkCollisions(listener); | ||
89 | |||
90 | // notifies animation that all the changes are done | ||
91 | if (listener != null) { | ||
92 | listener.doneUpdating(); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | @Override | ||
97 | public boolean isOver() { | ||
98 | return mDaedalus.isSolved(); | ||
99 | } | ||
100 | |||
101 | @Override | ||
102 | public World getWorld() { | ||
103 | return mDaedalus; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public int getSteps() { | ||
108 | return mStepCounter; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public Map<Integer, List<Animal>> getArrivalTimes() { | ||
113 | TreeMap<Integer, List<Animal>> arrivalTimes = new TreeMap<Integer, List<Animal>>(); | ||
114 | for (Map.Entry<Integer, List<Prey>> entry : mArrivalTimes.entrySet()) { | ||
115 | int time = entry.getKey(); | ||
116 | List<Animal> animals = new ArrayList<Animal>(entry.getValue()); | ||
117 | arrivalTimes.put(time, animals); | ||
118 | } | ||
119 | |||
120 | return arrivalTimes; | ||
121 | } | ||
122 | |||
123 | @Override | ||
124 | public String getRecordTable() { | ||
125 | String recordTable = ""; | ||
126 | int position = 1; | ||
127 | for (Map.Entry<Integer, List<Prey>> entry : mArrivalTimes.entrySet()) { | ||
128 | // only returns the 10 first | ||
129 | if (position > 10) { | ||
130 | return recordTable; | ||
131 | } | ||
132 | |||
133 | for (Prey prey : entry.getValue()) { | ||
134 | if (entry.getKey() == Integer.MIN_VALUE) { | ||
135 | recordTable += "-- "; | ||
136 | recordTable += prey.getClass().getSimpleName(); | ||
137 | recordTable += " - never finished\n"; | ||
138 | } else { | ||
139 | recordTable += position + ". "; | ||
140 | recordTable += prey.getClass().getSimpleName(); | ||
141 | if (entry.getKey() == Integer.MAX_VALUE) { | ||
142 | recordTable += " - has survived\n"; | ||
143 | } else { | ||
144 | recordTable += " - " + entry.getKey() + " steps\n"; | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | position += entry.getValue().size(); | ||
149 | } | ||
150 | |||
151 | return recordTable; | ||
152 | } | ||
153 | |||
154 | @Override | ||
155 | public void restart() { | ||
156 | mDaedalus.reset(); | ||
157 | mArrivalTimes.clear(); | ||
158 | mStepCounter = 0; | ||
159 | } | ||
160 | |||
161 | @Override | ||
162 | public void stop() { | ||
163 | List<Prey> forgottenPreys = new LinkedList<Prey>(); | ||
164 | for (Prey prey : mDaedalus.getPreys()) { | ||
165 | forgottenPreys.add(prey); | ||
166 | mDaedalus.removePrey(prey); | ||
167 | } | ||
168 | mArrivalTimes.put(Integer.MIN_VALUE, forgottenPreys); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * Moves the predators in the daedalus. | ||
173 | * | ||
174 | * @param listener | ||
175 | * The listener to which the function will notify the changes | ||
176 | * (can be null) | ||
177 | */ | ||
178 | |||
179 | private void movePredators(Animation listener) { | ||
180 | List<Predator> predators = mDaedalus.getPredators(); | ||
181 | for (int i = 0; i < predators.size(); i++) { | ||
182 | Predator predator = predators.get(i); | ||
183 | Vector2D position = predator.getPosition(); | ||
184 | Vector2D newPosition = position; | ||
185 | Direction[] choices = mDaedalus.getChoices(position); | ||
186 | |||
187 | // tries to make predator move | ||
188 | Direction choice; | ||
189 | try { | ||
190 | choice = predator.move(choices, mDaedalus); | ||
191 | if (!predator.getPosition().equals(position)) { | ||
192 | System.err.println("Error : Predator position changed while choosing direction."); | ||
193 | System.err.println("\tDid you call setPosition(Vector2D) or update(Direction) ?\n"); | ||
194 | predator.setPosition(position); | ||
195 | choice = null; | ||
196 | } | ||
197 | } catch (Exception E) { | ||
198 | System.err.print("Exception occurred while moving animals: "); | ||
199 | E.printStackTrace(); | ||
200 | choice = null; | ||
201 | } | ||
202 | |||
203 | // if predator could move | ||
204 | Action action; | ||
205 | if (choice != null) { | ||
206 | newPosition = position.addDirectionTo(choice); | ||
207 | |||
208 | int x = newPosition.getX(); | ||
209 | int y = newPosition.getY(); | ||
210 | |||