public Dictionary <int, List <SystemTile> > GetClaims() { Dictionary <int, List <SystemTile> > allClaims = new Dictionary <int, List <SystemTile> >(); foreach (Tuple <int, int> start in HSLocations) { SystemTile startTile = tiles[start.Item1][start.Item2]; int playerNum = startTile.playerNum; List <SystemTile> claimedTiles = new List <SystemTile>(); allClaims.Add(playerNum, claimedTiles); } for (int x = 0; x <= MaxRadius * 2; x++) { for (int y = 0; y <= MaxRadius * 2; y++) { SystemTile tile = tiles[x][y]; foreach (int claimer in tile.contestedBy) { allClaims[claimer].Add(tile); } } } return(allClaims); }
public bool AnomaliesOK( Galaxy galaxy, bool allowAdjacentAnomalies = false ) { int MaxRadius = galaxy.MaxRadius; SystemTile[][] tiles = galaxy.tiles; if (!allowAdjacentAnomalies) { for (int x = 0; x <= MaxRadius * 2; x++) { for (int y = 0; y <= MaxRadius * 2; y++) { SystemTile tile = tiles[x][y]; if (tile.anomaly != Anomaly.None) { foreach (SystemTile adj in tile.adjacent) { if (adj.anomaly != Anomaly.None) { return(false); } } } } } } return(true); }
public void init(int maxRad, int people = 6) { players = people; int width = 2 * maxRad + 1; tiles = new SystemTile[width][]; for (int i = 0; i <= 2 * maxRad; i++) { SystemTile[] row = new SystemTile[width]; for (int j = 0; j <= 2 * maxRad; j++) { row[j] = TilesetGenerator.GetBlankTile(); } tiles[i] = row; } MaxRadius = maxRad; }
public bool wormholesOK( Galaxy galaxy, bool bothHoles = true, bool hardHoleLimit = true, int HoleCount = 2, bool allowAdjacentHoles = false) { int MaxRadius = galaxy.MaxRadius; SystemTile[][] tiles = galaxy.tiles; int alphaCount = 0; int betaCount = 0; for (int x = 0; x <= MaxRadius * 2; x++) { for (int y = 0; y <= MaxRadius * 2; y++) { if (tiles[x][y].wormholes == Wormhole.Alpha) { alphaCount++; } if (tiles[x][y].wormholes == Wormhole.Beta) { betaCount++; } } } for (int x = 0; x <= MaxRadius * 2; x++) { for (int y = 0; y <= MaxRadius * 2; y++) { if (tiles[x][y].adjacent.Count() != tiles[x][y].adjacent.Distinct().Count()) { return(false); } } } if (bothHoles && alphaCount == 0 && betaCount == 0) { return(false); } if (hardHoleLimit && alphaCount != HoleCount && betaCount != HoleCount) { return(false); } if (alphaCount < HoleCount || betaCount < HoleCount) { return(false); } if (!allowAdjacentHoles) { for (int x = 0; x <= MaxRadius * 2; x++) { for (int y = 0; y <= MaxRadius * 2; y++) { SystemTile thisTile = tiles[x][y]; if (thisTile.wormholes != Wormhole.None) { foreach (SystemTile adjTile in thisTile.adjacent) { if (adjTile.wormholes != Wormhole.None && adjTile.wormholes != thisTile.wormholes) { return(false); } } } } } } return(true); }
public (List <int>, Dictionary <int, List <SystemTile> >, Dictionary <int, List <SystemTile> >) StakeClaims( Galaxy galaxy, int walk = 10, int emptyWalk = 11, int asteroidWalk = 13, int novaWalk = 100, int nebulaWalk = 50, int riftWalk = 05, int wormWalk = 12) { int MaxRadius = galaxy.MaxRadius; SystemTile[][] tiles = galaxy.tiles; List <Tuple <int, int> > HSLocations = galaxy.HSLocations; foreach (Tuple <int, int> start in HSLocations) { SystemTile startTile = tiles[start.Item1][start.Item2]; int playerNum = startTile.playerNum; startTile.claims[playerNum] = 0; SortedList <int, List <SystemTile> > adjacent = new SortedList <int, List <SystemTile> >(); foreach (SystemTile tile in startTile.adjacent) { int walkDist = walk; if (tile.anomaly == Anomaly.Nova) { walkDist = novaWalk; } else if (tile.anomaly == Anomaly.Nebula) { walkDist = nebulaWalk; } else if (tile.anomaly == Anomaly.Asteroids) { walkDist = asteroidWalk; } else if (tile.anomaly == Anomaly.Rift) { walkDist = riftWalk; } else if (tile.planets.Count() == 0) { walkDist = emptyWalk; } if (!adjacent.ContainsKey(walkDist)) { adjacent.Add(walkDist, new List <SystemTile>()); } adjacent[walkDist].Add(tile); } while (adjacent.Count() > 0) { IList <int> keys = adjacent.Keys; int firstKey = keys.First(); List <SystemTile> firstList = adjacent[firstKey]; SystemTile closestTile = firstList.First(); firstList.Remove(closestTile); if (firstList.Count() == 0) { adjacent.Remove(firstKey); } if (!closestTile.claims.ContainsKey(playerNum)) { closestTile.claims.Add(playerNum, firstKey); foreach (SystemTile next in closestTile.adjacent) { if (!next.claims.ContainsKey(playerNum)) { int walkDist = firstKey; if (next.anomaly == Anomaly.Nova) { walkDist += novaWalk; } else if (next.anomaly == Anomaly.Nebula) { walkDist += nebulaWalk; } else if (next.anomaly == Anomaly.Asteroids) { walkDist += asteroidWalk; } else if (next.anomaly.HasFlag(Anomaly.Rift)) { walkDist += riftWalk; } else if ((closestTile.wormholes & next.wormholes) != Wormhole.None) { walkDist += wormWalk; } else if (next.planets.Count() == 0) { walkDist += emptyWalk; } else { walkDist += walk; } if (!adjacent.ContainsKey(walkDist)) { adjacent.Add(walkDist, new List <SystemTile>()); } adjacent[walkDist].Add(next); } } } } } for (int x = 0; x <= MaxRadius * 2; x++) { for (int y = 0; y <= MaxRadius * 2; y++) { SystemTile tile = tiles[x][y]; if (tile.claims.Count() > 0) { tile.bestClaim = tile.claims.Min(claim => claim.Value); if (tile.claims.Count(claim => claim.Value > tile.bestClaim) > 0) { // TODO: no second best claim if > half players have best claim // TODO: rework code so "top half" of claims are allowed tile.secondBestClaim = tile.claims.Where(claim => claim.Value > tile.bestClaim).Min(claim => claim.Value); } } } } Dictionary <int, List <SystemTile> > sliceClaim = new Dictionary <int, List <SystemTile> >(); Dictionary <int, List <SystemTile> > sliceContest = new Dictionary <int, List <SystemTile> >(); List <int> players = new List <int>(); foreach (Tuple <int, int> start in HSLocations) { SystemTile startTile = tiles[start.Item1][start.Item2]; int playerNum = startTile.playerNum; players.Add(playerNum); List <SystemTile> sliceTiles = new List <SystemTile>(); List <SystemTile> contestedTiles = new List <SystemTile>(); for (int x = 0; x <= MaxRadius * 2; x++) { for (int y = 0; y <= MaxRadius * 2; y++) { SystemTile tile = tiles[x][y]; int bestClaim = tile.bestClaim; if (tile.claims.Count() == 0) { continue; } int playerClaim = tile.claims[playerNum]; int contesting = tile.claims.Count(claim => claim.Value == bestClaim); bool playerHasClaim = playerClaim == bestClaim; bool contestedClaim = contesting > 1; if (playerHasClaim) { tile.contestedBy.Add(playerNum); } if (playerHasClaim && contestedClaim) { contestedTiles.Add(tile); } if (playerHasClaim && !contestedClaim) { sliceTiles.Add(tile); } } } sliceClaim.Add(playerNum, sliceTiles); sliceContest.Add(playerNum, contestedTiles); } return(players, sliceClaim, sliceContest); }
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)); }