示例#1
0
        private static void PlaceOneWayTransitions()
        {
            if (randomizationError)
            {
                return;
            }
            List <string> oneWayEntrances   = LogicManager.TransitionNames().Where(transition => LogicManager.GetTransitionDef(transition).oneWay == 1).ToList();
            List <string> oneWayExits       = LogicManager.TransitionNames().Where(transition => LogicManager.GetTransitionDef(transition).oneWay == 2).ToList();
            List <string> horizontalOneWays = oneWayEntrances.Where(t => !LogicManager.GetTransitionDef(t).doorName.StartsWith("b")).ToList();

            while (horizontalOneWays.Any())
            {
                string horizontalEntrance = horizontalOneWays.First();
                string downExit           = oneWayExits[rand.Next(oneWayExits.Count)];

                tm.PlaceOneWayPair(horizontalEntrance, downExit);
                oneWayEntrances.Remove(horizontalEntrance);
                horizontalOneWays.Remove(horizontalEntrance);
                oneWayExits.Remove(downExit);
            }

            DirectedTransitions directed = new DirectedTransitions(rand);

            directed.Add(oneWayExits);
            while (oneWayEntrances.Any())
            {
                string entrance = oneWayEntrances[rand.Next(oneWayEntrances.Count)];
                string exit     = directed.GetNextTransition(entrance);

                tm.PlaceOneWayPair(entrance, exit);
                oneWayEntrances.Remove(entrance);
                oneWayExits.Remove(exit);
                directed.Remove(exit);
            }
        }
示例#2
0
        private static void PlaceIsolatedTransitions()
        {
            if (randomizationError)
            {
                return;
            }

            List <string>       isolatedTransitions    = tm.unplacedTransitions.Where(transition => LogicManager.GetTransitionDef(transition).isolated).ToList();
            List <string>       nonisolatedTransitions = tm.unplacedTransitions.Where(transition => !LogicManager.GetTransitionDef(transition).isolated).ToList();
            DirectedTransitions directed = new DirectedTransitions(rand);

            isolatedTransitions.Remove(startTransition);
            nonisolatedTransitions.Remove(startTransition);
            directed.Add(nonisolatedTransitions);

            bool connectAreas = RandomizerMod.Instance.Settings.ConnectAreas;

            while (isolatedTransitions.Any())
            {
                string transition1 = isolatedTransitions[rand.Next(isolatedTransitions.Count)];
                string transition2 = directed.GetNextTransition(transition1, favorSameArea: connectAreas);
                if (transition2 is null)
                {
                    Log("Ran out of nonisolated transitions during preplacement!");
                    randomizationError = true;
                    return;
                }
                tm.PlaceStandbyPair(transition1, transition2);
                isolatedTransitions.Remove(transition1);
                directed.Remove(transition2);
            }
        }
        public TransitionManager(Random rnd)
        {
            rand = rnd;
            dt   = new DirectedTransitions(rnd);
            pm   = new ProgressionManager(
                RandomizerState.InProgress
                );

            transitionPlacements = new Dictionary <string, string>();

            List <string> iterate = LogicManager.TransitionNames().ToList();

            unplacedTransitions = new List <string>();
            while (iterate.Any())
            {
                string t = iterate[rand.Next(iterate.Count)];
                unplacedTransitions.Add(t);
                iterate.Remove(t);
            }

            standbyTransitions   = new Dictionary <string, string>();
            reachableTransitions = new HashSet <string>();
            recentProgression    = new HashSet <string>();

            dt.Add(unplacedTransitions);
        }
示例#4
0
        public TransitionManager(Random rnd)
        {
            rand = rnd;
            dt   = new DirectedTransitions(rnd);
            pm   = new ProgressionManager(
                RandomizerState.InProgress
                );
            // start items added to pm in Connect Start to Graph in Randomizer

            transitionPlacements = new Dictionary <string, string>();

            List <string> iterate = LogicManager.TransitionNames().ToList();

            unplacedTransitions = new List <string>();
            while (iterate.Any())
            {
                string t = iterate[rand.Next(iterate.Count)];
                unplacedTransitions.Add(t);
                iterate.Remove(t);
            }

            standbyTransitions   = new Dictionary <string, string>();
            reachableTransitions = new HashSet <string>();
            recentProgression    = new HashSet <string>();
            vanillaProgression   = VanillaManager.GetVanillaProgression();
            checkProgression     = new HashSet <string>();

            dt.Add(unplacedTransitions);
        }
 public string NextTransition(DirectedTransitions _dt = null)
 {
     if (_dt == null)
     {
         _dt = dt;
     }
     return(reachableTransitions.FirstOrDefault(t => _dt.Test(t) && unplacedTransitions.Contains(t)));
 }
