From 90bd766f361083f6fd9e39ff080c83fcc606832f Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Sat, 21 Nov 2015 10:44:42 +0100 Subject: Reformat imported code --- .../epfl/maze/simulation/DaedalusSimulation.java | 681 ++++++++++----------- src/ch/epfl/maze/simulation/MazeSimulation.java | 381 ++++++------ src/ch/epfl/maze/simulation/Simulation.java | 108 ++-- 3 files changed, 575 insertions(+), 595 deletions(-) (limited to 'src/ch/epfl/maze/simulation') diff --git a/src/ch/epfl/maze/simulation/DaedalusSimulation.java b/src/ch/epfl/maze/simulation/DaedalusSimulation.java index 2082772..8b60b57 100644 --- a/src/ch/epfl/maze/simulation/DaedalusSimulation.java +++ b/src/ch/epfl/maze/simulation/DaedalusSimulation.java @@ -1,364 +1,349 @@ package ch.epfl.maze.simulation; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - import ch.epfl.maze.graphics.Animation; -import ch.epfl.maze.physical.Animal; -import ch.epfl.maze.physical.Daedalus; -import ch.epfl.maze.physical.Predator; -import ch.epfl.maze.physical.Prey; -import ch.epfl.maze.physical.World; +import ch.epfl.maze.physical.*; import ch.epfl.maze.util.Action; import ch.epfl.maze.util.Direction; import ch.epfl.maze.util.Vector2D; +import java.util.*; + /** * Simulation of a predation environment. Handles the next moves of every * predator and prey in a Daedalus, as well as the animation by notifying * changes to it. The simulation finishes when every prey has been caught. - * */ public final class DaedalusSimulation implements Simulation { - /* limit to the step counter, over which the animals are considered lost */ - public static final int COUNTER_LIMIT = 10000; - - /* simulation components */ - private Daedalus mDaedalus; - private Map> mArrivalTimes; - private int mStepCounter; - - /* collision check variables */ - private Map> mPreyMoves; - private Map> mPredatorMoves; - - /** - * Constructs a simulation with a {@code Daedalus} to simulate. - * - * @param daedalus - * The daedalus to simulate - */ - - public DaedalusSimulation(Daedalus daedalus) { - mDaedalus = daedalus; - mArrivalTimes = new TreeMap>(Collections.reverseOrder()); - mStepCounter = 0; - mPreyMoves = new HashMap>(); - mPredatorMoves = new HashMap>(); - } - - @Override - public void move(Animation listener) { - if (isOver()) { - return; - } - - // clears moves maps - mPreyMoves.clear(); - mPredatorMoves.clear(); - - // increments counter - mStepCounter++; - - // if counter exceeded the limit, it considers preys safe - if (mStepCounter > COUNTER_LIMIT) { - List preys = mDaedalus.getPreys(); - List safePreys = new LinkedList(); - for (Prey prey : preys) { - mDaedalus.removePrey(prey); - safePreys.add(prey); - } - - mArrivalTimes.put(Integer.MAX_VALUE, safePreys); // infinite - return; - } - - // asks predators and preys to move - movePredators(listener); - movePreys(listener); - - // checks collisions - checkCollisions(listener); - - // notifies animation that all the changes are done - if (listener != null) { - listener.doneUpdating(); - } - } - - @Override - public boolean isOver() { - return mDaedalus.isSolved(); - } - - @Override - public World getWorld() { - return mDaedalus; - } - - @Override - public int getSteps() { - return mStepCounter; - } - - @Override - public Map> getArrivalTimes() { - TreeMap> arrivalTimes = new TreeMap>(); - for (Map.Entry> entry : mArrivalTimes.entrySet()) { - int time = entry.getKey(); - List animals = new ArrayList(entry.getValue()); - arrivalTimes.put(time, animals); - } - - return arrivalTimes; - } - - @Override - public String getRecordTable() { - String recordTable = ""; - int position = 1; - for (Map.Entry> entry : mArrivalTimes.entrySet()) { - // only returns the 10 first - if (position > 10) { - return recordTable; - } - - for (Prey prey : entry.getValue()) { - if (entry.getKey() == Integer.MIN_VALUE) { - recordTable += "-- "; - recordTable += prey.getClass().getSimpleName(); - recordTable += " - never finished\n"; - } else { - recordTable += position + ". "; - recordTable += prey.getClass().getSimpleName(); - if (entry.getKey() == Integer.MAX_VALUE) { - recordTable += " - has survived\n"; - } else { - recordTable += " - " + entry.getKey() + " steps\n"; - } - } - } - position += entry.getValue().size(); - } - - return recordTable; - } - - @Override - public void restart() { - mDaedalus.reset(); - mArrivalTimes.clear(); - mStepCounter = 0; - } - - @Override - public void stop() { - List forgottenPreys = new LinkedList(); - for (Prey prey : mDaedalus.getPreys()) { - forgottenPreys.add(prey); - mDaedalus.removePrey(prey); - } - mArrivalTimes.put(Integer.MIN_VALUE, forgottenPreys); - } - - /** - * Moves the predators in the daedalus. - * - * @param listener - * The listener to which the function will notify the changes - * (can be null) - */ - - private void movePredators(Animation listener) { - List predators = mDaedalus.getPredators(); - for (int i = 0; i < predators.size(); i++) { - Predator predator = predators.get(i); - Vector2D position = predator.getPosition(); - Vector2D newPosition = position; - Direction[] choices = mDaedalus.getChoices(position); - - // tries to make predator move - Direction choice; - try { - choice = predator.move(choices, mDaedalus); - if (!predator.getPosition().equals(position)) { - System.err.println("Error : Predator position changed while choosing direction."); - System.err.println("\tDid you call setPosition(Vector2D) or update(Direction) ?\n"); - predator.setPosition(position); - choice = null; - } - } catch (Exception E) { - System.err.print("Exception occurred while moving animals: "); - E.printStackTrace(); - choice = null; - } - - // if predator could move - Action action; - if (choice != null) { - newPosition = position.addDirectionTo(choice); - - int x = newPosition.getX(); - int y = newPosition.getY(); - - if (mDaedalus.isFree(x, y)) { - action = new Action(choice, true); - } else { - newPosition = position; - action = new Action(choice, false); - choice = Direction.NONE; - } - - if (listener != null) { - // asks animation to draw corresponding action - listener.update(predator, i, action); - } - - predator.update(choice); - } else { - if (listener != null) { - // asks animation to draw a confused animal - action = new Action(Direction.NONE, false); - listener.update(predator, i, action); - } - } - - // records position changes to handle collisions - List moves = new ArrayList(); - moves.add(position); - moves.add(newPosition); - mPredatorMoves.put(predator, moves); - } - } - - /** - * Moves the preys in the daedalus. - * - * @param listener - * The listener to which the function will notify the changes - * (can be null) - */ - - private void movePreys(Animation listener) { - List preys = mDaedalus.getPreys(); - Action action; - Direction choice; - for (int i = 0; i < preys.size(); i++) { - Prey prey = preys.get(i); - Vector2D position = prey.getPosition(); - Vector2D newPosition = position; - Direction[] choices = mDaedalus.getChoices(position); - - // tries to make prey move - try { - choice = prey.move(choices, mDaedalus); - if (!prey.getPosition().equals(position)) { - System.err.println("Error : Prey position changed while choosing direction."); - System.err.println("\tDid you call setPosition(Vector2D) or update(Direction) ?\n"); - prey.setPosition(position); - choice = null; - } - } catch (Exception E) { - System.err.print("Exception occurred while moving animals: "); - E.printStackTrace(); - choice = null; - } - - // if prey could move - if (choice != null) { - newPosition = position.addDirectionTo(choice); - - int x = newPosition.getX(); - int y = newPosition.getY(); - - if (mDaedalus.isFree(x, y)) { - action = new Action(choice, true); - } else { - newPosition = position; - action = new Action(choice, false); - choice = Direction.NONE; - } - - if (listener != null) { - // draws animation - listener.update(prey, i + mDaedalus.getPredators().size(), action); - } - prey.update(choice); - } else { - if (listener != null) { - action = new Action(Direction.NONE, false); - listener.update(prey, i + mDaedalus.getPredators().size(), action); - } - } - - // records position changes to handle collisions - List moves = new ArrayList(); - moves.add(position); - moves.add(newPosition); - mPreyMoves.put(prey, moves); - } - } - - /** - * Checks collisions between predators and preys in {@codeO(n*m)}. A collision - * occurs if two animals land on the same tile, or when they run into each - * other. - *

- * A special case is handled when animals run into each other. The animation - * is notified that an animal dies between two squares. - * - * @param listener - * The listener to which the function will notify the changes - * (can be null) - */ - - private void checkCollisions(Animation listener) { - List predators = mDaedalus.getPredators(); - List preys = mDaedalus.getPreys(); - - for (int i = 0; i < predators.size(); ++i) { - Predator a = predators.get(i); - List aChanges = mPredatorMoves.get(a); - for (int j = 0; j < preys.size(); ++j) { - Prey b = preys.get(j); - List bChanges = mPreyMoves.get(b); - - // position changes for animal a - Vector2D aOld = aChanges.get(0); - Vector2D aNew = aChanges.get(1); - // position changes for animal b - Vector2D bOld = bChanges.get(0); - Vector2D bNew = bChanges.get(1); - - // if (a.new == b.new) or (a.old == b.new and b.old == a.new) - boolean diesInBetween = aOld.equals(bNew) && bOld.equals(aNew); - boolean diesInPlace = aNew.equals(bNew); - - if (diesInPlace || diesInBetween) { - if (mDaedalus.hasPrey(b)) { - mDaedalus.removePrey(b); - - // records survival time - if (mArrivalTimes.get(mStepCounter) == null) { - mArrivalTimes.put(mStepCounter, new LinkedList()); - } - mArrivalTimes.get(mStepCounter).add(b); - - // asks animation to interrupt movement if it dies - // moving - if (listener != null && diesInBetween) { - listener.updateDying(j + predators.size()); - } - } - } - } - } - } + /* limit to the step counter, over which the animals are considered lost */ + public static final int COUNTER_LIMIT = 10000; + + /* simulation components */ + private Daedalus mDaedalus; + private Map> mArrivalTimes; + private int mStepCounter; + + /* collision check variables */ + private Map> mPreyMoves; + private Map> mPredatorMoves; + + /** + * Constructs a simulation with a {@code Daedalus} to simulate. + * + * @param daedalus The daedalus to simulate + */ + + public DaedalusSimulation(Daedalus daedalus) { + mDaedalus = daedalus; + mArrivalTimes = new TreeMap>(Collections.reverseOrder()); + mStepCounter = 0; + mPreyMoves = new HashMap>(); + mPredatorMoves = new HashMap>(); + } + + @Override + public void move(Animation listener) { + if (isOver()) { + return; + } + + // clears moves maps + mPreyMoves.clear(); + mPredatorMoves.clear(); + + // increments counter + mStepCounter++; + + // if counter exceeded the limit, it considers preys safe + if (mStepCounter > COUNTER_LIMIT) { + List preys = mDaedalus.getPreys(); + List safePreys = new LinkedList(); + for (Prey prey : preys) { + mDaedalus.removePrey(prey); + safePreys.add(prey); + } + + mArrivalTimes.put(Integer.MAX_VALUE, safePreys); // infinite + return; + } + + // asks predators and preys to move + movePredators(listener); + movePreys(listener); + + // checks collisions + checkCollisions(listener); + + // notifies animation that all the changes are done + if (listener != null) { + listener.doneUpdating(); + } + } + + @Override + public boolean isOver() { + return mDaedalus.isSolved(); + } + + @Override + public World getWorld() { + return mDaedalus; + } + + @Override + public int getSteps() { + return mStepCounter; + } + + @Override + public Map> getArrivalTimes() { + TreeMap> arrivalTimes = new TreeMap>(); + for (Map.Entry> entry : mArrivalTimes.entrySet()) { + int time = entry.getKey(); + List animals = new ArrayList(entry.getValue()); + arrivalTimes.put(time, animals); + } + + return arrivalTimes; + } + + @Override + public String getRecordTable() { + String recordTable = ""; + int position = 1; + for (Map.Entry> entry : mArrivalTimes.entrySet()) { + // only returns the 10 first + if (position > 10) { + return recordTable; + } + + for (Prey prey : entry.getValue()) { + if (entry.getKey() == Integer.MIN_VALUE) { + recordTable += "-- "; + recordTable += prey.getClass().getSimpleName(); + recordTable += " - never finished\n"; + } else { + recordTable += position + ". "; + recordTable += prey.getClass().getSimpleName(); + if (entry.getKey() == Integer.MAX_VALUE) { + recordTable += " - has survived\n"; + } else { + recordTable += " - " + entry.getKey() + " steps\n"; + } + } + } + position += entry.getValue().size(); + } + + return recordTable; + } + + @Override + public void restart() { + mDaedalus.reset(); + mArrivalTimes.clear(); + mStepCounter = 0; + } + + @Override + public void stop() { + List forgottenPreys = new LinkedList(); + for (Prey prey : mDaedalus.getPreys()) { + forgottenPreys.add(prey); + mDaedalus.removePrey(prey); + } + mArrivalTimes.put(Integer.MIN_VALUE, forgottenPreys); + } + + /** + * Moves the predators in the daedalus. + * + * @param listener The listener to which the function will notify the changes + * (can be null) + */ + + private void movePredators(Animation listener) { + List predators = mDaedalus.getPredators(); + for (int i = 0; i < predators.size(); i++) { + Predator predator = predators.get(i); + Vector2D position = predator.getPosition(); + Vector2D newPosition = position; + Direction[] choices = mDaedalus.getChoices(position); + + // tries to make predator move + Direction choice; + try { + choice = predator.move(choices, mDaedalus); + if (!predator.getPosition().equals(position)) { + System.err.println("Error : Predator position changed while choosing direction."); + System.err.println("\tDid you call setPosition(Vector2D) or update(Direction) ?\n"); + predator.setPosition(position); + choice = null; + } + } catch (Exception E) { + System.err.print("Exception occurred while moving animals: "); + E.printStackTrace(); + choice = null; + } + + // if predator could move + Action action; + if (choice != null) { + newPosition = position.addDirectionTo(choice); + + int x = newPosition.getX(); + int y = newPosition.getY(); + + if (mDaedalus.isFree(x, y)) { + action = new Action(choice, true); + } else { + newPosition = position; + action = new Action(choice, false); + choice = Direction.NONE; + } + + if (listener != null) { + // asks animation to draw corresponding action + listener.update(predator, i, action); + } + + predator.update(choice); + } else { + if (listener != null) { + // asks animation to draw a confused animal + action = new Action(Direction.NONE, false); + listener.update(predator, i, action); + } + } + + // records position changes to handle collisions + List moves = new ArrayList(); + moves.add(position); + moves.add(newPosition); + mPredatorMoves.put(predator, moves); + } + } + + /** + * Moves the preys in the daedalus. + * + * @param listener The listener to which the function will notify the changes + * (can be null) + */ + + private void movePreys(Animation listener) { + List preys = mDaedalus.getPreys(); + Action action; + Direction choice; + for (int i = 0; i < preys.size(); i++) { + Prey prey = preys.get(i); + Vector2D position = prey.getPosition(); + Vector2D newPosition = position; + Direction[] choices = mDaedalus.getChoices(position); + + // tries to make prey move + try { + choice = prey.move(choices, mDaedalus); + if (!prey.getPosition().equals(position)) { + System.err.println("Error : Prey position changed while choosing direction."); + System.err.println("\tDid you call setPosition(Vector2D) or update(Direction) ?\n"); + prey.setPosition(position); + choice = null; + } + } catch (Exception E) { + System.err.print("Exception occurred while moving animals: "); + E.printStackTrace(); + choice = null; + } + + // if prey could move + if (choice != null) { + newPosition = position.addDirectionTo(choice); + + int x = newPosition.getX(); + int y = newPosition.getY(); + + if (mDaedalus.isFree(x, y)) { + action = new Action(choice, true); + } else { + newPosition = position; + action = new Action(choice, false); + choice = Direction.NONE; + } + + if (listener != null) { + // draws animation + listener.update(prey, i + mDaedalus.getPredators().size(), action); + } + prey.update(choice); + } else { + if (listener != null) { + action = new Action(Direction.NONE, false); + listener.update(prey, i + mDaedalus.getPredators().size(), action); + } + } + + // records position changes to handle collisions + List moves = new ArrayList(); + moves.add(position); + moves.add(newPosition); + mPreyMoves.put(prey, moves); + } + } + + /** + * Checks collisions between predators and preys in {@codeO(n*m)}. A collision + * occurs if two animals land on the same tile, or when they run into each + * other. + *

+ * A special case is handled when animals run into each other. The animation + * is notified that an animal dies between two squares. + * + * @param listener The listener to which the function will notify the changes + * (can be null) + */ + + private void checkCollisions(Animation listener) { + List predators = mDaedalus.getPredators(); + List preys = mDaedalus.getPreys(); + + for (int i = 0; i < predators.size(); ++i) { + Predator a = predators.get(i); + List aChanges = mPredatorMoves.get(a); + for (int j = 0; j < preys.size(); ++j) { + Prey b = preys.get(j); + List bChanges = mPreyMoves.get(b); + + // position changes for animal a + Vector2D aOld = aChanges.get(0); + Vector2D aNew = aChanges.get(1); + // position changes for animal b + Vector2D bOld = bChanges.get(0); + Vector2D bNew = bChanges.get(1); + + // if (a.new == b.new) or (a.old == b.new and b.old == a.new) + boolean diesInBetween = aOld.equals(bNew) && bOld.equals(aNew); + boolean diesInPlace = aNew.equals(bNew); + + if (diesInPlace || diesInBetween) { + if (mDaedalus.hasPrey(b)) { + mDaedalus.removePrey(b); + + // records survival time + if (mArrivalTimes.get(mStepCounter) == null) { + mArrivalTimes.put(mStepCounter, new LinkedList()); + } + mArrivalTimes.get(mStepCounter).add(b); + + // asks animation to interrupt movement if it dies + // moving + if (listener != null && diesInBetween) { + listener.updateDying(j + predators.size()); + } + } + } + } + } + } } diff --git a/src/ch/epfl/maze/simulation/MazeSimulation.java b/src/ch/epfl/maze/simulation/MazeSimulation.java index d70f735..3fd0e52 100644 --- a/src/ch/epfl/maze/simulation/MazeSimulation.java +++ b/src/ch/epfl/maze/simulation/MazeSimulation.java @@ -1,10 +1,5 @@ package ch.epfl.maze.simulation; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - import ch.epfl.maze.graphics.Animation; import ch.epfl.maze.physical.Animal; import ch.epfl.maze.physical.Maze; @@ -13,199 +8,201 @@ import ch.epfl.maze.util.Action; import ch.epfl.maze.util.Direction; import ch.epfl.maze.util.Vector2D; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + /** * Simulation of a maze solver. Handles the next move of each animal, as well as * the animation by notifying the changes to it. The simulation finishes when * every animal has found the exit. - * */ public final class MazeSimulation implements Simulation { - /* limit to the step counter, over which the animals are considered lost */ - public static final int COUNTER_LIMIT = 10000; - - /* simulation components */ - private Maze mMaze; - private Map> mArrivalTimes; - private int mStepCounter; - - /** - * Constructs a simulation with a {@code Maze} to simulate. - * - * @param maze - * The maze to simulate - */ - - public MazeSimulation(Maze maze) { - mMaze = maze; - mArrivalTimes = new TreeMap>(); - mStepCounter = 0; - } - - @Override - public void move(Animation listener) { - if (isOver()) { - return; - } - - // increments counter - mStepCounter++; - - // if counter exceeded limit, it considers animals lost - if (mStepCounter > COUNTER_LIMIT) { - List animals = mMaze.getAnimals(); - List lostAnimals = new LinkedList(); - for (Animal animal : animals) { - mMaze.removeAnimal(animal); - lostAnimals.add(animal); - } - - mArrivalTimes.put(Integer.MAX_VALUE, lostAnimals); // infinite - return; - } - - // asks animals to move - moveAnimals(listener); - - // notifies animation that all the changes are done - if (listener != null) { - listener.doneUpdating(); - } - } - - @Override - public boolean isOver() { - return mMaze.isSolved(); - } - - @Override - public World getWorld() { - return mMaze; - } - - @Override - public int getSteps() { - return mStepCounter; - } - - public Map> getArrivalTimes() { - return new TreeMap>(mArrivalTimes); - } - - public String getRecordTable() { - String recordTable = ""; - int position = 1; - for (Map.Entry> entry : mArrivalTimes.entrySet()) { - // only returns the 10 first - if (position > 10) { - return recordTable; - } - - for (Animal animal : entry.getValue()) { - if (entry.getKey() == Integer.MAX_VALUE) { - recordTable += "-- "; - recordTable += animal.getClass().getSimpleName(); - recordTable += " - never finished\n"; - } else { - recordTable += position + ". "; - recordTable += animal.getClass().getSimpleName(); - recordTable += " - " + entry.getKey() + " steps\n"; - } - } - position += entry.getValue().size(); - } - - return recordTable; - } - - @Override - public void restart() { - mMaze.reset(); - mArrivalTimes.clear(); - mStepCounter = 0; - } - - @Override - public void stop() { - List forgottenAnimals = new LinkedList(); - for (Animal animal : mMaze.getAnimals()) { - forgottenAnimals.add(animal); - mMaze.removeAnimal(animal); - } - mArrivalTimes.put(Integer.MAX_VALUE, forgottenAnimals); - } - - /** - * Moves the animals in the maze. - * - * @param listener - * The listener to which the function will notify the changes - * (can be null) - */ - - private void moveAnimals(Animation listener) { - List animals = mMaze.getAnimals(); - for (int i = 0; i < animals.size(); i++) { - Animal animal = animals.get(i); - Vector2D position = animal.getPosition(); - Direction[] choices = mMaze.getChoices(position); - - // tries to make animal move - Direction choice; - try { - choice = animal.move(choices); - if (!animal.getPosition().equals(position)) { - System.err.println("Error : Animal position changed while choosing direction."); - System.err.println("\tDid you call setPosition(Vector2D) or update(Direction) ?\n"); - animal.setPosition(position); - choice = null; - } - } catch (Exception E) { - System.err.print("Exception occurred while moving animals: "); - E.printStackTrace(); - choice = null; - } - - // if animal could move - if (choice != null) { - Vector2D futurePosition = animal.getPosition(); - futurePosition = futurePosition.addDirectionTo(choice); - - int x = futurePosition.getX(); - int y = futurePosition.getY(); - - - if (mMaze.isFree(x, y)) { - // asks animation to draw the action of the animal - if (listener != null) { - Action action = new Action(choice, true); - listener.update(animal, i, action); - } - - // if at the end of the maze - if (mMaze.getTile(x, y) == World.EXIT) { - mMaze.removeAnimal(animal); - - // records arrival time - if (mArrivalTimes.get(mStepCounter) == null) { - mArrivalTimes.put(mStepCounter, new LinkedList()); - } - mArrivalTimes.get(mStepCounter).add(animal); - } else { - animal.update(choice); - } - } else if (listener != null) { - // asks animation to draw an interrupted movement - Action action = new Action(choice, false); - listener.update(animal, i, action); - } - - } else if (listener != null) { - // asks animation to draw a confused animal - Action action = new Action(Direction.NONE, false); - listener.update(animal, i, action); - } - } - } + /* limit to the step counter, over which the animals are considered lost */ + public static final int COUNTER_LIMIT = 10000; + + /* simulation components */ + private Maze mMaze; + private Map> mArrivalTimes; + private int mStepCounter; + + /** + * Constructs a simulation with a {@code Maze} to simulate. + * + * @param maze The maze to simulate + */ + + public MazeSimulation(Maze maze) { + mMaze = maze; + mArrivalTimes = new TreeMap>(); + mStepCounter = 0; + } + + @Override + public void move(Animation listener) { + if (isOver()) { + return; + } + + // increments counter + mStepCounter++; + + // if counter exceeded limit, it considers animals lost + if (mStepCounter > COUNTER_LIMIT) { + List animals = mMaze.getAnimals(); + List lostAnimals = new LinkedList(); + for (Animal animal : animals) { + mMaze.removeAnimal(animal); + lostAnimals.add(animal); + } + + mArrivalTimes.put(Integer.MAX_VALUE, lostAnimals); // infinite + return; + } + + // asks animals to move + moveAnimals(listener); + + // notifies animation that all the changes are done + if (listener != null) { + listener.doneUpdating(); + } + } + + @Override + public boolean isOver() { + return mMaze.isSolved(); + } + + @Override + public World getWorld() { + return mMaze; + } + + @Override + public int getSteps() { + return mStepCounter; + } + + public Map> getArrivalTimes() { + return new TreeMap>(mArrivalTimes); + } + + public String getRecordTable() { + String recordTable = ""; + int position = 1; + for (Map.Entry> entry : mArrivalTimes.entrySet()) { + // only returns the 10 first + if (position > 10) { + return recordTable; + } + + for (Animal animal : entry.getValue()) { + if (entry.getKey() == Integer.MAX_VALUE) { + recordTable += "-- "; + recordTable += animal.getClass().getSimpleName(); + recordTable += " - never finished\n"; + } else { + recordTable += position + ". "; + recordTable += animal.getClass().getSimpleName(); + recordTable += " - " + entry.getKey() + " steps\n"; + } + } + position += entry.getValue().size(); + } + + return recordTable; + } + + @Override + public void restart() { + mMaze.reset(); + mArrivalTimes.clear(); + mStepCounter = 0; + } + + @Override + public void stop() { + List forgottenAnimals = new LinkedList(); + for (Animal animal : mMaze.getAnimals()) { + forgottenAnimals.add(animal); + mMaze.removeAnimal(animal); + } + mArrivalTimes.put(Integer.MAX_VALUE, forgottenAnimals); + } + + /** + * Moves the animals in the maze. + * + * @param listener The listener to which the function will notify the changes + * (can be null) + */ + + private void moveAnimals(Animation listener) { + List animals = mMaze.getAnimals(); + for (int i = 0; i < animals.size(); i++) { + Animal animal = animals.get(i); + Vector2D position = animal.getPosition(); + Direction[] choices = mMaze.getChoices(position); + + // tries to make animal move + Direction choice; + try { + choice = animal.move(choices); + if (!animal.getPosition().equals(position)) { + System.err.println("Error : Animal position changed while choosing direction."); + System.err.println("\tDid you call setPosition(Vector2D) or update(Direction) ?\n"); + animal.setPosition(position); + choice = null; + } + } catch (Exception E) { + System.err.print("Exception occurred while moving animals: "); + E.printStackTrace(); + choice = null; + } + + // if animal could move + if (choice != null) { + Vector2D futurePosition = animal.getPosition(); + futurePosition = futurePosition.addDirectionTo(choice); + + int x = futurePosition.getX(); + int y = futurePosition.getY(); + + + if (mMaze.isFree(x, y)) { + // asks animation to draw the action of the animal + if (listener != null) { + Action action = new Action(choice, true); + listener.update(animal, i, action); + } + + // if at the end of the maze + if (mMaze.getTile(x, y) == World.EXIT) { + mMaze.removeAnimal(animal); + + // records arrival time + if (mArrivalTimes.get(mStepCounter) == null) { + mArrivalTimes.put(mStepCounter, new LinkedList()); + } + mArrivalTimes.get(mStepCounter).add(animal); + } else { + animal.update(choice); + } + } else if (listener != null) { + // asks animation to draw an interrupted movement + Action action = new Action(choice, false); + listener.update(animal, i, action); + } + + } else if (listener != null) { + // asks animation to draw a confused animal + Action action = new Action(Direction.NONE, false); + listener.update(animal, i, action); + } + } + } } diff --git a/src/ch/epfl/maze/simulation/Simulation.java b/src/ch/epfl/maze/simulation/Simulation.java index c3190b3..ab2fb84 100644 --- a/src/ch/epfl/maze/simulation/Simulation.java +++ b/src/ch/epfl/maze/simulation/Simulation.java @@ -1,84 +1,82 @@ package ch.epfl.maze.simulation; -import java.util.List; -import java.util.Map; - import ch.epfl.maze.graphics.Animation; import ch.epfl.maze.physical.Animal; import ch.epfl.maze.physical.World; +import java.util.List; +import java.util.Map; + /** * The {@code Simulation} interface defines a set of rules that must be * fulfilled in order to be displayed. - * */ public interface Simulation { - /** - * Asks the {@code Simulation} to compute the next move and, if specified, - * notifies the changes to the listener. - * - * @param listener - * The listener to which the function will notify the changes - * (can be null) - */ + /** + * Asks the {@code Simulation} to compute the next move and, if specified, + * notifies the changes to the listener. + * + * @param listener The listener to which the function will notify the changes + * (can be null) + */ - public void move(Animation listener); + public void move(Animation listener); - /** - * Determines if the simulation is over. - * - * @return true if no more moves can be made, false otherwise - */ + /** + * Determines if the simulation is over. + * + * @return true if no more moves can be made, false otherwise + */ - public boolean isOver(); + public boolean isOver(); - /** - * Retrieves the current state of the simulated world. - * - * @return The {@code World} that is being simulated - */ + /** + * Retrieves the current state of the simulated world. + * + * @return The {@code World} that is being simulated + */ - public World getWorld(); + public World getWorld(); - /** - * Retrieves the step counter of the {@code Simulation}. - * - * @return The current step counter - */ + /** + * Retrieves the step counter of the {@code Simulation}. + * + * @return The current step counter + */ - public int getSteps(); + public int getSteps(); - /** - * Retrieves the mapping of the steps done by the animals that have finished - * the simulation. - * - * @return Map of steps done by animals which have accomplished the - * simulation - */ + /** + * Retrieves the mapping of the steps done by the animals that have finished + * the simulation. + * + * @return Map of steps done by animals which have accomplished the + * simulation + */ - public Map> getArrivalTimes(); + public Map> getArrivalTimes(); - /** - * Retrieves the record table of the animals that have finished the - * simulation. - * - * @return A {@code String} containing the top 10 animals which have - * accomplished the simulation - */ + /** + * Retrieves the record table of the animals that have finished the + * simulation. + * + * @return A {@code String} containing the top 10 animals which have + * accomplished the simulation + */ - public String getRecordTable(); + public String getRecordTable(); - /** - * Restarts the simulation from the beginning. - */ + /** + * Restarts the simulation from the beginning. + */ - public void restart(); + public void restart(); - /** - * Stops abruptly the simulation. - */ + /** + * Stops abruptly the simulation. + */ - public void stop(); + public void stop(); } -- cgit v1.2.3