package ch.epfl.maze.physical.zoo; import ch.epfl.maze.physical.Animal; import ch.epfl.maze.physical.stragegies.picker.CyclePicker; import ch.epfl.maze.physical.stragegies.picker.ForwardPicker; import ch.epfl.maze.physical.stragegies.picker.SimplePicker; import ch.epfl.maze.util.Direction; import ch.epfl.maze.util.Vector2D; import java.util.Set; /** * Monkey A.I. that puts its hand on the left wall and follows it. * * @author EPFL * @author Pacien TRAN-GIRARD */ public class Monkey extends Animal implements SimplePicker, ForwardPicker, CyclePicker { public static final Direction SMART_PAW = Direction.LEFT; private boolean foundWall; /** * Constructs a monkey with a starting position. * * @param position Starting position of the monkey in the labyrinth */ public Monkey(Vector2D position) { super(position); this.foundWall = false; } @Override public Direction getStartingDirection() { return this.getDirection().unRelativeDirection(Monkey.SMART_PAW); } @Override public Direction getRotationDirection() { return Monkey.SMART_PAW.reverse(); } /** * Picks a Direction preferably following the "paw rule", or forward if no wall has been encountered, * or any available Direction if the Monkey has no current Direction. * * @param choices A set of Direction choices * @return The picked Direction */ @Override public Direction pick(Set choices) { if (this.getDirection() == Direction.NONE) return SimplePicker.super.pick(choices); else if (!this.foundWall) return ForwardPicker.super.pick(choices); else return CyclePicker.super.pick(choices); } /** * Moves according to the relative left wall that the monkey has to follow. */ @Override public Direction move(Set choices) { if (this.nextToWall(choices)) this.foundWall = true; return this.pick(choices); } @Override public Animal copy() { return new Monkey(this.getPosition()); } /** * Checks is the Monkey is next to a wall. * * @param choices The available Direction choices * @return T(The Direction choices set indicates the presence of a wall) */ private boolean nextToWall(Set choices) { return choices.size() < 4; } }