summaryrefslogtreecommitdiff
path: root/src/ch/epfl/maze/simulation/DaedalusSimulation.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/ch/epfl/maze/simulation/DaedalusSimulation.java')
-rw-r--r--src/ch/epfl/maze/simulation/DaedalusSimulation.java364
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 @@
1package ch.epfl.maze.simulation;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.HashMap;
6import java.util.LinkedList;
7import java.util.List;
8import java.util.Map;
9import java.util.TreeMap;
10
11import ch.epfl.maze.graphics.Animation;
12import ch.epfl.maze.physical.Animal;
13import ch.epfl.maze.physical.Daedalus;
14import ch.epfl.maze.physical.Predator;
15import ch.epfl.maze.physical.Prey;
16import ch.epfl.maze.physical.World;
17import ch.epfl.maze.util.Action;
18import ch.epfl.maze.util.Direction;
19import 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
28public 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