public void UpdateReachableTransitions(string newThing = null, bool item = false, ProgressionManager _pm = null) { if (_pm != null) { pm = _pm; } if (newThing == null) { newThing = Randomizer.startTransition; } Queue <string> updates = new Queue <string>(); if (!item) { reachableTransitions.Add(newThing); } pm.Add(newThing); updates.Enqueue(newThing); while (updates.Any()) { string next = updates.Dequeue(); if (transitionPlacements.TryGetValue(next, out string next2) && !reachableTransitions.Contains(next2)) { reachableTransitions.Add(next2); pm.Add(next2); updates.Enqueue(next2); } HashSet <string> potentialTransitions = LogicManager.GetTransitionsByProgression(recentProgression); recentProgression = new HashSet <string>(); foreach (string transition in potentialTransitions) { if (!reachableTransitions.Contains(transition) && pm.CanGet(transition)) { reachableTransitions.Add(transition); pm.Add(transition); updates.Enqueue(transition); if (transitionPlacements.TryGetValue(transition, out string transition2)) { reachableTransitions.Add(transition2); pm.Add(transition2); updates.Enqueue(transition2); } } } } }
public void UpdateReachableTransitions(string newThing = "Tutorial_01[right1]", bool item = false, ProgressionManager _pm = null) { if (_pm != null) { pm = _pm; } Queue <string> updates = new Queue <string>(); if (!item) { reachableTransitions.Add(newThing); } pm.Add(newThing); updates.Enqueue(newThing); while (updates.Any()) { string next = updates.Dequeue(); if (transitionPlacements.TryGetValue(next, out string next2) && !reachableTransitions.Contains(next2)) { reachableTransitions.Add(next2); pm.Add(next2); updates.Enqueue(next2); } foreach (string transition in LogicManager.GetTransitionsByProgression(next)) { if (!reachableTransitions.Contains(transition) && pm.CanGet(transition)) { reachableTransitions.Add(transition); pm.Add(transition); updates.Enqueue(transition); if (transitionPlacements.TryGetValue(transition, out string transition2)) { reachableTransitions.Add(transition2); pm.Add(transition2); updates.Enqueue(transition2); } } } } }
private static bool ValidateItemRandomization() { RandomizerMod.Instance.Log("Beginning item placement validation..."); List <string> unfilledLocations; if (im.normalFillShops) { unfilledLocations = im.randomizedLocations.Except(ItemManager.nonShopItems.Keys).Except(ItemManager.shopItems.Keys).ToList(); } else { unfilledLocations = im.randomizedLocations.Except(ItemManager.nonShopItems.Keys).Except(LogicManager.ShopNames).ToList(); } if (unfilledLocations.Any()) { Log("Unable to validate!"); string m = "The following locations were not filled: "; foreach (string l in unfilledLocations) { m += l + ", "; } Log(m); return(false); } HashSet <(string, string)> LIpairs = new HashSet <(string, string)>(ItemManager.nonShopItems.Select(kvp => (kvp.Key, kvp.Value))); foreach (var kvp in ItemManager.shopItems) { LIpairs.UnionWith(kvp.Value.Select(i => (kvp.Key, i))); } var lookup = LIpairs.ToLookup(pair => pair.Item2, pair => pair.Item1).Where(x => x.Count() > 1); if (lookup.Any()) { Log("Unable to validate!"); string m = "The following items were placed multiple times: "; foreach (var x in lookup) { m += x.Key + ", "; } Log(m); string l = "The following locations were filled by these items: "; foreach (var x in lookup) { foreach (string k in x) { l += k + ", "; } } Log(l); return(false); } /* * // Potentially useful debug logs * foreach (string item in ItemManager.GetRandomizedItems()) * { * if (ItemManager.nonShopItems.Any(kvp => kvp.Value == item)) * { * Log($"Placed {item} at {ItemManager.nonShopItems.First(kvp => kvp.Value == item).Key}"); * } * else if (ItemManager.shopItems.Any(kvp => kvp.Value.Contains(item))) * { * Log($"Placed {item} at {ItemManager.shopItems.First(kvp => kvp.Value.Contains(item)).Key}"); * } * else LogError($"Unable to find where {item} was placed."); * } * foreach (string location in ItemManager.GetRandomizedLocations()) * { * if (ItemManager.nonShopItems.TryGetValue(location, out string item)) * { * Log($"Filled {location} with {item}"); * } * else if (ItemManager.shopItems.ContainsKey(location)) * { * Log($"Filled {location}"); * } * else LogError($"{location} was not filled."); * } */ ProgressionManager pm = new ProgressionManager( RandomizerState.Validating ); pm.Add(startProgression); HashSet <string> locations = new HashSet <string>(im.randomizedLocations.Union(vm.progressionLocations)); HashSet <string> transitions = new HashSet <string>(); HashSet <string> items = im.randomizedItems; items.ExceptWith(startItems); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { transitions.UnionWith(LogicManager.TransitionNames()); tm.ResetReachableTransitions(); tm.UpdateReachableTransitions(_pm: pm); } vm.ResetReachableLocations(false, pm); int passes = 0; while (locations.Any() || items.Any() || transitions.Any()) { if (RandomizerMod.Instance.Settings.RandomizeTransitions) { transitions.ExceptWith(tm.reachableTransitions); } foreach (string location in locations.Where(loc => pm.CanGet(loc)).ToList()) { locations.Remove(location); if (vm.progressionLocations.Contains(location)) { vm.UpdateVanillaLocations(location, false, pm); if (RandomizerMod.Instance.Settings.RandomizeTransitions && !LogicManager.ShopNames.Contains(location)) { tm.UpdateReachableTransitions(location, true, pm); } else if (RandomizerMod.Instance.Settings.RandomizeTransitions) { foreach (string i in vm.progressionShopItems[location]) { tm.UpdateReachableTransitions(i, true, pm); } } // It is possible for a shop to be both a vanilla progression location and contain randomized items, if // Charms or Keys are unrandomized if (ItemManager.shopItems.TryGetValue(location, out List <string> shopItems)) { foreach (string newItem in shopItems) { items.Remove(newItem); if (LogicManager.GetItemDef(newItem).progression) { pm.Add(newItem); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { tm.UpdateReachableTransitions(newItem, true, pm); } } } } } else if (ItemManager.nonShopItems.TryGetValue(location, out string item)) { items.Remove(item); if (LogicManager.GetItemDef(item).progression) { pm.Add(item); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { tm.UpdateReachableTransitions(item, true, pm); } } } else if (ItemManager.shopItems.TryGetValue(location, out List <string> shopItems)) { foreach (string newItem in shopItems) { items.Remove(newItem); if (LogicManager.GetItemDef(newItem).progression) { pm.Add(newItem); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { tm.UpdateReachableTransitions(newItem, true, pm); } } } } else { Log("Unable to validate!"); Log($"Location {location} did not correspond to any known placement."); return(false); } } passes++; if (passes > 400) { Log("Unable to validate!"); Log("Progression: " + pm.ListObtainedProgression() + Environment.NewLine + "Grubs: " + pm.obtained[LogicManager.grubIndex] + Environment.NewLine + "Essence: " + pm.obtained[LogicManager.essenceIndex] + Environment.NewLine + "Flames: " + pm.obtained[LogicManager.flameIndex]); string m = string.Empty; foreach (string s in items) { m += s + ", "; } Log("Unable to get items: " + m); m = string.Empty; foreach (string s in locations) { m += s + ", "; } Log("Unable to get locations: " + m); m = string.Empty; foreach (string s in transitions) { m += s + ","; } Log("Unable to get transitions: " + m); LogItemPlacements(pm); return(false); } } //LogItemPlacements(pm); Log("Validation successful."); return(true); }
public void ResetReachableLocations() { reachableLocations = new HashSet <string>( randomizedLocations.Union(vm.progressionLocations).Where(val => pm.CanGet(val)) ); }
private static bool ValidateItemRandomization() { RandomizerMod.Instance.Log("Beginning item placement validation..."); if (im.randomizedLocations.Except(ItemManager.nonShopItems.Keys).Except(ItemManager.shopItems.Keys).Any()) { Log("Unable to validate!"); string m = "The following locations were not filled: "; foreach (string l in im.randomizedLocations.Except(ItemManager.nonShopItems.Keys).Except(ItemManager.shopItems.Keys)) { m += l + ", "; } Log(m); return(false); } ProgressionManager pm = new ProgressionManager( RandomizerState.Validating ); pm.Add(startProgression); HashSet <string> everything = new HashSet <string>(im.randomizedLocations.Union(vm.progressionLocations)); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { everything.UnionWith(LogicManager.TransitionNames()); tm.ResetReachableTransitions(); tm.UpdateReachableTransitions(_pm: pm); } vm.ResetReachableLocations(false, pm); int passes = 0; while (everything.Any()) { if (RandomizerMod.Instance.Settings.RandomizeTransitions) { everything.ExceptWith(tm.reachableTransitions); } foreach (string location in im.randomizedLocations.Union(vm.progressionLocations).Where(loc => everything.Contains(loc) && pm.CanGet(loc))) { everything.Remove(location); if (LogicManager.ShopNames.Contains(location)) { if (ItemManager.shopItems.Keys.Contains(location)) { foreach (string newItem in ItemManager.shopItems[location]) { if (LogicManager.GetItemDef(newItem).progression) { pm.Add(newItem); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { tm.UpdateReachableTransitions(newItem, true, pm); } } } } if (vm.progressionLocations.Contains(location)) { vm.UpdateVanillaLocations(location, false, pm); } } else if (vm.progressionLocations.Contains(location)) { vm.UpdateVanillaLocations(location, false, pm); } else if (LogicManager.GetItemDef(ItemManager.nonShopItems[location]).progression) { pm.Add(ItemManager.nonShopItems[location]); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { tm.UpdateReachableTransitions(ItemManager.nonShopItems[location], true, pm); } } } passes++; if (passes > 400) { Log("Unable to validate!"); Log("Able to get items: " + pm.ListObtainedProgression() + Environment.NewLine + "Grubs: " + pm.obtained[LogicManager.grubIndex] + Environment.NewLine + "Essence: " + pm.obtained[LogicManager.essenceIndex]); string m = string.Empty; foreach (string s in everything) { m += s + ", "; } Log("Unable to get locations: " + m); LogItemPlacements(pm); return(false); } } //LogItemPlacements(pm); Log("Validation successful."); return(true); }
public void UpdateReachableTransitions(string newThing = null, bool item = false, ProgressionManager _pm = null) { if (_pm != null) { pm = _pm; } if (newThing == null) { newThing = Randomizer.startTransition; } Queue <string> updates = new Queue <string>(); if (!item) { reachableTransitions.Add(newThing); } pm.Add(newThing); updates.Enqueue(newThing); while (updates.Any()) { string next = updates.Dequeue(); if (transitionPlacements.TryGetValue(next, out string next2) && !reachableTransitions.Contains(next2)) { reachableTransitions.Add(next2); pm.Add(next2); updates.Enqueue(next2); } HashSet <string> potentialTransitions = LogicManager.GetTransitionsByProgression(recentProgression); // update possible vanilla locations HashSet <string> potentialLocations = LogicManager.GetLocationsByProgression(recentProgression); potentialLocations.IntersectWith(vanillaProgression); if (potentialLocations.Any()) { checkProgression.UnionWith(potentialLocations); vanillaProgression.ExceptWith(checkProgression); } recentProgression = new HashSet <string>(); foreach (string transition in potentialTransitions) { if (!reachableTransitions.Contains(transition) && pm.CanGet(transition)) { reachableTransitions.Add(transition); pm.Add(transition); updates.Enqueue(transition); if (transitionPlacements.TryGetValue(transition, out string transition2)) { reachableTransitions.Add(transition2); pm.Add(transition2); updates.Enqueue(transition2); } } } if (!updates.Any()) // vanilla locations are very unlikely to enter into logic, so we only check them right before the loop ends { List <string> iterate = new List <string>(); foreach (string loc in checkProgression) { if (pm.CanGet(loc)) { pm.Add(loc); iterate.Add(loc); // **Don't**modify**collection**while**iterating** updates.Enqueue(loc); } } checkProgression.ExceptWith(iterate); } } }
private static bool ValidateItemRandomization() { RandomizerMod.Instance.Log("Beginning item placement validation..."); if (im.randomizedLocations.Except(ItemManager.nonShopItems.Keys).Except(ItemManager.shopItems.Keys).Any()) { Log("Unable to validate!"); string m = "The following locations were not filled: "; foreach (string l in im.randomizedLocations.Except(ItemManager.nonShopItems.Keys).Except(ItemManager.shopItems.Keys)) { m += l + ", "; } Log(m); return(false); } /* * // Potentially useful debug logs * foreach (string item in ItemManager.GetRandomizedItems()) * { * if (ItemManager.nonShopItems.Any(kvp => kvp.Value == item)) * { * Log($"Placed {item} at {ItemManager.nonShopItems.First(kvp => kvp.Value == item).Key}"); * } * else if (ItemManager.shopItems.Any(kvp => kvp.Value.Contains(item))) * { * Log($"Placed {item} at {ItemManager.shopItems.First(kvp => kvp.Value.Contains(item)).Key}"); * } * else LogError($"Unable to find where {item} was placed."); * } * foreach (string location in ItemManager.GetRandomizedLocations()) * { * if (ItemManager.nonShopItems.TryGetValue(location, out string item)) * { * Log($"Filled {location} with {item}"); * } * else if (ItemManager.shopItems.ContainsKey(location)) * { * Log($"Filled {location}"); * } * else LogError($"{location} was not filled."); * } */ ProgressionManager pm = new ProgressionManager( RandomizerState.Validating ); pm.Add(startProgression); HashSet <string> locations = new HashSet <string>(im.randomizedLocations.Union(vm.progressionLocations)); HashSet <string> transitions = new HashSet <string>(); HashSet <string> items = ItemManager.GetRandomizedItems(); items.ExceptWith(startItems); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { transitions.UnionWith(LogicManager.TransitionNames()); tm.ResetReachableTransitions(); tm.UpdateReachableTransitions(_pm: pm); } vm.ResetReachableLocations(false, pm); int passes = 0; while (locations.Any() || items.Any() || transitions.Any()) { if (RandomizerMod.Instance.Settings.RandomizeTransitions) { transitions.ExceptWith(tm.reachableTransitions); } foreach (string location in locations.Where(loc => pm.CanGet(loc)).ToList()) { locations.Remove(location); if (vm.progressionLocations.Contains(location)) { vm.UpdateVanillaLocations(location, false, pm); } if (ItemManager.nonShopItems.TryGetValue(location, out string item)) { items.Remove(item); if (LogicManager.GetItemDef(item).progression) { pm.Add(item); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { tm.UpdateReachableTransitions(item, true, pm); } } } else if (ItemManager.shopItems.TryGetValue(location, out List <string> shopItems)) { foreach (string newItem in shopItems) { items.Remove(newItem); if (LogicManager.GetItemDef(newItem).progression) { pm.Add(newItem); if (RandomizerMod.Instance.Settings.RandomizeTransitions) { tm.UpdateReachableTransitions(newItem, true, pm); } } } } else if (!vm.progressionLocations.Contains(location)) { Log("Unable to validate!"); Log($"Location {location} did not correspond to any known placement."); return(false); } } passes++; if (passes > 400) { Log("Unable to validate!"); Log("Progression: " + pm.ListObtainedProgression() + Environment.NewLine + "Grubs: " + pm.obtained[LogicManager.grubIndex] + Environment.NewLine + "Essence: " + pm.obtained[LogicManager.essenceIndex]); string m = string.Empty; foreach (string s in items) { m += s + ", "; } Log("Unable to get items: " + m); m = string.Empty; foreach (string s in locations) { m += s + ", "; } Log("Unable to get locations: " + m); m = string.Empty; foreach (string s in transitions) { m += s + ","; } Log("Unable to get transitions: " + m); LogItemPlacements(pm); return(false); } } //LogItemPlacements(pm); Log("Validation successful."); return(true); }