示例#6
0
        public void UpdateTransitionStandby(string transition1, string transition2)
        {
            bool ableToRelink1;
            bool ableToRelink2;

            bool T1InStandby = standbyTransitions.TryGetValue(transition1, out string oldTransition2);
            bool T2InStandby = standbyTransitions.TryGetValue(transition2, out string oldTransition1);

            standbyTransitions.Remove(transition1);
            standbyTransitions.Remove(transition2);

            if (T1InStandby && oldTransition1 == transition1)
            {
                return;                                               // this means t1 and t2 were already linked in standby
            }
            if (T1InStandby || T2InStandby)
            {
                DirectedTransitions dt = new DirectedTransitions(rand);
                dt.Add(unplacedTransitions);
                if (T1InStandby && dt.GetNextTransition(oldTransition2) is string newTransition1)
                {
                    standbyTransitions[oldTransition2] = newTransition1;
                    standbyTransitions[newTransition1] = oldTransition2;
                    unplacedTransitions.Remove(newTransition1);
                    dt.Remove(newTransition1);
                    ableToRelink1 = true;
                }
                else
                {
                    ableToRelink1 = !T1InStandby;
                }

                if (T2InStandby && dt.GetNextTransition(oldTransition1) is string newTransition2)
                {
                    standbyTransitions[oldTransition1] = newTransition2;
                    standbyTransitions[newTransition2] = oldTransition1;
                    unplacedTransitions.Remove(newTransition2);
                    ableToRelink2 = true;
                }
                else
                {
                    ableToRelink2 = !T2InStandby;
                }

                if (T1InStandby && T2InStandby && !ableToRelink1 && !ableToRelink2)
                {
                    standbyTransitions[oldTransition1] = oldTransition2;
                    standbyTransitions[oldTransition2] = oldTransition1;
                    return;
                }

                if (!ableToRelink1 || !ableToRelink2)
                {
                    LogError("Error encountered in updating standby transitions. Unable to relink after removing standby transition.");
                    Randomizer.randomizationError = true;
                }
            }
        }
        public string ForceTransition(DirectedTransitions _dt = null)
        {
            if (_dt == null)
            {
                _dt = dt;
            }

            List <string> candidateTransitions = new List <string>();

            candidateTransitions.AddRange(unplacedTransitions);
            candidateTransitions.AddRange(standbyTransitions.Keys);
            candidateTransitions = candidateTransitions.Except(reachableTransitions).Where(transition => _dt.Test(transition)).ToList();
            bool Test(string transition)
            {
                HashSet <string> tempProgression = FakeUpdateReachableTransitions(transition);

                tempProgression.Remove(transition);
                tempProgression.IntersectWith(candidateTransitions);
                return(tempProgression.Any());
            }

            return(candidateTransitions.FirstOrDefault(t => Test(t)));
        }
        public void UpdateTransitionStandby(string transition1, string transition2)
        {
            if (standbyTransitions.TryGetValue(transition1, out string oldTransition2))
            {
                DirectedTransitions dt = new DirectedTransitions(rand);
                dt.Add(unplacedTransitions);
                standbyTransitions.Remove(transition1);
                string newTransition1 = dt.GetNextTransition(oldTransition2);
                standbyTransitions[oldTransition2] = newTransition1;
                standbyTransitions.Add(newTransition1, oldTransition2);
                unplacedTransitions.Remove(newTransition1);
            }

            if (standbyTransitions.TryGetValue(transition2, out string oldTransition1))
            {
                DirectedTransitions dt = new DirectedTransitions(rand);
                dt.Add(unplacedTransitions);
                standbyTransitions.Remove(transition2);
                string newTransition2 = dt.GetNextTransition(oldTransition1);
                standbyTransitions[oldTransition1] = newTransition2;
                standbyTransitions.Add(newTransition2, oldTransition1);
                unplacedTransitions.Remove(newTransition2);
            }
        }
