//Utilizes BFS search algorithm to find all locations in the world which are reachable with the current item set //In this algorithm, we want to check for items which have been removed from I but are still contained within R, so an initial search is done to collect items, //then repeated iteratively until no new items are found, at which point the final reachability graph is returned. public WorldGraph GetReachableLocationsAssumed(WorldGraph world, List <Item> owneditems) { WorldGraph copy = world.Copy(); //Used so items may be removed from world at will List <Item> newitems = ItemSearch(copy, owneditems); //Find items within R List <Item> combined = owneditems.ToList(); //Copy list while (newitems.Count > 0) { combined.AddRange(newitems); //Add items to currently used items newitems = ItemSearch(copy, combined); //Find items within R } return(GetReachableLocations(world, combined)); //Use that combined list to find final search result }
//Calculate info about human-like playthrough and then return the score public InterestingnessOutput CalcDistributionInterestingness(WorldGraph world) { PlaythroughInfo info = new PlaythroughInfo(); try { info = searcher.PlaythroughSearch(world.Copy()); } catch { throw new Exception(); //Something went wrong, have calling code retry } BiasOutput biasinfo = CalcDistributionBias(world); return(ScorePlaythrough(world, info, biasinfo)); }
//Experiment space static void Main(string[] args) { Fill filler = new Fill(); Search searcher = new Search(); Statistics stats = new Statistics(); ////Uncomment to test different complexity measures and generate many worlds with different parameters. //double[] testaverages = new double[5]; //for (int regioncount = 10; regioncount <= 50; regioncount += 5) //{ // for (int itemcount = 5; itemcount <= Math.Min(regioncount, 30); itemcount += 5) // { // List<TestComplexityOutput> complexity = AverageComplexity(regioncount, itemcount); // Console.WriteLine("Regions: " + regioncount + ", Items: " + itemcount); // Console.WriteLine("Sum: " + complexity.Average(x => x.sum)); // Console.WriteLine("Avg: " + complexity.Average(x => x.average)); // Console.WriteLine("Max: " + complexity.Average(x => x.max)); // Console.WriteLine("SOS: " + complexity.Average(x => x.sumofsquares)); // Console.WriteLine("Avg50: " + complexity.Average(x => x.top50)); // Console.WriteLine("Avg75: " + complexity.Average(x => x.top75)); // Console.Write(Environment.NewLine); // } //} //Loop through each algorithm set to be used and each world in the list, performing specified algorithm on specified world and recording information about the result. string[] algos = { "Random", "Forward", "Assumed" }; foreach (string worldname in testworlds) { DateTime expstart = DateTime.Now; string jsontext = File.ReadAllText("../../../WorldGraphs/" + worldname + ".json"); WorldGraph world = JsonConvert.DeserializeObject <WorldGraph>(jsontext); //Loop to perform fill algorithms for (int i = 0; i < 3; i++) //0 = Random, 1 = Forward, 2 = Assumed { if (dotests[i]) { int savecounter = 0; int countofexp = db.Results.Count(x => x.Algorithm == algos[i] && x.World == worldname); while (countofexp < trials) //Go until there are trial number of records in db { InterestingnessOutput intstat = new InterestingnessOutput(); double difference = -1; while (true) //If something goes wrong in playthrough search, may need to retry { WorldGraph input = world.Copy(); //Copy so that world is not passed by reference and overwritten List <Item> majoritempool = input.Items.Where(x => x.Importance == 2).ToList(); List <Item> minoritempool = input.Items.Where(x => x.Importance < 2).ToList(); WorldGraph randomizedgraph = new WorldGraph(); DateTime start = DateTime.Now; //Start timing right before algorithm //Decide which algo to use based on i switch (i) { case 0: randomizedgraph = filler.RandomFill(input, majoritempool); break; case 1: randomizedgraph = filler.ForwardFill(input, majoritempool); break; case 2: randomizedgraph = filler.AssumedFill(input, majoritempool); break; } randomizedgraph = filler.RandomFill(randomizedgraph, minoritempool); //Use random for minor items always since they don't matter //Calculate metrics DateTime end = DateTime.Now; difference = (end - start).TotalMilliseconds; try { intstat = stats.CalcDistributionInterestingness(randomizedgraph); break; //Was successful, continue } catch { } //Something went wrong, retry fill from scratch ////Uncomment to print the spheres of the result. //SphereSearchInfo output = searcher.SphereSearch(randomizedgraph); //Print_Spheres(output); } //Store result in database Result result = new Result(); result.Algorithm = algos[i]; result.World = worldname; result.Completable = intstat.completable; result.ExecutionTime = difference; result.Bias = intstat.bias.biasvalue; result.BiasDirection = intstat.bias.direction; result.Interestingness = intstat.interestingness; result.Fun = intstat.fun; result.Challenge = intstat.challenge; result.Satisfyingness = intstat.satisfyingness; result.Boredom = intstat.boredom; db.Entry(result).State = EntityState.Added; savecounter++; if (savecounter >= 1000) //Save every 1000 results processed { db.SaveChanges(); savecounter = 0; } countofexp++; } db.SaveChanges(); //Save changes when combo of algo and world is done } } DateTime expend = DateTime.Now; double expdifference = (expend - expstart).TotalMinutes; Console.WriteLine("Time to perform " + trials + " iterations for world " + worldname + ": " + expdifference + " minutes"); //Print how long this world took to do } Console.ReadLine(); }
//Experiment space static void Main(string[] args) { Fill filler = new Fill(); Search searcher = new Search(); Statistics stats = new Statistics(); //string testjsontext = File.ReadAllText("../../../WorldGraphs/World3.json"); //WorldGraph testworld = JsonConvert.DeserializeObject<WorldGraph>(testjsontext); //double[] testaverages = new double[5]; //for (int regioncount = 10; regioncount <= 50; regioncount += 5) //{ // for (int itemcount = 5; itemcount <= Math.Min(regioncount, 30); itemcount += 5) // { // List<TestComplexityOutput> complexity = AverageComplexity(regioncount, itemcount); // Console.WriteLine("Regions: " + regioncount + ", Items: " + itemcount); // Console.WriteLine("Sum: " + complexity.Average(x => x.sum)); // Console.WriteLine("Avg: " + complexity.Average(x => x.average)); // Console.WriteLine("Max: " + complexity.Average(x => x.max)); // Console.WriteLine("SOS: " + complexity.Average(x => x.sumofsquares)); // Console.WriteLine("Avg50: " + complexity.Average(x => x.top50)); // Console.WriteLine("Avg75: " + complexity.Average(x => x.top75)); // Console.Write(Environment.NewLine); // } //} //string generatedjson = GenerateWorld(50, 30); //string jsontest = File.ReadAllText("../../../WorldGraphs/World5.json"); //WorldGraph testworld = JsonConvert.DeserializeObject<WorldGraph>(jsontest); //int testlocationcount = testworld.GetLocationCount(); //Search testsearcher = new Search(); //testsearcher.PathsToRegion(world, world.Regions.First(x => x.Name == "Waterfall")); //Parser testparse = new Parser(); //string result = testparse.Simplify("(Sword and Bow and Bow) or Has(Key,2)"); //Should be simplified to something like (Sword and Bow) or Has(Key,2) //string result2 = testparse.Simplify("Sword or Sword and Bow"); //Should be simplified to Sword ////majoritempool.RemoveAt(8); ////majoritempool.RemoveAt(0); //bool result = testparse.RequirementsMet("(Sword and Bow) or Has(Key,2)", majoritempool); //string testjsontext = File.ReadAllText("../../../WorldGraphs/TestWorldOriginal.json"); //WorldGraph testworld = JsonConvert.DeserializeObject<WorldGraph>(testjsontext); //SphereSearchInfo testoutput = searcher.SphereSearch(testworld); //Print_Spheres(testoutput); string[] algos = { "Random", "Forward", "Assumed" }; foreach (string worldname in testworlds) { DateTime expstart = DateTime.Now; string jsontext = File.ReadAllText("../../../WorldGraphs/" + worldname + ".json"); WorldGraph world = JsonConvert.DeserializeObject <WorldGraph>(jsontext); int l = world.GetLocationCount(); //Loop to perform fill for (int i = 0; i < 3; i++) //0 = Random, 1 = Forward, 2 = assumed { if (dotests[i]) { //List<InterestingnessOutput> intstats = new List<InterestingnessOutput>(); //double totaltime = 0; int savecounter = 0; int countofexp = db.Results.Count(x => x.Algorithm == algos[i] && x.World == worldname); //int countofexp = 0; while (countofexp < trials) //Go until there are trial number of records in db { InterestingnessOutput intstat = new InterestingnessOutput(); double difference = -1; while (true) //If something goes wrong in playthrough search, may need to retry { WorldGraph input = world.Copy(); //Copy so that world is not passed by reference and overwritten List <Item> majoritempool = input.Items.Where(x => x.Importance == 2).ToList(); List <Item> minoritempool = input.Items.Where(x => x.Importance < 2).ToList(); WorldGraph randomizedgraph = new WorldGraph(); DateTime start = DateTime.Now; //Start timing right before algorithm //Decide which algo to use based on i switch (i) { case 0: randomizedgraph = filler.RandomFill(input, majoritempool); break; case 1: randomizedgraph = filler.ForwardFill(input, majoritempool); break; case 2: randomizedgraph = filler.AssumedFill(input, majoritempool); break; } randomizedgraph = filler.RandomFill(randomizedgraph, minoritempool); //Use random for minor items always since they don't matter //Calculate metrics DateTime end = DateTime.Now; difference = (end - start).TotalMilliseconds; //totaltime += difference; //string randomizedjson = JsonConvert.SerializeObject(randomizedgraph); //SphereSearchInfo output = searcher.SphereSearch(randomizedgraph); //Print_Spheres(output); try { intstat = stats.CalcDistributionInterestingness(randomizedgraph); break; //Was successful, continue } catch { } //Something went wrong, retry fill from scratch } //intstats.Add(intstat); //Store result in database Result result = new Result(); result.Algorithm = algos[i]; result.World = worldname; result.Completable = intstat.completable; result.ExecutionTime = difference; result.Bias = intstat.bias.biasvalue; result.BiasDirection = intstat.bias.direction; result.Interestingness = intstat.interestingness; result.Fun = intstat.fun; result.Challenge = intstat.challenge; result.Satisfyingness = intstat.satisfyingness; result.Boredom = intstat.boredom; db.Entry(result).State = EntityState.Added; savecounter++; if (savecounter >= 1000) //Save every 1000 results processed { db.SaveChanges(); savecounter = 0; } countofexp++; } //double avgint = intstats.Where(x => x.completable).Average(x => x.interestingness); //Console.WriteLine("Average interestingness for " + algos[i] + " Fill in world " + worldname + ": " + avgint); //double avgbias = intstats.Where(x => x.completable).Average(x => x.bias.biasvalue); //Console.WriteLine("Average bias for " + algos[i] + " Fill in world " + worldname + ": " + avgbias); //double avgfun = intstats.Where(x => x.completable).Average(x => x.fun); //Console.WriteLine("Average fun for " + algos[i] + " Fill in world " + worldname + ": " + avgfun); //double avgchal = intstats.Where(x => x.completable).Average(x => x.challenge); //Console.WriteLine("Average challenge for " + algos[i] + " Fill in world " + worldname + ": " + avgchal); //double avgsat = intstats.Where(x => x.completable).Average(x => x.satisfyingness); //Console.WriteLine("Average satisfyingness for " + algos[i] + " Fill in world " + worldname + ": " + avgsat); //double avgbore = intstats.Where(x => x.completable).Average(x => x.boredom); //Console.WriteLine("Average boredom for " + algos[i] + " Fill in world " + worldname + ": " + avgbore); //double avgtime = totaltime / trials; //Console.WriteLine("Average time to generate for " + algos[i] + " Fill in world " + worldname + ": " + avgtime + "ms"); db.SaveChanges(); //Save changes when combo of algo and world is done } //Console.Write(Environment.NewLine); } //Console.Write(Environment.NewLine); //Console.Write(Environment.NewLine); DateTime expend = DateTime.Now; double expdifference = (expend - expstart).TotalMinutes; Console.WriteLine("Time to perform " + trials + " iterations for world " + worldname + ": " + expdifference + " minutes"); } Console.ReadLine(); }