public void FindFairStartingLocations(Map map, BalanceCheckerSettings settings, List<int> fixedStarts, int minimumCapitalDistance) { _MinimumDistanceBetweenCapitals = minimumCapitalDistance; _FixedStarts = fixedStarts; _Map = (Map)map.Clone(); _balanceCheckerSettings = settings; _States = new PrioQueue<MapState, double>(); _States.Enqueue(MapState.FromMap(map), 0); TopResult = null; _FairnessDict = new Dictionary<string, double>(); Start(); }
public static MapState FromMap(Map map) { MapState ms = new MapState(); foreach(Tile t in map.GetAllTiles()) foreach (Unit u in t.Units) if (u.UnitOwner != Game.BarbarianPlayerId) { while (ms.PlayerStarts.Count <= u.UnitOwner) ms.PlayerStarts.Add(new PlayerStart() { PlayerId = ms.PlayerStarts.Count }); ms.PlayerStarts[u.UnitOwner].StartX = t.X; ms.PlayerStarts[u.UnitOwner].StartY = t.Y; } return ms; }
public void ApplyToMap(Map map) { Dictionary<int, List<Unit>> playerUnits = new Dictionary<int, List<Unit>>(); foreach (Tile t in map.GetAllTiles()) { foreach (Unit u in t.Units) { if (!playerUnits.ContainsKey(u.UnitOwner)) playerUnits[u.UnitOwner] = new List<Unit>(); playerUnits[u.UnitOwner].Add(u); } t.Units.Clear(); } foreach (PlayerStart ps in PlayerStarts) map.GetTile(ps.StartX, ps.StartY).Units.AddRange(playerUnits[ps.PlayerId]); }
public List<MapState> GetNeighbouringStates(Map map, List<int> fixedStarts, int minimumDistanceBetweenCapitals) { List<MapState> list = new List<MapState>(); foreach (var startToMove in PlayerStarts) { if (fixedStarts.Contains(startToMove.PlayerId)) continue; foreach (Tile t in map.GetNeighbours(map.GetTile(startToMove.StartX, startToMove.StartY), true)) { if (t.IsTraversableByLand()) { MapState clone = this.Clone(); clone.PlayerStarts[startToMove.PlayerId].StartX = t.X; clone.PlayerStarts[startToMove.PlayerId].StartY = t.Y; if(clone.RespectsMinimumDistance(map, minimumDistanceBetweenCapitals)) list.Add(clone); } } } return list; }
public static Map CropToSelection(Map thisMap, Selection selection) { int minX = int.MaxValue; int maxX = int.MinValue; int minY = int.MaxValue; int maxY = int.MinValue; foreach (var t in selection) { minX = Math.Min(minX, t.X); minY = Math.Min(minY, t.Y); maxX = Math.Max(maxX, t.X); maxY = Math.Max(maxY, t.Y); } Map map = (Map)thisMap.Clone(); if (minX == int.MaxValue) return map; // return uncropped map if no selected tiles map.SetDimensions(maxX - minX + 1, maxY - minY + 1); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { Tile t = (Tile)thisMap.GetTile(x, y).Clone(); map.SetTile(x - minX, y - minY, t); } } return map; }
public static Map RepeatVertically(Map thisMap, int times) { if (times < 2) return thisMap; Map map = (Map)thisMap.Clone(); map.SetDimensions(thisMap.Width, thisMap.Height * times); for (int x = 0; x < thisMap.Width; x++) { for (int y = 0; y < thisMap.Height; y++) { Tile t = thisMap.GetTile(x, y); for (int r = 0; r < times; r++) map.SetTile(x, y + r * thisMap.Height, (Tile)t.Clone()); } } return map; }
public override Map Execute(Map map, Selection selection) { switch (MirrorAroundEdge) { case MirrorEdge.East: return MirrorEast(map); case MirrorEdge.North: return MirrorNorth(map); case MirrorEdge.West: return MirrorWest(map); case MirrorEdge.South: return MirrorSouth(map); default: throw new Exception("Unknown mirror edge: " + MirrorAroundEdge); } }
public override Selection Execute(Map map, Selection selection) { if (Clear) return new Selection(); else return SelectTiles(map, selection, Left, Top, Width, Height); }
public abstract Selection Execute(Map map, Selection selection);
public static Map Resize(Map thisMap, ResizeOperation parameters) { Map map = (Map)thisMap.Clone(); map.SetDimensions(parameters.Width, parameters.Height); for (int x = 0; x < parameters.Width; x++) { for (int y = 0; y < parameters.Height; y++) { Tile t = new Tile(); t.PlotType = parameters.PlotType; t.Terrain = parameters.TerrainType; map.SetTile(x, y, t); } } int minX = 0; // west alignment int minY = 0; // south alignment if (parameters.HorAlign == HorizontalNeighbour.None) // center alignment minX = (thisMap.Width - parameters.Width) / 2; else if (parameters.HorAlign == HorizontalNeighbour.East) minX = thisMap.Width - parameters.Width; if (parameters.VerAlign == VerticalNeighbour.None) // center alignment minY = (thisMap.Height - parameters.Height) / 2; else if (parameters.VerAlign == VerticalNeighbour.North) minY = thisMap.Height - parameters.Height; for (int x = minX; x < minX + parameters.Width; x++) { for (int y = minY; y < minY + parameters.Height; y++) { Tile t = (Tile)thisMap.GetTileAcrossWrap(x, y, false, false); if(t != null) map.SetTile(x - minX, y - minY, t); } } return map; }
public static Selection SelectTiles(Map thisMap, Selection selection, int left, int top, int width, int height) { var result = new Selection(); result.AddRange(selection); for (int x = left; x < left + width; x++) for (int y = top; y < top + height; y++) { Tile t = thisMap.GetTileAcrossWrap(x, y); if (t != null && !selection.ContainsTile(t)) result.Add(t.GetCoordinate()); } return result; }
private static Game ParseBicFile(string path) { throw new Exception("Parsing .bic files is not yet fully implemented. (The map dimensions are hardcoded. Try asking Novice nicely for help.)"); BinaryReader reader = null; try { Game game = new Game(); reader = new BinaryReader(new FileStream(path, FileMode.Open)); int i = 0; try { while (true) { byte b = reader.ReadByte(); if ("TILE".IndexOf((char)b) == i) i++; else i = 0; if (i > 3) { i = 0; int tileCount = reader.ReadInt32(); Map map = new Map(); map.Width = 200; map.Height = 100; map.SetDimensions(map.Width, map.Height); game.Map = map; for (int y = map.Height-1; y >= 0; y--) { for (int xx = 0; xx < map.Width; xx++) { Tile tile = new Tile(); if (xx * 2 >= map.Width) tile.X = xx * 2 - map.Width + 1; else tile.X = xx * 2; tile.Y = y; tile.PlotType = PlotTypes.FLAT; int tileByteCount = reader.ReadInt32(); int riverInfo = reader.ReadInt16(); int resource = reader.ReadInt32(); byte image = reader.ReadByte(); byte file = reader.ReadByte(); int unknown = reader.ReadInt16(); byte overlays = reader.ReadByte(); byte terrain = reader.ReadByte(); /* 0a byte binary flags as indicated in overview 0b nibble terrain: 0 = desert, 1 = plains, 2 = grassland, 3 = tundra, 4 = floodplain, 5 = hills, 6 = mountain, 7 = forest, 8 = jungle, 9 = coast, a = sea, b = ocean nibble basic terrain: only 0,1,2,3,9,a,b */ int terrainType = (int)(terrain / 16); int basicTerrain = terrain % 16; switch (terrainType) { case 0: tile.Terrain = TerrainTypes.TERRAIN_DESERT; break; case 1: tile.Terrain = TerrainTypes.TERRAIN_PLAINS; break; case 2: tile.Terrain = TerrainTypes.TERRAIN_GRASS; break; case 3: tile.Terrain = TerrainTypes.TERRAIN_TUNDRA; break; case 4: tile.Terrain = TerrainTypes.TERRAIN_DESERT; tile.FeatureType = FeatureTypes.FEATURE_FLOOD_PLAINS; break; case 5: tile.PlotType = PlotTypes.HILL; tile.Terrain = TerrainTypes.TERRAIN_GRASS; break; case 6: tile.PlotType = PlotTypes.PEAK; tile.Terrain = TerrainTypes.TERRAIN_GRASS; break; case 7: tile.FeatureType = FeatureTypes.FEATURE_FOREST; tile.Terrain = TerrainTypes.TERRAIN_GRASS; break; case 8: tile.FeatureType = FeatureTypes.FEATURE_JUNGLE; tile.Terrain = TerrainTypes.TERRAIN_GRASS; break; case 9: tile.Terrain = TerrainTypes.TERRAIN_COAST; break; case 10: case 11: tile.Terrain = TerrainTypes.TERRAIN_OCEAN; break; default: tile.Terrain = TerrainTypes.TERRAIN_GRASS; break; } switch (basicTerrain) { case 0: tile.Terrain = TerrainTypes.TERRAIN_DESERT; break; case 1: tile.Terrain = TerrainTypes.TERRAIN_PLAINS; break; case 2: tile.Terrain = TerrainTypes.TERRAIN_GRASS; break; case 3: tile.Terrain = TerrainTypes.TERRAIN_TUNDRA; break; case 9: tile.Terrain = TerrainTypes.TERRAIN_COAST; break; case 10: case 11: tile.Terrain = TerrainTypes.TERRAIN_OCEAN; break; default: break; } int bonuses = reader.ReadInt16(); int barbCamp = reader.ReadInt16(); int unknown2 = reader.ReadInt32(); int continent = reader.ReadInt16(); //byte unknown3 = reader.ReadByte(); game.Map.SetTile(tile.X, tile.Y, tile); } } } } } catch (EndOfStreamException) { } return game; } catch (Exception e) { throw new Exception(string.Format("Exception reading map from file {0}. Error was: {1}", path, e.Message), e); } finally { if (reader != null) reader.Close(); } }
public void SetTiles(Map map, int minX, int minY) { for (int x = minX; x < minX + map.Width; x++) for (int y = minY; y < minY + map.Height; y++) this.SetTile(x, y, (Tile)map.GetTile(x - minX, y - minY).Clone()); }
public override Map Execute(Map map, Selection selection) { return RotateAroundCorner(map, TopCorner, LeftCorner); }
public static Map RotateCW(Map thisMap) { Map map = new Map(); map.SetDimensions(thisMap.Height, thisMap.Width); map.IsHorizontalWrap = thisMap.IsVerticalWrap; map.IsVerticalWrap = thisMap.IsHorizontalWrap; map.UnparsedData = new List<string>(thisMap.UnparsedData); foreach (Tile t in thisMap.GetAllTiles()) { map.SetTile(t.Y, map.Height - 1 - t.X, (Tile)t.Clone()); } Map map2 = (Map)map.Clone(); foreach (Tile t in map2.GetAllTiles()) { t.IsWOfRiver = false; t.IsNOfRiver = false; } foreach (Tile t in map.GetAllTiles()) { if (t.IsNOfRiver) { Tile w = map2.GetNeighbour(t.X, t.Y, HorizontalNeighbour.West, VerticalNeighbour.None); if (w != null) { w.IsWOfRiver = true; if (t.RiverWEDirection == RiverDirection.WEST_TO_EAST) w.RiverNSDirection = RiverDirection.NORTH_TO_SOUTH; else w.RiverNSDirection = RiverDirection.SOUTH_TO_NORTH; } } if (t.IsWOfRiver) { Tile tt = map2.GetTile(t.X, t.Y); tt.IsNOfRiver = true; if (t.RiverNSDirection == RiverDirection.NORTH_TO_SOUTH) tt.RiverWEDirection = RiverDirection.EAST_TO_WEST; else tt.RiverWEDirection = RiverDirection.WEST_TO_EAST; } } return map2; }
public override Map Execute(Map map, Selection selection) { return CropToSelection(map, selection); }
public static Map RotateAroundCorner(Map map, bool topCorner, bool leftCorner) { if (map.Width != map.Height) map = ResizeOperation.Resize(map, new ResizeOperation() { Width = Math.Min(map.Width, map.Height), Height = Math.Min(map.Width, map.Height), TerrainType = TerrainTypes.TERRAIN_GRASS, PlotType = PlotTypes.FLAT, HorAlign = HorizontalNeighbour.None, VerAlign = VerticalNeighbour.None }); Map topLeft = null, topRight = null, bottomLeft = null, bottomRight = null; if (leftCorner) { if (topCorner) { // Rotate around top left corner bottomRight = map; bottomLeft = RotateOperation.RotateCW(bottomRight); topLeft = RotateOperation.RotateCW(bottomLeft); topRight = RotateOperation.RotateCW(topLeft); } else { // Rotate around bottom left corner topRight = map; bottomRight = RotateOperation.RotateCW(topRight); bottomLeft = RotateOperation.RotateCW(bottomRight); topLeft = RotateOperation.RotateCW(bottomLeft); } } else { if (topCorner) { // Rotate around top right corner bottomLeft = map; topLeft = RotateOperation.RotateCW(bottomLeft); topRight = RotateOperation.RotateCW(topLeft); bottomRight = RotateOperation.RotateCW(topRight); } else { // Rotate around bottom right corner topLeft = map; topRight = RotateOperation.RotateCW(topLeft); bottomRight = RotateOperation.RotateCW(topRight); bottomLeft = RotateOperation.RotateCW(bottomRight); } } Map r = (Map)map.Clone(); r.SetDimensions(map.Width * 2, map.Height * 2); r.SetTiles(bottomRight, map.Width, 0); r.SetTiles(bottomLeft, 0, 0); r.SetTiles(topLeft, 0, map.Height); r.SetTiles(topRight, map.Width, map.Height); return r; }
public override Map Execute(Map map, Selection selection) { return Resize(map, this); }
public static Map MirrorWest(Map thisMap) { Map map = (Map)thisMap.Clone(); map.SetDimensions(thisMap.Width * 2, thisMap.Height); for (int x = 0; x < thisMap.Width; x++) { for (int y = 0; y < thisMap.Height; y++) { Tile t = thisMap.GetTile(x, y); map.SetTile(thisMap.Width + x, y, (Tile)t.Clone()); map.SetTile(thisMap.Width - 1 - x, y, (Tile)t.Clone()); } } map.FlipRiversHorizontally(0, thisMap.Width - 1); return map; }
public static Map MirrorSouth(Map thisMap) { Map map = (Map)thisMap.Clone(); map.SetDimensions(thisMap.Width, thisMap.Height * 2); for (int x = 0; x < thisMap.Width; x++) { for (int y = 0; y < thisMap.Height; y++) { Tile t = thisMap.GetTile(x, y); map.SetTile(x, thisMap.Height + y, (Tile)t.Clone()); map.SetTile(x, thisMap.Height - 1 - y, (Tile)t.Clone()); } } map.FlipRiversVertically(0, thisMap.Height - 1); return map; }
public bool RespectsMinimumDistance(Map map, int minimumDistanceBetweenCapitals) { foreach (var ps in PlayerStarts) foreach (var ps2 in PlayerStarts) if (ps != ps2 && map.GetDistanceBetween(ps.StartX, ps.StartY, ps2.StartX, ps2.StartY) < minimumDistanceBetweenCapitals) return false; return true; }
public override Map Execute(Map map, Selection selection) { return ScrambleSelection(map, selection, Distance, DontScrambleWater); }
public override Map Execute(Map map, Selection selection) { if (Clockwise) return RotateCW(map); else return RotateCCW(map); }
public override Map Execute(Map map, Selection selection) { if (Vertically) return RepeatVertically(map, Times); else return RepeatHorizontally(map, Times); }
private static Game ParseWorldbuilderFile(string path) { TextReader tr = null; int lineNumber = 0; string line = null; try { Game game = new Game(); bool inGame = false; Map map = null; Tile tile = null; Unit unit = null; Team team = null; Player player = null; tr = new StreamReader(new FileStream(path, FileMode.Open)); line = tr.ReadLine(); while (line != null) { lineNumber++; line = line.Trim(); string tag = line.ToLower(); string value = null; if (inGame) { if (tag.Equals("endgame")) inGame = false; else game.UnparsedData.Add(line); } else if (map != null) { if (tag.Equals("endmap")) { map.SetDimensions(map.Width, map.Height); game.Map = map; map = null; } else if (ExtractValue(line, "grid width=", ref value)) map.Width = Int32.Parse(value); else if (ExtractValue(line, "grid height=", ref value)) map.Height = Int32.Parse(value); else if (ExtractValue(line, "wrap X=", ref value)) map.IsHorizontalWrap = (Int32.Parse(value) == 1); else if (ExtractValue(line, "wrap Y=", ref value)) map.IsVerticalWrap = (Int32.Parse(value) == 1); else if (ExtractValue(line, "num plots written=", ref value)) ;// Ignore this value, overwrite it with width*height when saving map else if (ExtractValue(line, "num signs written=", ref value)) ;// Ignore this value, overwrite it with #of signs when saving map else map.UnparsedData.Add(line); } else if (team != null) { if (tag.Equals("endteam")) { game.Teams.Add(team); team = null; } else if (ExtractValue(line, "TeamID=", ref value)) team.TeamId = Int32.Parse(value); else team.UnparsedData.Add(line); } else if (player != null) { if (tag.Equals("endplayer")) { Team t = game.GetTeamById(player.TeamId); if (t == null) throw new Exception("Player object referring to unknown TeamId " + player.TeamId); game.Players.Add(player); player.PlayerId = game.Players.Count - 1; player = null; } else if (ExtractValue(line, "Team=", ref value)) player.TeamId = Int32.Parse(value); else if (ExtractValue(line, "LeaderType=", ref value)) player.LeaderType = value; else if (ExtractValue(line, "CivType=", ref value)) player.CivType = value; else if (ExtractValue(line, "Color=", ref value)) player.Color = (PlayerColors)Enum.Parse(typeof(PlayerColors), value); else player.UnparsedData.Add(line); } else if (tile != null) { if (unit != null) { //BeginUnit // UnitType=UNIT_SETTLER, UnitOwner=1 // Damage=0 // Level=1, Experience=0 // FacingDirection=4 // UnitAIType=UNITAI_SETTLE //EndUnit if (tag.Equals("endunit")) { tile.Units.Add(unit); unit = null; } else if (ExtractValue(line, "UnitType=", ref value)) { int i = value.IndexOf(", UnitOwner="); if (i > 0) { unit.UnitType = value.Substring(0, i).Trim(); unit.UnitOwner = Int32.Parse(value.Substring(i + ", UnitOwner=".Length).Trim()); } else unit.UnitType = value.Trim(); } else unit.UnparsedData.Add(line); } else if (tag.Equals("beginunit")) { unit = new Unit(); } else if (tag.Equals("endplot")) { game.Map.SetTile(tile.X, tile.Y, tile); tile = null; } else if (ExtractValue(line, "x=", ref value)) { int i = value.IndexOf(",y="); if (i > 0) { tile.X = Int32.Parse(value.Substring(0, i).Trim()); tile.Y = Int32.Parse(value.Substring(i + 3).Trim()); } } else if (ExtractValue(line, "TerrainType=", ref value)) tile.Terrain = (TerrainTypes)Enum.Parse(typeof(TerrainTypes), value); else if (ExtractValue(line, "BonusType=", ref value)) tile.BonusType = (BonusTypes)Enum.Parse(typeof(BonusTypes), value); else if (ExtractValue(line, "PlotType=", ref value)) tile.PlotType = (PlotTypes)Int32.Parse(value); else if (ExtractValue(line, "RiverWEDirection=", ref value)) tile.RiverWEDirection = (RiverDirection)Int32.Parse(value); else if (ExtractValue(line, "RiverNSDirection=", ref value)) tile.RiverNSDirection = (RiverDirection)Int32.Parse(value); else if (tag.Equals("isnofriver")) tile.IsNOfRiver = true; else if (tag.Equals("iswofriver")) tile.IsWOfRiver = true; else if (ExtractValue(line, "FeatureType=", ref value)) { int i = value.IndexOf(", FeatureVariety="); if (i > 0) { tile.FeatureType = (FeatureTypes)Enum.Parse(typeof(FeatureTypes), value.Substring(0, i).Trim()); tile.FeatureVariety = Int32.Parse(value.Substring(i + ", FeatureVariety=".Length).Trim()); } else { tile.FeatureType = (FeatureTypes)Enum.Parse(typeof(FeatureTypes), value); tile.FeatureVariety = -1; } } else tile.UnparsedData.Add(line); } else if (tag.Equals("begingame")) inGame = true; else if (tag.Equals("beginteam")) team = new Team(); else if (tag.Equals("beginplayer")) player = new Player(); else if (tag.Equals("beginmap")) map = new Map(); else if (tag.Equals("beginplot")) tile = new Tile(); else if (ExtractValue(line, "Version=", ref value)) game.Version = Int32.Parse(value); else game.UnparsedOuterData.Add(line); line = tr.ReadLine(); } //BeginPlot // x=1,y=2 // BonusType=BONUS_CLAM // FeatureType=FEATURE_FOREST, FeatureVariety=1 // TerrainType=TERRAIN_GRASS // PlotType=1 //EndPlot //BeginMap // grid width=50 // grid height=50 // top latitude=90 // bottom latitude=-90 // wrap X=1 // wrap Y=1 // world size=WORLDSIZE_STANDARD // climate=CLIMATE_TEMPERATE // sealevel=SEALEVEL_MEDIUM // num plots written=2500 // num signs written=0 // Randomize Resources=false //EndMap game.Players.Add(new Player() { TeamId = -1, PlayerId = Game.BarbarianPlayerId, CivType = "BARBARIANS", Color = PlayerColors.PLAYERCOLOR_BLACK, LeaderType = "CONAN" }); return game; } catch (Exception e) { throw new Exception(string.Format("Exception reading map from file {0} (line {1}: {2}). Error was: {3}", path, lineNumber, line, e.Message), e); } finally { if (tr != null) tr.Close(); } }
public static Map ScrambleSelection(Map thisMap, Selection selection, int distance, bool dontScrambleWater) { Map map = (Map)thisMap.Clone(); var unswappedTiles = map.GetAllTiles().Where(t => selection.ContainsTile(t) && !(t.IsWater() && dontScrambleWater)).ToList(); unswappedTiles = Utility.ShuffleList(unswappedTiles); Dictionary<Tile, Tile> swaps = new Dictionary<Tile, Tile>(); while (unswappedTiles.Count > 0) { var tileToSwap = unswappedTiles[0]; Tile tileToSwapWith = null; for (var i = 1; i < unswappedTiles.Count; i++) { var t = unswappedTiles[i]; if (map.GetDistanceBetween(t.X, t.Y, tileToSwap.X, tileToSwap.Y) <= distance) { tileToSwapWith = t; break; } } if (tileToSwapWith != null) { swaps[tileToSwap] = tileToSwapWith; unswappedTiles.Remove(tileToSwapWith); } unswappedTiles.Remove(tileToSwap); } foreach (var tile in swaps.Keys) { Utility.SwapTiles(tile, swaps[tile]); } map.CalculateFreshWater(); map.CalculateIrrigationStatus(); map.AssignContinentIds(); return map; }