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);
                        }
                    }
                }
            }
        }
Example #3
0
        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);
        }
Example #6
0
        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);
                }
            }
        }
Example #7
0
        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);
        }