/// <summary> /// Gets a list of player int identifiers from the galaxy /// </summary> /// <param name="galaxy">The galaxy to get the player list for</param> /// <returns>A List of ints, representing the player identifiers</returns> public List <int> GetPlayers() { 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); } return(players); }
/// <summary> /// Initializes a new galaxy. This adds placeholder tiles and initializes data structures. /// </summary> /// <param name="maxRad">The maximum 'radius' of the galaxy.</param> /// <param name="playerCount">The number of players to initialize the galaxy for</param> public void init(int maxRad, int playerCount = 6) { players = playerCount; 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 void RenderSystemTile(Form form, PaintEventArgs e, SystemTile tile, int x, int y, int w, int h, bool small = false) { if (e == null || form == null) { Debug.WriteLine("Render Tile missing needed field"); return; } string pathString = $"..\\..\\Resources\\" + $"{(small ? "small\\small-" : "full\\")}"; if (tile.sysNum == 0 && tile.playerNum != -1) { pathString += "tilehome.png"; } else { pathString += $"tile{(tile.sysNum < 10 ? "0" : "")}{tile.sysNum}.png"; } Bitmap tileImage; if (images.ContainsKey(pathString)) { tileImage = images[pathString]; } else { try { tileImage = new Bitmap(pathString); } catch (Exception ex) { pathString = $"..\\..\\Resources\\" + $"{(small ? "small\\small-" : "full\\")}" + $"tilebw.png"; tileImage = new Bitmap(pathString); } images.Add(pathString, tileImage); } e.Graphics.DrawImage(tileImage, x, y, w, h); }
public void renderGalaxy(Form form, PaintEventArgs e, Galaxy galaxy) { if (galaxy == null) { return; } bool small = false; Point tileSize = new Point((int)((small ? 200 : 900) * scale), (int)((small ? 172 : 774) * scale)); for (int y = 0; y < galaxy.tiles.Length; y++) { for (int x = 0; x < galaxy.tiles[y].Length; x++) { SystemTile tile = galaxy.tiles[y][x]; bool isHS = galaxy.HSLocations.Contains(new Tuple <int, int>(x, y)); if (tile.sysNum == 0 && !isHS) { continue; } Point tilePos = new Point((int)(0.75 * tileSize.X) * x, (int)(tileSize.Y * (y + 0.5 * (x - 3)))); RenderSystemTile(form, e, tile, tilePos.X, tilePos.Y, tileSize.X, tileSize.Y, small); } } }
/// <summary> /// Sets Strength of claims on systems. Based on selected contest method and exponent of claim strength to distance ratio /// </summary> /// <param name="contestMethod">The method used to determine how to get STR claims from DIST claims</param> /// <param name="claimExponent">The exponent used to determing STR of claims from DIST of claims</param> public void StakeStrClaims( StrContestMethod contestMethod = StrContestMethod.TopAndClose, double claimExponent = -2.0) { ResetStrengthClaims(); for (int x = 0; x <= 2 * MaxRadius; x++) { for (int y = 0; y <= 2 * MaxRadius; y++) { SystemTile tile = tiles[x][y]; if (tile.sysNum > 0 && tile.planets.Count() > 0) { Dictionary <int, double> claims = new Dictionary <int, double>(); foreach (int pnum in tile.distClaims.Keys) { switch (contestMethod) { case StrContestMethod.Slices: if (claims[pnum] == tile.distClaims.Values.Max()) { // full claim on resources for best claim (or tied) claims.Add(pnum, 1.0); } break; case StrContestMethod.ClaimSize: if (tile.distClaims.Values.Min() == 0 && tile.distClaims.Values.Min() == claims[pnum]) { // home systems (distance = 0) are only claimed by owner // TODO: might be a way to refactor a bit so this check isn't needed claims.Add(pnum, 1.0); } else { // all claims scaled by distance, inverted to a power // e.g. distances 10 and 20 might become claims of 1/10 and 1/20 claims.Add(pnum, Math.Pow(tile.distClaims[pnum], claimExponent)); } break; case StrContestMethod.TopAndClose: if (tile.distClaims.Values.Min() == 0 && tile.distClaims.Values.Min() == claims[pnum]) { // home systems (distance = 0) are only claimed by owner // TODO: might be a way to refactor a bit so this check isn't needed claims.Add(pnum, 1.0); } else if (claims[pnum] < 1.1 * tile.distClaims.Values.Min()) { // TODO: Refactor to make 'close' a configurable setting somehow // all claims scaled by distance, inverted to a power // e.g. distances 10 and 20 might become claims of 1/10 and 1/20 claims.Add(pnum, Math.Pow(tile.distClaims[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) { tile.strClaims.Add(claim.Key, claim.Value / claimScale); } } } } }
/// <summary> /// For the galaxy, fills the 'claims' for each tile for each players, where the claim is the 'distance' /// from their home system to the tile in question. Used for scoring 'slices' /// </summary> /// <param name="galaxy">The Galaxy to stake claims in</param> /// <param name="walk">'distance' for default walk</param> /// <param name="emptyWalk">'distance' for walk through empty space</param> /// <param name="asteroidWalk">'distance' for walk through asteroids</param> /// <param name="novaWalk">'distance' for walk through nova</param> /// <param name="nebulaWalk">'distance' for walk through nebula</param> /// <param name="riftWalk">'distance' for walk through gravity rift</param> /// <param name="wormWalk">'distance' for walk through wormhole</param> public void StakeDistClaims( int walk = 10, int emptyWalk = 11, int asteroidWalk = 13, int novaWalk = 100, int nebulaWalk = 20, int riftWalk = 08, int wormWalk = 12) { ResetDistanceClaims(); // for each home system (and therefore each player) determine how 'far' they are from each tile. // 'distances' are weighted by tile type, e.g. a system two tiles away with a planet in between is // 'closer' than the same setup where the middle tile is a nebula foreach (Tuple <int, int> start in HSLocations) { SystemTile startTile = tiles[start.Item1][start.Item2]; int playerNum = startTile.playerNum; // smaller number claims are better, a player's own home system has claim value 0 for themselves startTile.distClaims[playerNum] = 0; SortedList <int, List <SystemTile> > adjacent = new SortedList <int, List <SystemTile> >(); // start by getting sorted list of all adjacent tiles to HS, sorted by lowest 'distance' first 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); } //dijkstra's (?) to find 'shortest path' from HS to all tiles on the board 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.distClaims.ContainsKey(playerNum)) { closestTile.distClaims.Add(playerNum, firstKey); foreach (SystemTile next in closestTile.adjacent) { if (!next.distClaims.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); } } } } } }