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)); }