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(); }
/// <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(); }
internal static void Reset() { // Prepare lists for new randomization. MaxRando.Clear(); TypeLists.Clear(); LookupTable.Clear(); NameLookup.Clear(); }
/// <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); } }
/// <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); } }
/// <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); } } }