示例#9
0
        private static void ConnectStartToGraph()
        {
            if (randomizationError)
            {
                return;
            }
            Log("Attaching start to graph...");

            tm.pm = new ProgressionManager(
                RandomizerState.InProgress
                );
            im.ResetReachableLocations();
            vm.ResetReachableLocations();
            tm.ResetReachableTransitions();

            tm.pm.Add(startProgression);

            {   // keeping local variables out of the way
                DirectedTransitions d = new DirectedTransitions(rand);
                d.Add(startTransition);
                string transition2 = tm.ForceTransition(d);
                if (transition2 is null) // this should happen extremely rarely, but it has to be handled
                {
                    Log("No way out of start?!?");
                    Log("Was the start transition already placed? " + TransitionManager.transitionPlacements.ContainsKey(startTransition));
                    randomizationError = true;
                    return;
                }
                tm.PlaceTransitionPair(startTransition, transition2);
            }

            while (true)
            {
                if (!RandomizerMod.Instance.Settings.RandomizeSkills)
                {
                    // it is essentially impossible to generate a transition randomizer without one of these accessible
                    if (tm.pm.CanGet("Mantis_Claw") || tm.pm.CanGet("Mothwing_Cloak") || tm.pm.CanGet("Shade_Cloak"))
                    {
                        return;
                    }
                }
                else if (im.FindNextLocation(tm.pm) != null)
                {
                    return;
                }

                tm.UnloadReachableStandby();
                List <string> placeableTransitions = tm.reachableTransitions.Intersect(tm.unplacedTransitions.Union(tm.standbyTransitions.Keys)).ToList();
                if (!placeableTransitions.Any())
                {
                    Log("Could not connect start to map--ran out of placeable transitions.");
                    foreach (string t in tm.reachableTransitions)
                    {
                        Log(t);
                    }
                    randomizationError = true;
                    return;
                }

                DirectedTransitions directed = new DirectedTransitions(rand);
                directed.Add(placeableTransitions);

                if (tm.ForceTransition(directed) is string transition1)
                {
                    string transition2 = directed.GetNextTransition(transition1);
                    tm.PlaceTransitionPair(transition1, transition2);
                }
                else
                {
                    Log("Could not connect start to map--ran out of progression transitions.");
                    randomizationError = true;
                    return;
                }
            }
        }
        public static void BuildSpanningTree(Dictionary <string, List <string> > sortedTransitions, string first = null)
        {
            List <string> remaining = sortedTransitions.Keys.ToList();

            while (first == null)
            {
                first = remaining[rand.Next(remaining.Count)];
                if (!sortedTransitions[first].Any(t => !LogicManager.GetTransitionDef(t).isolated))
                {
                    first = null;
                }
            }
            remaining.Remove(first);
            List <DirectedTransitions> directed = new List <DirectedTransitions>();

            directed.Add(new DirectedTransitions(rand));
            directed[0].Add(sortedTransitions[first].Where(t => !LogicManager.GetTransitionDef(t).isolated).ToList());
            int failsafe = 0;

            while (remaining.Any())
            {
                bool placed = false;
                failsafe++;
                if (failsafe > 500 || !directed[0].AnyCompatible())
                {
                    Log("Triggered failsafe on round " + failsafe + " in BuildSpanningTree, where first transition set was: " + first + " with count: " + sortedTransitions[first].Count);
                    randomizationError = true;
                    return;
                }

                string nextRoom = remaining[rand.Next(remaining.Count)];

                foreach (DirectedTransitions dt in directed)
                {
                    List <string> nextAreaTransitions = sortedTransitions[nextRoom].Where(transition => !LogicManager.GetTransitionDef(transition).deadEnd&& dt.Test(transition)).ToList();
                    List <string> newTransitions      = sortedTransitions[nextRoom].Where(transition => !LogicManager.GetTransitionDef(transition).isolated).ToList();

                    if (!nextAreaTransitions.Any())
                    {
                        continue;
                    }

                    string transitionTarget = nextAreaTransitions[rand.Next(nextAreaTransitions.Count)];
                    string transitionSource = dt.GetNextTransition(transitionTarget);

                    tm.PlaceTransitionPair(transitionSource, transitionTarget);
                    remaining.Remove(nextRoom);

                    dt.Add(newTransitions);
                    dt.Remove(transitionTarget, transitionSource);
                    placed = true;
                    break;
                }
                if (placed)
                {
                    continue;
                }
                else
                {
                    DirectedTransitions dt = new DirectedTransitions(rand);
                    dt.Add(sortedTransitions[nextRoom].Where(transition => !LogicManager.GetTransitionDef(transition).isolated).ToList());
                    directed.Add(dt);
                    remaining.Remove(nextRoom);
                }
            }
            //Log("Completed first pass of BuildSpanningTree with " + directed.Count + " connected component(s).");
            for (int i = 0; i < directed.Count; i++)
            {
                DirectedTransitions dt  = directed[i];
                DirectedTransitions dt1 = null;
                string transition1      = null;
                string transition2      = null;

                foreach (var dt2 in directed)
                {
                    if (dt == dt2)
                    {
                        continue;
                    }

                    if (dt.left && dt2.right)
                    {
                        transition1 = dt.leftTransitions[rand.Next(dt.leftTransitions.Count)];
                        transition2 = dt2.rightTransitions[rand.Next(dt2.rightTransitions.Count)];
                        dt1         = dt2;
                        break;
                    }
                    else if (dt.right && dt2.left)
                    {
                        transition1 = dt.rightTransitions[rand.Next(dt.rightTransitions.Count)];
                        transition2 = dt2.leftTransitions[rand.Next(dt2.leftTransitions.Count)];
                        dt1         = dt2;
                        break;
                    }
                    else if (dt.top && dt2.bot)
                    {
                        transition1 = dt.topTransitions[rand.Next(dt.topTransitions.Count)];
                        transition2 = dt2.botTransitions[rand.Next(dt2.botTransitions.Count)];
                        dt1         = dt2;
                        break;
                    }
                    else if (dt.bot && dt2.top)
                    {
                        transition1 = dt.botTransitions[rand.Next(dt.botTransitions.Count)];
                        transition2 = dt2.topTransitions[rand.Next(dt2.topTransitions.Count)];
                        dt1         = dt2;
                        break;
                    }
                }
                if (!string.IsNullOrEmpty(transition1))
                {
                    tm.PlaceTransitionPair(transition1, transition2);
                    dt1.Add(dt.AllTransitions);
                    dt1.Remove(transition1, transition2);
                    directed.Remove(dt);
                    i = -1;
                }
            }
            //Log("Exited BuildSpanningTree with " + directed.Count + " connected component(s).");
        }