001/*
002 * This file is part of Baritone.
003 *
004 * Baritone is free software: you can redistribute it and/or modify
005 * it under the terms of the GNU Lesser General Public License as published by
006 * the Free Software Foundation, either version 3 of the License, or
007 * (at your option) any later version.
008 *
009 * Baritone is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public License
015 * along with Baritone.  If not, see <https://www.gnu.org/licenses/>.
016 */
017
018package baritone.api.pathing.goals;
019
020import java.util.Arrays;
021
022/**
023 * A composite of many goals, any one of which satisfies the composite.
024 * For example, a GoalComposite of block goals for every oak log in loaded chunks
025 * would result in it pathing to the easiest oak log to get to
026 *
027 * @author avecowa
028 */
029public class GoalComposite implements Goal {
030
031    /**
032     * An array of goals that any one of must be satisfied
033     */
034    private final Goal[] goals;
035
036    public GoalComposite(Goal... goals) {
037        this.goals = goals;
038    }
039
040    @Override
041    public boolean isInGoal(int x, int y, int z) {
042        for (Goal goal : goals) {
043            if (goal.isInGoal(x, y, z)) {
044                return true;
045            }
046        }
047        return false;
048    }
049
050    @Override
051    public double heuristic(int x, int y, int z) {
052        double min = Double.MAX_VALUE;
053        for (Goal g : goals) {
054            // TODO technically this isn't admissible...?
055            min = Math.min(min, g.heuristic(x, y, z)); // whichever is closest
056        }
057        return min;
058    }
059
060    @Override
061    public double heuristic() {
062        double min = Double.MAX_VALUE;
063        for (Goal g : goals) {
064            // just take the highest value that is guaranteed to be inside the goal
065            min = Math.min(min, g.heuristic());
066        }
067        return min;
068    }
069
070    @Override
071    public String toString() {
072        return "GoalComposite" + Arrays.toString(goals);
073    }
074
075    public Goal[] goals() {
076        return goals;
077    }
078}