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();
}
}
}