예제 #1
0
        public void Test()
        {
            var lookupTable = new LookupTable <string, int>(StringComparer.OrdinalIgnoreCase);

            lookupTable.Should().BeEmpty();
            lookupTable["first"].Should().BeEmpty();

            lookupTable.Add("first", value: 2);
            lookupTable.Add("first", value: 3);
            lookupTable.Add("first", value: 4);
            lookupTable.Add("second", value: 5);
            lookupTable.Should().HaveCount(2);
            lookupTable["first"].Should().HaveCount(3);
            lookupTable["first"].Should().BeEquivalentTo(2, 3, 4);

            lookupTable.Remove("first", value: 3);
            lookupTable["first"].Should().HaveCount(2);
            lookupTable["first"].Should().BeEquivalentTo(2, 4);

            lookupTable.Remove("first");
            lookupTable["first"].Should().BeEmpty();
            lookupTable.Should().HaveCount(1);

            var copy = new LookupTable <string, int>(lookupTable, StringComparer.OrdinalIgnoreCase);

            lookupTable.Add("second", value: 6);
            copy["second"].Should().HaveCount(1);

            lookupTable.Clear();
            lookupTable.Should().BeEmpty();
            copy.Should().NotBeEmpty();
        }
예제 #2
0
 /// <summary>
 /// Resets any fields to prepare for a new shuffle.
 /// </summary>
 internal static void Reset()
 {
     // Reset digraph reachability settings.
     Digraph.ResetSettings();
     // Prepare lists for new randomization.
     LookupTable.Clear();
 }
예제 #3
0
 internal static void Reset()
 {
     // Prepare lists for new randomization.
     MaxRando.Clear();
     TypeLists.Clear();
     LookupTable.Clear();
     NameLookup.Clear();
 }
예제 #4
0
        /// <summary>
        /// LookupTable is created from the global BoundModules without shuffling.
        /// </summary>
        private static void CreateLookupTableNoShuffle()
        {
            // Create lookup table for later features.
            LookupTable.Clear();

            foreach (var item in Globals.BoundModules)
            {
                LookupTable.Add(item.Code, item.Code);
            }
        }
예제 #5
0
        /// <summary>
        /// LookupTable is created from the global BoundModules after shuffling included modules.
        /// </summary>
        private static void CreateLookupTableShuffle()
        {
            List <string> excluded = Globals.BoundModules.Where(x => x.Omitted).Select(x => x.Code).ToList();
            List <string> included = Globals.BoundModules.Where(x => !x.Omitted).Select(x => x.Code).ToList();

            // Shuffle the list of included modules.
            List <string> shuffle = new List <string>(included);

            Randomize.FisherYatesShuffle(shuffle);
            LookupTable.Clear();

            for (int i = 0; i < included.Count; i++)
            {
                LookupTable.Add(included[i], shuffle[i]);
            }

            // Include the unmodified list of excluded modules.
            foreach (string name in excluded)
            {
                LookupTable.Add(name, name);
            }
        }
예제 #6
0
        /// <summary>
        /// Populates and shuffles the the modules flagged to be randomized. Returns true if override files should be added.
        /// </summary>
        /// <param name="paths">KPaths object for this game.</param>
        public static void Module_rando(KPaths paths)
        {
            // Reset digraph reachability settings.
            Digraph.ResetSettings();
            LookupTable.Clear();

            // Split the Bound modules into their respective lists.
            bool reachable  = false;
            int  iterations = 0;

            // Only shuffle if there is more than 1 module in the shuffle.
            if (Globals.BoundModules.Count(x => !x.Omitted) > 1)
            {
                if (Properties.Settings.Default.UseRandoRules ||
                    Properties.Settings.Default.VerifyReachability)
                {
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    sw.Start();

                    while (!reachable && iterations < MAX_ITERATIONS)
                    {
                        iterations++;

                        Console.WriteLine($"Iteration {iterations}:");

                        CreateLookupTableShuffle();

                        Digraph.SetRandomizationLookup(LookupTable);

                        if (Properties.Settings.Default.UseRandoRules)
                        {
                            // Skip to the next iteration if the rules are violated.
                            if (AreRulesViolated())
                            {
                                continue;
                            }
                        }

                        if (Properties.Settings.Default.VerifyReachability)
                        {
                            Digraph.CheckReachability();
                            reachable = Digraph.IsGoalReachable();
                        }
                        else
                        {
                            reachable = true;
                        }
                    }

                    if (Properties.Settings.Default.VerifyReachability)
                    {
                        if (reachable)
                        {
                            var message = $"Reachable solution found after {iterations} shuffles. Time elapsed: {sw.Elapsed}";
                            Console.WriteLine(message);
                        }
                        else
                        {
                            // Throw an exception if not reachable.
                            var message = $"No reachable solution found over {iterations} shuffles. Time elapsed: {sw.Elapsed}";
                            Console.WriteLine(message);
                            throw new TimeoutException(message);
                        }
                    }

                    //digraph.WriteReachableToConsole();
                    Console.WriteLine();
                }
                else
                {
                    CreateLookupTableShuffle();
                }
            }
            else
            {
                CreateLookupTableNoShuffle();
            }

            WriteFilesToModulesDirectory(paths);

            // Write additional override files (and unlock galaxy map).
            WriteOverrideFiles(paths);

            // Fix warp coordinates.
            if (Properties.Settings.Default.ModuleExtrasValue.HasFlag(ModuleExtras.FixCoordinates))
            {
                FixWarpCoordinates(paths);
            }

            // Fixed Rakata riddle Man in Mind Prison.
            if (Properties.Settings.Default.ModuleExtrasValue.HasFlag(ModuleExtras.FixMindPrison))
            {
                FixMindPrison(paths);
            }

            // Unlock locked doors or elevators.
            UnlockDoors(paths);

            // Vulkar Spice Lab Transition
            if (Properties.Settings.Default.ModuleExtrasValue.HasFlag(ModuleExtras.VulkarSpiceLZ))
            {
                var vulk_files = paths.FilesInModules.Where(fi => fi.Name.Contains(LookupTable[AREA_TAR_VULK_BASE]));
                foreach (FileInfo fi in vulk_files)
                {
                    // Skip any files that end in "s.rim".
                    if (fi.Name[fi.Name.Length - 5] == 's')
                    {
                        continue;
                    }

                    RIM r_vul = new RIM(fi.FullName);
                    r_vul.File_Table.FirstOrDefault(x => x.Label == LABEL_TAR_VULK_GIT && x.TypeID == (int)ResourceType.GIT).File_Data = Properties.Resources.m10aa;

                    r_vul.WriteToFile(fi.FullName);
                }
            }
        }