예제 #1
0
        /// <summary>
        /// Evaluates the garden for symmetry by checking for relative symmetry on 4 axis
        /// N-S, E-W, NE-SW, and NW-SE.
        ///
        /// </summary>
        /// <returns>A double from 0 (unique) to 1 (full symmetry) describing the symmetry</returns>
        public double symmetric(int jigger, double weight)
        {
            //Gravel matches aren't that big of a deal.
            //More interested in Rocks
            //We are going to take the Hamming distance of the strings by "Jiggering" them by some integer (call it jigger) in each direction
            //Unlike Hamming we are only going to take the count of the Rs that do match up to the other neighborhood.
            //Then we will divide this number by the min number of Rs in each comparsion section times J^2 (so the number of Rs in N for E-W and NE in NW-SE)
            //If perfectly symmetrical, this number will be 1.
            List <double> products = new List <double>();

            Neighborhood[] halves = allHalves();
            Neighborhood   north = halves[NORTH], northeast = halves[NORTHEAST], east = halves[EAST],
                           southeast = halves[SOUTHEAST], south = halves[SOUTH],
                           southwest = halves[SOUTHWEST], west = halves[WEST],
                           northwest = halves[NORTHWEST];

            //do all comparisons
            products.Add(symmetric(north, south, jigger, false, false));
            products.Add(symmetric(east, west, jigger, false, true));
            products.Add(symmetric(northwest, southeast, jigger, true, false));
            products.Add(symmetric(northeast, southwest, jigger, true, false));
            double averageProduct = average(products);

            return(averageProduct * weight);
        }
예제 #2
0
        public Neighborhood[] allHalves()
        {
            Point        tempPoint;
            Atom         tempAtom;
            double       slope = length / (width + 0.0);
            Neighborhood north, south, east, west, northeast, southwest, northwest, southeast;

            north     = getNeighborhood(new Point(0, length / 2), width, length - (length / 2));
            south     = getNeighborhood(new Point(0, 0), width, (length / 2));
            east      = getNeighborhood(new Point(0, 0), (width / 2), length);
            west      = getNeighborhood(new Point((width / 2), 0), width - (width / 2), length);
            northeast = new Neighborhood();
            southeast = new Neighborhood();
            northwest = new Neighborhood();
            southwest = new Neighborhood();

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < length; y++)
                {
                    tempPoint = new Point(x, y);
                    tempAtom  = atomAt(tempPoint);
                    if (y > slope * x)
                    {
                        //in NW
                        northwest.addAtom(tempAtom);
                    }
                    else
                    {
                        //in SE
                        southeast.addAtom(tempAtom);
                    }
                    if (y > (-1 * slope) * x + length)
                    {
                        //in NE
                        northeast.addAtom(tempAtom);
                    }
                    else
                    {
                        //in SW
                        southwest.addAtom(tempAtom);
                    }
                }
            }
            return(new Neighborhood[] { north, northeast, east, southeast, south, southwest, west, northwest });
        }
예제 #3
0
        /// <summary>
        /// Takes two preferably disjoint Neighborhoods and measures if one has
        /// a dominant amount of Rocks over the other.
        /// This score should be very weak in the case where there are few rocks as it may not
        /// be feasible to cover all distinct halves. This can be controlled with the
        /// "balanceOfNeighborhoods" property.
        /// </summary>
        /// <param name="upper">One neighborhood to measure.</param>
        /// <param name="lower">The other neighborhood to measure.</param>
        /// <returns></returns>
        private static double balanceOfNeighborhoods(Neighborhood upper, Neighborhood lower)
        {
            int    nRocksUpper = upper.numberOfRocks();
            int    nRocksLower = upper.numberOfRocks();
            double resultRatio;

            if (nRocksUpper >= nRocksLower)
            {
                //adding 1.0 to cast to double and prevent division by zero
                resultRatio = (nRocksLower + 1.0) / (nRocksUpper + 1.0);
            }
            else
            {
                resultRatio = (nRocksUpper + 1.0) / (nRocksLower + 1.0);
            }
            return(resultRatio);
        }
예제 #4
0
        /// <summary>
        /// Counts the number of hits and return how many hits occured against how many
        /// were possible.
        /// </summary>
        /// <param name="atomCompare"></param>
        /// <param name="neighboorhoodCompare"></param>
        /// <param name="jigger"></param>
        /// <param name="atomLocation"></param>
        /// <returns></returns>
        private static double singleSymmetry(Atom atomCompare, Neighborhood neighboorhoodCompare,
                                             int jigger, Point atomLocation)
        {
            string atomCompareString = atomCompare.ToString(), compareTo;

            //temp. Only care about rocks
            if (!atomCompareString.Equals(Rock.rockString))
            {
                return(0);
            }
            Point comparePoint;
            int   countHits = 0, countAll = 0;

            for (int xDelta = -1 * jigger; xDelta <= jigger; xDelta++)
            {
                for (int yDelta = -1 * jigger; yDelta <= jigger; yDelta++)
                {
                    comparePoint = new Point(atomLocation.X + xDelta, atomLocation.Y + yDelta);
                    compareTo    = neighboorhoodCompare.getAtom(comparePoint).ToString();
                    try
                    {
                        if (atomCompareString.Equals(compareTo))
                        {
                            countHits++;
                        }
                        countAll++;
                    }
                    catch
                    {
                        //not on the grid. This is instance is not a problem. Jiggering can throw
                        //us outside of the grid.
                    }
                }
            }
            //prevent division by zero errors
            return(countAll != 0? countHits / (countAll + 0.0): 0);
        }
예제 #5
0
        /// <summary>
        /// Go through every point in the upper neighborhood and compare it to the lower.
        /// Need to implement how to refernce points (Offsetting)
        /// </summary>
        /// <param name="upper"></param>
        /// <param name="lower"></param>
        /// <param name="jigger"></param>
        /// <returns></returns>
        private double symmetric(Neighborhood upper, Neighborhood lower, int jigger, bool flipCoordinates, bool flipOnWidth)
        {
            int totalRocks;
            int upperRocks = upper.numberOfRocks();
            int lowerRocks = lower.numberOfRocks();

            totalRocks = upperRocks < lowerRocks ? upperRocks : lowerRocks;
            List <double> products = new List <double>();
            Atom          tempAtom;
            Point         tempLocation;

            foreach (Atom a in upper.getAtoms())
            {
                if (!a.getResident().isGravel)
                {
                    if (flipCoordinates)
                    {
                        tempLocation = invert(a.getLocation());
                    }
                    else
                    {
                        if (flipOnWidth)
                        {
                            tempLocation = new Point(a.getLocation().X, length - 1 - a.getLocation().Y);
                        }
                        else
                        {
                            tempLocation = new Point(width - 1 - a.getLocation().X, a.getLocation().Y);
                        }
                    }
                    tempAtom = atomAt(tempLocation);
                    products.Add(singleSymmetry(tempAtom, lower, jigger, a.getLocation()));
                }
            }
            return(1 - Math.Pow(average(products), 1 / 4.0));
        }