package ch.epfl.maze.physical.zoo; import ch.epfl.maze.physical.Animal; import ch.epfl.maze.util.Direction; import ch.epfl.maze.util.Vector2D; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Monkey A.I. that puts its hand on the left wall and follows it. * * @author Pacien TRAN-GIRARD */ public class Monkey extends Animal { private Direction currentDirection; /** * Constructs a monkey with a starting position. * * @param position Starting position of the monkey in the labyrinth */ public Monkey(Vector2D position) { super(position); this.currentDirection = Direction.NONE; } /** * Finds a currentDirection following the "left paw rule". * * @param choices An array of possible directions * @return The currentDirection to take according to the "left paw rule" */ private Direction followLeft(Direction[] choices) { List choiceList = new ArrayList<>(Arrays.asList(choices)); Direction dir = this.currentDirection.rotateLeft(); while (!choiceList.contains(dir)) dir = dir.rotateRight(); return dir; } /** * Determines the strategy to follow depending on special cases. * * @param choices An array of possible directions * @return The Direction to take */ private Direction findDirection(Direction[] choices) { if (choices.length == 0) return Direction.NONE; if (this.currentDirection == Direction.NONE) return choices[0]; if (choices.length == 1) return choices[0]; if (choices.length > 3) return choices[0]; return this.followLeft(choices); } /** * Moves according to the relative left wall that the monkey has to follow. */ @Override public Direction move(Direction[] choices) { this.currentDirection = this.findDirection(choices); return this.currentDirection; } @Override public Animal copy() { return new Monkey(this.getPosition()); } }