/// <summary> /// Add the item, its previous levels and its prerequisites to the given set and list. /// </summary> /// <param name="list">The list.</param> /// <param name="set">The set.</param> /// <param name="item">The item.</param> /// <param name="includeRoots">if set to <c>true</c> [include roots].</param> internal static void FillDependencies(this IList <StaticSkillLevel> list, SkillLevelSet <StaticSkillLevel> set, StaticSkillLevel item, bool includeRoots) { StaticSkill skill = item.Skill; // Add first level and prerequisites if (!set.Contains(skill, 1)) { // Prerequisites foreach (StaticSkillLevel prereq in skill.Prerequisites.Where(prereq => skill != prereq.Skill)) { list.FillDependencies(set, prereq, true); } // Include the first level StaticSkillLevel newItem = new StaticSkillLevel(skill, 1); list.Add(newItem); set.Set(newItem); } // Add greater levels Int64 max = includeRoots ? item.Level : item.Level - 1; for (int i = 2; i <= max; i++) { if (set.Contains(skill, i)) { continue; } StaticSkillLevel newItem = new StaticSkillLevel(skill, i); list.Add(newItem); set.Set(newItem); } }
/// <summary> /// Ensures the prerequisites order is correct. /// </summary> /// <param name="list"></param> private static void FixPrerequisitesOrder(ICollection <PlanEntry> list) { // Gather prerequisites/postrequisites relationships and use them to connect nodes - O(n²) operation Dictionary <PlanEntry, List <PlanEntry> > dependencies = new Dictionary <PlanEntry, List <PlanEntry> >(); foreach (PlanEntry entry in list) { dependencies[entry] = new List <PlanEntry>(list.Where(x => entry.IsDependentOf(x))); } // Insert entries LinkedList <PlanEntry> entriesToAdd = new LinkedList <PlanEntry>(list); SkillLevelSet <PlanEntry> set = new SkillLevelSet <PlanEntry>(); list.Clear(); while (entriesToAdd.Count != 0) { // Gets the first entry which has all its prerequisites satisfied. PlanEntry item = entriesToAdd.First(x => dependencies[x].All(y => set[y.Skill, y.Level] != null)); // Add it to the set and list, and remove it from the entries to add set[item.Skill, item.Level] = item; entriesToAdd.Remove(item); list.Add(item); } }
/// <summary> /// Add the item, its previous levels and its prerequisites to the given set and list. /// </summary> /// <param name="list">The list.</param> /// <param name="set">The set.</param> /// <param name="item">The item.</param> /// <param name="includeRoots">if set to <c>true</c> [include roots].</param> internal static void FillDependencies(this IList<StaticSkillLevel> list, SkillLevelSet<StaticSkillLevel> set, StaticSkillLevel item, bool includeRoots) { StaticSkill skill = item.Skill; // Add first level and prerequisites if (!set.Contains(skill, 1)) { // Prerequisites foreach (StaticSkillLevel prereq in skill.Prerequisites.Where(prereq => skill != prereq.Skill)) { list.FillDependencies(set, prereq, true); } // Include the first level StaticSkillLevel newItem = new StaticSkillLevel(skill, 1); list.Add(newItem); set.Set(newItem); } // Add greater levels Int64 max = includeRoots ? item.Level : item.Level - 1; for (int i = 2; i <= max; i++) { if (set.Contains(skill, i)) continue; StaticSkillLevel newItem = new StaticSkillLevel(skill, i); list.Add(newItem); set.Set(newItem); } }
/// <summary> /// Add the item, its previous levels and its prerequisites to the given set and list. /// </summary> /// <param name="set"></param> /// <param name="list"></param> /// <param name="item"></param> /// <param name="includeRoots"></param> internal static void FillDependencies(SkillLevelSet<StaticSkillLevel> set, List<StaticSkillLevel> list, StaticSkillLevel item, bool includeRoots) { var skill = item.Skill; // Add first level and prerequisites if (!set.Contains(skill, 1)) { // Prerequisites foreach (var prereq in skill.Prerequisites) { // Deal with recursive skills such as Polaris if (skill != prereq.Skill) { FillDependencies(set, list, prereq, true); } } // Include the first level var newItem = new StaticSkillLevel(skill, 1); list.Add(newItem); set.Set(newItem); } // Add greater levels int max = (includeRoots ? item.Level : item.Level - 1); for (int i = 2; i <= max; i++) { if (!set.Contains(skill, i)) { var newItem = new StaticSkillLevel(skill, i); list.Add(newItem); set.Set(newItem); } } }
/// <summary> /// Gets all the dependencies, in a way matching the hierachical order and without redudancies. /// I.e, for eidetic memory II, it will return <c>{ instant recall I, instant recall II, instant recall III, instant recall IV, eidetic memory I, eidetic memory II }</c>. /// </summary> /// <param name="src">The source.</param> /// <param name="includeRoots">When true, the levels in this enumeration are also included.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException">src</exception> public static IEnumerable <StaticSkillLevel> GetAllDependencies(this IEnumerable <StaticSkillLevel> src, bool includeRoots) { src.ThrowIfNull(nameof(src)); SkillLevelSet <StaticSkillLevel> set = new SkillLevelSet <StaticSkillLevel>(); List <StaticSkillLevel> list = new List <StaticSkillLevel>(); // Fill the set and list foreach (StaticSkillLevel item in src) { list.FillDependencies(set, item, includeRoots); } // Return the results return(list); }
/// <summary> /// Gets all the dependencies, in a way matching the hierachical order and without redudancies. /// I.e, for eidetic memory II, it will return <c>{ instant recall I, instant recall II, instant recall III, instant recall IV, eidetic memory I, eidetic memory II }</c>. /// </summary> /// <param name="src">The source.</param> /// <param name="includeRoots">When true, the levels in this enumeration are also included.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException">src</exception> public static IEnumerable<StaticSkillLevel> GetAllDependencies(this IEnumerable<StaticSkillLevel> src, bool includeRoots) { src.ThrowIfNull(nameof(src)); SkillLevelSet<StaticSkillLevel> set = new SkillLevelSet<StaticSkillLevel>(); List<StaticSkillLevel> list = new List<StaticSkillLevel>(); // Fill the set and list foreach (StaticSkillLevel item in src) { list.FillDependencies(set, item, includeRoots); } // Return the results return list; }
/// <summary> /// Gets all the dependencies, in a way matching the hirarchical order and without redudancies. /// I.e, for eidetic memory II, it will return <c>{ instant recall I, instant recall II, instant recall III, instant recall IV, eidetic memory I, eidetic memory II }</c>. /// </summary> /// <param name="includeRoots">When true, the levels in this enumeration are also included.</param> public static IEnumerable <StaticSkillLevel> GetAllDependencies(this IEnumerable <StaticSkillLevel> src, bool includeRoots) { var set = new SkillLevelSet <StaticSkillLevel>(); var list = new List <StaticSkillLevel>(); // Fill the set and list foreach (var item in src) { FillDependencies(set, list, item, includeRoots); } // Return the results foreach (var item in list) { yield return(item); } }
/// <summary> /// Gets all the dependencies, in a way matching the hirarchical order and without redudancies. /// I.e, for eidetic memory II, it will return <c>{ instant recall I, instant recall II, instant recall III, instant recall IV, eidetic memory I, eidetic memory II }</c>. /// </summary> /// <param name="includeRoots">When true, the levels in this enumeration are also included.</param> public static IEnumerable<StaticSkillLevel> GetAllDependencies(this IEnumerable<StaticSkillLevel> src, bool includeRoots) { var set = new SkillLevelSet<StaticSkillLevel>(); var list = new List<StaticSkillLevel>(); // Fill the set and list foreach (var item in src) { FillDependencies(set, list, item, includeRoots); } // Return the results foreach (var item in list) { yield return item; } }
/// <summary> /// Add the item, its previous levels and its prerequisites to the given set and list. /// </summary> /// <param name="set"></param> /// <param name="list"></param> /// <param name="item"></param> /// <param name="includeRoots"></param> internal static void FillDependencies(SkillLevelSet <StaticSkillLevel> set, List <StaticSkillLevel> list, StaticSkillLevel item, bool includeRoots) { var skill = item.Skill; // Add first level and prerequisites if (!set.Contains(skill, 1)) { // Prerequisites foreach (var prereq in skill.Prerequisites) { // Deal with recursive skills such as Polaris if (skill != prereq.Skill) { FillDependencies(set, list, prereq, true); } } // Include the first level var newItem = new StaticSkillLevel(skill, 1); list.Add(newItem); set.Set(newItem); } // Add greater levels int max = (includeRoots ? item.Level : item.Level - 1); for (int i = 2; i <= max; i++) { if (!set.Contains(skill, i)) { var newItem = new StaticSkillLevel(skill, i); list.Add(newItem); set.Set(newItem); } } }
/// <summary> /// Ensures the prerequisites order is correct. /// </summary> /// <param name="list"></param> private static void FixPrerequisitesOrder(ICollection<PlanEntry> list) { // Gather prerequisites/postrequisites relationships and use them to connect nodes - O(n²) operation Dictionary<PlanEntry, List<PlanEntry>> dependencies = new Dictionary<PlanEntry, List<PlanEntry>>(); foreach (PlanEntry entry in list) { dependencies[entry] = new List<PlanEntry>(list.Where(x => entry.IsDependentOf(x))); } // Insert entries LinkedList<PlanEntry> entriesToAdd = new LinkedList<PlanEntry>(list); SkillLevelSet<PlanEntry> set = new SkillLevelSet<PlanEntry>(); list.Clear(); while (entriesToAdd.Count != 0) { // Gets the first entry which has all its prerequisites satisfied. PlanEntry item = entriesToAdd.First(x => dependencies[x].All(y => set[y.Skill, y.Level] != null)); // Add it to the set and list, and remove it from the entries to add set[item.Skill, item.Level] = item; entriesToAdd.Remove(item); list.Add(item); } }