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.Arrays;
import java.util.List;
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 Pacien TRAN-GIRARD
 */

public class Hamster extends ProbabilisticAnimal {

    private final List<Vector2D> 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 An array of choices
     * @return An array of smart choices
     */

    private Direction[] excludeDeadPaths(Direction[] choices) {
        return (new ArrayList<>(Arrays.asList(choices)))
                .stream()
                .filter(dir -> !this.deadPaths.contains(this.getPosition().addDirectionTo(dir)))
                .collect(Collectors.toList())
                .toArray(new Direction[0]);
    }

    /**
     * Moves without retracing directly its steps and by avoiding the dead-ends
     * it learns during its journey.
     */

    @Override
    public Direction move(Direction[] choices) {
        Direction[] smartChoices = this.excludeDeadPaths(choices);
        if (smartChoices.length == 1) this.deadPaths.add(this.getPosition()); // dead end
        return super.move(smartChoices);
    }

    @Override
    public Animal copy() {
        return new Hamster(this.getPosition());
    }
}