private void ReconstructPlan(ref AntAIPlan aPlan, List <AntAINode> aClosed, AntAINode aGoal) { aPlan.Reset(); int index; AntAINode current = aGoal; while (current != null && current.parent != null) { aPlan.Insert(current.action); index = FindEqual(aClosed, current.parent); current = (index == -1) ? aClosed[0] : aClosed[index]; } }
/// <summary> /// Builds the plan. /// </summary> /// <param name="aPlan">Reference to the result Plan.</param> /// <param name="aCurrent">Current World State.</param> /// <param name="aGoal">Goal World State that we want reach.</param> public void MakePlan(ref AntAIPlan aPlan, AntAICondition aCurrent, AntAICondition aGoal) { #if UNITY_EDITOR DebugConditions = aCurrent.Clone(); #endif var opened = new List <AntAINode>(); var closed = new List <AntAINode>(); opened.Add(new AntAINode { world = aCurrent, parent = null, cost = 0, heuristic = aCurrent.Heuristic(aGoal), sum = aCurrent.Heuristic(aGoal), action = string.Empty }); AntAINode current = opened[0]; while (opened.Count > 0) { // Find lowest rank. current = opened[0]; for (int i = 1, n = opened.Count; i < n; i++) { if (opened[i].sum < current.sum) { current = opened[i]; } } opened.Remove(current); if (current.world.Match(aGoal)) { // Plan is found! ReconstructPlan(ref aPlan, closed, current); aPlan.isSuccess = true; if (EventPlanUpdated != null) { EventPlanUpdated(aPlan); } return; } closed.Add(current); // Get neighbors. List <AntAIAction> neighbors = GetPossibleTransitions(current.world); AntAICondition neighbor; int openedIndex = -1; int closedIndex = -1; int cost = -1; for (int i = 0, n = neighbors.Count; i < n; i++) { cost = current.cost + neighbors[i].cost; neighbor = current.world.Clone(); neighbor.Act(neighbors[i].post); openedIndex = FindEqual(opened, neighbor); closedIndex = FindEqual(closed, neighbor); if (openedIndex > -1 && cost < opened[openedIndex].cost) { opened.RemoveAt(openedIndex); openedIndex = -1; } if (closedIndex > -1 && cost < closed[closedIndex].cost) { closed.RemoveAt(closedIndex); closedIndex = -1; } if (openedIndex == -1 && closedIndex == -1) { opened.Add(new AntAINode { world = neighbor, cost = cost, heuristic = neighbor.Heuristic(aGoal), sum = cost + neighbor.Heuristic(aGoal), action = neighbors[i].name, parent = current.world }); } } } // Failed plan. ReconstructPlan(ref aPlan, closed, current); aPlan.isSuccess = false; if (EventPlanUpdated != null) { EventPlanUpdated(aPlan); } }