package ai.pathfinder.search;

import ai.pathfinder.core.Action;
import ai.pathfinder.core.Failure;
import ai.pathfinder.core.Node;
import ai.pathfinder.core.Problem;
import ai.pathfinder.core.Solution;

public class HillClimbingSearch extends SearchAlgorithm {

    private Heuristic h;
    private Problem problem;

    public HillClimbingSearch() {
        this(new ManhattanDistanceHeuristic());
    }

    public HillClimbingSearch(Heuristic h) {
        this.algorithmName = "Hill-Climbing Search";
        this.h = h;
    }

    @Override
    public SearchResult search(Problem problem) {
        this.problem = problem;
        Node current = problem.getInitialNode();

        reset();
        while (true) {
            Node neightbor = getHighestValueNode(current);
            if (getValue(neightbor) <= getValue(current)) {
                break;
            }
            current = neightbor;
            removeFrontier(current);
        }
        if (problem.isGoal(current)) return new Solution(current);
        return new Failure();
    }

    private int getValue(Node node) {
        return h.evaluate(node, problem.getGoalNode()) * -1;
    }

    private Node getHighestValueNode(Node node) {
        Node bestNode = null;

        addExplored(node);
        for (Action action : problem.getActions(node)) {
            Node childNode = problem.getResult(node, action);
            addFrontier(childNode);
            if (bestNode == null || getValue(bestNode) < getValue(childNode)) {
                bestNode = childNode;
            }
        }
        return bestNode;
    }

}

@@ -762,32 +762,66 @@
 eNode(current);%0A
+            addExplored(current);%0A
             if (
@@ -860,24 +860,24 @@
 current)) %7B%0A
-
             
@@ -938,45 +938,8 @@
 or;%0A
-            removeFrontier(current);%0A
     
@@ -1239,35 +1239,8 @@
 l;%0A%0A
-        addExplored(node);%0A
     
@@ -1354,16 +1354,17 @@
 ction);%0A
+%0A
         
@@ -1505,24 +1505,24 @@
  childNode;%0A
-
             
@@ -1515,32 +1515,71 @@
 ;%0A            %7D%0A
+            removeFrontier(childNode);%0A
         %7D%0A      

update hill-climbing animation