package ch.epfl.maze.physical; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Daedalus in which predators hunt preys. Once a prey has been caught by a * predator, it will be removed from the daedalus. * * @author EPFL * @author Pacien TRAN-GIRARD */ public final class Daedalus extends World { private final Set predators; private final Set predatorHistory; private final Set preys; private final Set preyHistory; /** * Constructs a Daedalus with a labyrinth structure * * @param labyrinth Structure of the labyrinth, an NxM array of tiles */ public Daedalus(int[][] labyrinth) { super(labyrinth); this.predators = new HashSet<>(); this.predatorHistory = new HashSet<>(); this.preys = new HashSet<>(); this.preyHistory = new HashSet<>(); } @Override public boolean isSolved() { return this.preys.isEmpty(); } /** * Adds a predator to the daedalus. * * @param p The predator to add */ public void addPredator(Predator p) { this.predators.add(p); this.predatorHistory.add((Predator) p.copy()); } /** * Adds a prey to the daedalus. * * @param p The prey to add */ public void addPrey(Prey p) { this.preys.add(p); this.preyHistory.add((Prey) p.copy()); } /** * Removes a predator from the daedalus. * * @param p The predator to remove */ public void removePredator(Predator p) { this.predators.remove(p); } /** * Removes a prey from the daedalus. * * @param p The prey to remove */ public void removePrey(Prey p) { this.preys.remove(p); } @Override public Set getAnimalSet() { return Stream .concat(this.predators.stream(), this.preys.stream()) .collect(Collectors.toSet()); } /** * Returns a copy of the set of all current predators in the daedalus. * * @return A set of all predators in the daedalus */ public Set getPredatorSet() { return new HashSet<>(this.predators); } /** * Returns a copy of the list of all current predators in the daedalus. * * @return A list of all predators in the daedalus * @deprecated Use @code{Set getPredatorSet()} instead */ public List getPredators() { return new ArrayList<>(this.getPredatorSet()); } /** * Returns a copy of the set of all current preys in the daedalus. * * @return A set of all preys in the daedalus */ public Set getPreySet() { return new HashSet<>(this.preys); } /** * Returns a copy of the list of all current preys in the daedalus. * * @return A list of all preys in the daedalus * @deprecated Use @code{Set getPreySet()} instead */ public List getPreys() { return new ArrayList<>(this.getPreySet()); } /** * Determines if the daedalus contains a predator. * * @param p The predator in question * @return true if the predator belongs to the world, false * otherwise. */ public boolean hasPredator(Predator p) { return this.predators.contains(p); } /** * Determines if the daedalus contains a prey. * * @param p The prey in question * @return true if the prey belongs to the world, false * otherwise. */ public boolean hasPrey(Prey p) { return this.preys.contains(p); } @Override public void reset() { this.predators.clear(); this.predatorHistory.forEach(p -> this.predators.add((Predator) p.copy())); this.preys.clear(); this.preyHistory.forEach(p -> this.preys.add((Prey) p.copy())); } }