示例#1
0
        /*
         * 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);
        }
示例#2
0
        //Calculates the bias for a given permutation of items in the world graph
        public BiasOutput CalcDistributionBias(WorldGraph world)
        {
            //Get total counts for majors and items so a percent can be calculated
            int totalmajorcount    = world.Items.Where(x => x.Importance >= 2).Count();
            int totallocationcount = world.GetLocationCount();
            //Find spheres in randomized world
            Search            searcher = new Search();
            List <WorldGraph> spheres  = searcher.SphereSearch(world).Spheres;

            //Initialize variables to use in the loop
            double[] spherebias           = new double[spheres.Count];
            int      rollingmajorcount    = 0;
            int      rollinglocationcount = 0;

            for (int i = 0; i < spheres.Count; i++)
            {
                WorldGraph sphere = spheres[i];
                //Check the number of major items in the sphere, not counting those in previous spheres
                int majoritemcount = sphere.CollectMajorItems().Count - rollingmajorcount;
                rollingmajorcount += majoritemcount;
                //Check the number of locations in the sphere, not counting those in previous spheres
                int locationcount = sphere.GetLocationCount() - rollinglocationcount;
                rollinglocationcount += locationcount;
                //Find the percentage of major items and locations in this sphere
                double majorpercent    = majoritemcount / (double)totalmajorcount;
                double locationpercent = locationcount / (double)totallocationcount;
                //Now find the difference between the two percentages
                double difference = majorpercent - locationpercent;
                spherebias[i] = difference;
            }
            //Now that we have a list of biases find the sum of their absolute values to determine absolute bias
            //Also use the positivity of bias before and after the median to determine bias direction
            double overallsum = 0;
            double beforesum  = 0;                          //Sums bias before median so a bias direction can be computed
            double aftersum   = 0;                          //Sums bias after median so a bias direction can be computed
            bool   even       = spherebias.Length % 2 == 0; //Want to check if even so can determine when after the median is
            int    median     = spherebias.Length / 2;      //Use median to determine bias direction

            for (int i = 0; i < spherebias.Length; i++)
            {
                overallsum += Math.Abs(spherebias[i]);
                if (i < median) //Before median, add to that sum
                {
                    beforesum += spherebias[i];
                }
                else if ((i >= median && even) || (i > median && !even)) //After median, add to that sum. If it's even then >= makes sense so every index is checked, if odd then skip middle
                {
                    aftersum = spherebias[i];
                }
            }
            //Package output and return
            BiasOutput output = new BiasOutput();

            output.biasvalue = overallsum / spherebias.Length; //Get average of absolute value to determine overall bias
            output.direction = beforesum < aftersum;           //If bias is more positive before the median, the direction is toward the beginning, otherwise toward end
            return(output);
        }