namespace SpriteCompiler.AI { using System.Collections.Generic; using System.Linq; /// /// Depth-first search with a cutoff /// public class DepthLimitedSearch : DepthFirstSearch where T : ISearchNode where C : ICost, new() { protected readonly INodeLimiter limit; public DepthLimitedSearch(ISearchStrategy strategy, INodeLimiter limit) : base(strategy) { this.limit = limit; } public override IEnumerable Search(ISearchProblem problem, S initialState) { // Save the old node expander var oldExpander = strategy.Expander; // Wrap the expander with a depth-limied expanded in order to // terminate the search var expander = new DepthLimitedNodeExpander(oldExpander, limit); strategy.Expander = expander; // Run the search var solution = base.Search(problem, initialState); // Restore the old expander strategy.Expander = oldExpander; // Check to see we failed and if the reason for failing was not reaching the cutoff depth. if (!solution.Any() && expander.CutoffOccured) { return null; } return solution; } public bool IsCutoff(IEnumerable result) { return result == null; } } }