public double scoreGalaxy(
            Galaxy galaxy,
            bool bothHoles                = true,
            bool hardHoleLimit            = true,
            int HoleCount                 = 2,
            bool allowAdjacentHoles       = false,
            bool allowAdjacentAnomalies   = false,
            ContestValue contestMethod    = ContestValue.ClaimSize,
            ResourceScoreMethod resMethod = ResourceScoreMethod.MaxVal,
            double ResInfRatio            = 1.0,
            double ResScaling             = 2.0,
            double claimExponent          = -3.0)
        {
            double score         = 0.0;
            double resourceScore = 0.0;

            int MaxRadius = galaxy.MaxRadius;

            SystemTile[][]           tiles       = galaxy.tiles;
            List <Tuple <int, int> > HSLocations = galaxy.HSLocations;

            if (!wormholesOK(
                    galaxy,
                    bothHoles,
                    hardHoleLimit,
                    HoleCount,
                    allowAdjacentHoles))
            {
                return(0.0);
            }

            if (!AnomaliesOK(galaxy, allowAdjacentAnomalies))
            {
                return(0.0);
            }

            List <int> players;
            Dictionary <int, List <SystemTile> > sliceClaim;
            Dictionary <int, List <SystemTile> > sliceContest;


            (players, sliceClaim, sliceContest) = StakeClaims(galaxy);
            if (contestMethod == ContestValue.Slices)
            {
                resourceScore =
                    GetResourceScoreSlice(
                        galaxy,
                        players,
                        sliceClaim,
                        sliceContest,
                        resMethod,
                        ResInfRatio,
                        ResScaling);
            }
            else
            {
                resourceScore =
                    GetResourceScoreClaims(
                        galaxy,
                        players,
                        resMethod,
                        contestMethod,
                        ResInfRatio,
                        ResScaling,
                        claimExponent);
            }

            score = resourceScore;

            return(score);
        }
        public double GetResourceScoreClaims(
            Galaxy galaxy,
            List <int> players,
            ResourceScoreMethod resMethod = ResourceScoreMethod.MaxVal,
            ContestValue contestMethod    = ContestValue.TopAndRunnerUp,
            double ResInfRatio            = 1.0,
            double ResScaling             = 2.0,
            double claimExponent          = -2.0)
        {
            Dictionary <int, double> resourceClaims = new Dictionary <int, double>();

            foreach (int pnum in players)
            {
                resourceClaims.Add(pnum, 0);
            }

            int MaxRadius = galaxy.MaxRadius;

            for (int x = 0; x <= 2 * MaxRadius; x++)
            {
                for (int y = 0; y <= 2 * MaxRadius; y++)
                {
                    SystemTile tile = galaxy.tiles[x][y];
                    if (tile.sysNum > 0 && tile.planets.Count() > 0)
                    {
                        Dictionary <int, double> claims = new Dictionary <int, double>();
                        foreach (int pnum in tile.claims.Keys)
                        {
                            switch (contestMethod)
                            {
                            case ContestValue.Slices:
                                if (claims[pnum] == tile.bestClaim)
                                {
                                    claims.Add(pnum, 1.0);
                                }
                                break;

                            case ContestValue.ClaimSize:
                                if (tile.bestClaim > 0)
                                {
                                    claims.Add(pnum, Math.Pow(tile.claims[pnum], claimExponent));
                                }
                                else if (claims[pnum] == tile.bestClaim)
                                {
                                    claims.Add(pnum, 1.0);
                                }
                                break;

                            case ContestValue.TopAndRunnerUp:
                                if (tile.bestClaim == 0 && claims[pnum] == tile.bestClaim)
                                {
                                    claims.Add(pnum, 1.0);
                                }
                                else if (claims[pnum] == tile.bestClaim || claims[pnum] == tile.secondBestClaim)
                                {
                                    claims.Add(pnum, Math.Pow(tile.claims[pnum], claimExponent));
                                }
                                break;
                            }
                        }
                        if (claims.Count() == 0)
                        {
                            throw new Exception("Every system should have at least one claim, right?");
                        }
                        double claimScale = claims.Sum(claim => claim.Value);
                        foreach (KeyValuePair <int, double> claim in claims)
                        {
                            double val = 0.0;
                            switch (resMethod)
                            {
                            case ResourceScoreMethod.DirectSum:
                                val = tile.GetResources() + ResInfRatio * tile.GetInfluence();
                                break;

                            case ResourceScoreMethod.Separate:
                                throw new Exception("Not supporting \"separate\" for claim method");

                            case ResourceScoreMethod.MaxVal:
                                val = tile.planets.Sum(planet => Math.Max(planet.resources, ResInfRatio * planet.influence));
                                break;
                            }
                            tile.adjClaims.Add(claim.Key, claim.Value / claimScale);
                            resourceClaims[claim.Key] += val * claim.Value / claimScale;
                        }
                    }
                }
            }

            double minSlice = resourceClaims.Min(claim => claim.Value);
            double maxSlice = resourceClaims.Max(claim => claim.Value);

            return(Math.Pow(minSlice / maxSlice, ResScaling));
        }