package ch.epfl.maze.physical.zoo; import ch.epfl.maze.physical.Animal; import ch.epfl.maze.physical.ProbabilisticAnimal; import ch.epfl.maze.util.Direction; import ch.epfl.maze.util.Vector2D; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * Hamster A.I. that remembers the previous choice it has made and the dead ends * it has already met. * * @author EPFL * @author Pacien TRAN-GIRARD */ public class Hamster extends ProbabilisticAnimal { private final List deadPaths; /** * Constructs a hamster with a starting position. * * @param position Starting position of the hamster in the labyrinth */ public Hamster(Vector2D position) { super(position); this.deadPaths = new ArrayList<>(); } /** * Discard directions known to lead to dead ends. * * @param choices A set of choices * @return A set of smart choices */ private Set excludeDeadPaths(Set choices) { return choices .stream() .filter(dir -> !this.deadPaths.contains(this.getPosition().addDirectionTo(dir))) .collect(Collectors.toSet()); } /** * Moves without retracing directly its steps and by avoiding the dead-ends * it learns during its journey. */ @Override public Direction move(Set choices) { Set smartChoices = this.excludeDeadPaths(choices); if (smartChoices.size() == 1) this.deadPaths.add(this.getPosition()); // dead end return super.move(smartChoices); } @Override public Animal copy() { return new Hamster(this.getPosition()); } }