using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SpriteCompiler.AI { public class IterativeDeepeningAStarSearch : ISearch where T : IHeuristicSearchNode where C : ICost, new() { private static readonly C Cost = new C(); protected readonly ISearchStrategy search; protected readonly C limit; public IterativeDeepeningAStarSearch(ISearchStrategy search, C limit) { this.search = search; this.limit = limit; } public IEnumerable Search(ISearchProblem problem, S initialState) { C bound = Cost.Zero(); while (bound.CompareTo(limit) < 0) { var limiter = new CostNodeLimiter(bound, Cost.Maximum()); var dls = new DepthLimitedSearch(search, limiter); var result = dls.Search(problem, initialState); // If there was no cutoff, return the solution (or lack thereof) if (!dls.IsCutoff(result)) { return result; } // If the cost did not change, throw exception if (bound.Equals(limiter.NextCost)) { throw new ApplicationException("IDA*: Bound did not increase after depth-limited search"); } // Otherwise, increase the cutoff to the next value bound = limiter.NextCost; } // An empty list signals failure return Enumerable.Empty(); } } }