/* * Sphere Search is done iteratively in “Spheres” and is used to attempt to trace a path * from the beginning to the end of the game. The first sphere s is simply all locations which are * reachable from the beginning of the game. As it searches these locations, it adds key items * found to a temporary set; we do not want those items to affect reachability until the next sphere * iteration so we do not yet add them to I. After all reachable locations have been found, sphere s * is added to the list of spheres S, and all items in the temporary set are added to I. It then * iterates again with a new sphere s. */ public SphereSearchInfo SphereSearch(WorldGraph world) { SphereSearchInfo output = new SphereSearchInfo(); output.Spheres = new List <WorldGraph>(); List <Item> owneditems = new List <Item>(); //Initial sphere s0 includes items reachable from the start of the game WorldGraph s0 = GetReachableLocations(world, owneditems); owneditems = s0.CollectMajorItems(); //Collect all major items reachable from the start of the game output.Spheres.Add(s0); //Add initial sphere to sphere list //sx indicates every sphere after the first. Any major items found in s0 means sx should be bigger. WorldGraph sx = GetReachableLocations(world, owneditems); int temp = owneditems.Where(x => x.Importance >= 2).Count(); //Temp is the count of previously owned major items owneditems = sx.CollectAllItems(); //Used to find new count of major items //If counts are equal then no new major items found, stop searching while (owneditems.Where(x => x.Importance >= 2).Count() > temp) //If new count is not greater than old count, that means all currently reachable locations have been found { output.Spheres.Add(sx); //If new locations found, add to sphere list //Take the same steps taken before the loop: Get new reachable locations, collect new major items, and check to see if new count is larger than old count sx = GetReachableLocations(world, owneditems); temp = owneditems.Where(x => x.Importance >= 2).Count(); //Only want to consider count of major items owneditems = sx.CollectAllItems(); } //At this point, either a dead end has been found or all locations have been discovered //If the goal item is in the list of owned items, means the end has been found and thus the game is completable output.Completable = owneditems.Count(x => x.Name == world.GoalItemName) > 0; return(output); }
//This function outputs text for each sphere in the calculated sphere list //To avoid redundancy, major items will not be printed more than once //Sample output: /* * Sphere 0: * Forest_Chest: Bow * Forest_Quest: Magic * Field_Hidden A: Bombs * Field_Hidden B: Sword * City_Quest: GateKey * * Sphere 1: * Field_Hidden C: GrapplingHook * Lake_Quest: Sling * * Sphere 2: * Valley_Chest: Key * * Sphere 3: * Dungeon_Boss: Goal * * Is Completable: True */ static void Print_Spheres(SphereSearchInfo input) { List <WorldGraph> spheres = input.Spheres; List <Item> MajorItemsFound = new List <Item>(); //Keeps track of already printed items to avoid redundancy int i = 0; foreach (WorldGraph sphere in spheres) //Go through each sphere { Console.WriteLine(Environment.NewLine + "Sphere " + i + ":"); //Print the sphere index i++; List <Item> majors = sphere.CollectAllItems().Where(x => x.Importance >= 2).ToList(); //Only check for major items foreach (Item m in majors) { if (!MajorItemsFound.Contains(m)) //Check if each major item has been printed already; if not print { MajorItemsFound.Add(m); //This loop is used to find the location of the item so that it may be printed as well Location l = new Location(); foreach (Region r in sphere.Regions) { if (r.Locations.Count(x => x.Item == m) > 0) { l = r.Locations.First(x => x.Item == m); } } Console.WriteLine(l.Name + ": " + m.Name); //Print the item location and name } } } Console.WriteLine(Environment.NewLine + "Is Completable: " + input.Completable + Environment.NewLine); //After finishing, print if completable or not }