//покрыть всю карту public static void FillAll(Tile[][] map, Tile tile, AdjacencyMatrix matrix) { for (int i = 0; i < map.Length; i++) { for (int j = 0; j < map[i].Length; j++) { tile.PlaceInstance(map, i, j, matrix); } } }
//покрыть случайным плотным разбросом public static void FillRandomThick(Tile[][] map, Tile tile, AdjacencyMatrix matrix) { int count = map.Length * 10; for (int i = 0; i < count; i++) { int x = _random.Next(0, map.Length); int y = _random.Next(0, map[x].Length); tile.PlaceInstance(map, x, y, matrix); } }
} //концы моста помечаются, чтоб при прокладывании дороги, зайти на мост и покинуть его можно было только на его "концах" public override void PlaceInstance(Tile[][] map, int x, int y, AdjacencyMatrix matrix) { Bridge lastBridge = new Bridge(x, y); lastBridge.IsLast = true; if (!CheckForAllowToPlace(map, x, y, matrix, typeof(Bridge))) { return; } map[x][y] = lastBridge; Random rnd = new Random(x * y); int bridgesCount = rnd.Next(1, 10); bool xAxis = rnd.Next(0, 2) == 0 ? true : false; int direction = rnd.Next(0, 2) == 0 ? 1 : -1; while (bridgesCount > 0) { if (xAxis) { x += direction; } else { y += direction; } if (x < 0 || x >= map.Length || y < 0 || y >= map[x].Length) { return; } if (!CheckForAllowToPlace(map, x, y, matrix, typeof(Bridge))) { break; } lastBridge = new Bridge(x, y); map[x][y] = lastBridge; bridgesCount--; } lastBridge.IsLast = true; }
//покрыть лужами в углах карты public static void FillPuddlesAtCorner(Tile[][] map, Tile tile, AdjacencyMatrix matrix) { int count = 2; //сколько всего луж for (int i = 0; i < count; i++) { int cx = i == 0 ? 0 : map.Length - 1; int cy = i == 0 ? 0 : map[cx].Length - 1; tile.PlaceInstance(map, cx, cy, matrix); if (map[cx][cy]?.GetType() != tile.GetType()) { continue; } int r = _random.Next(8, 20); //радиус лужи FillEllipse(map, tile, matrix, cx, cy, r); } }
protected bool CheckForAllowToPlace(Tile[][] map, int x, int y, AdjacencyMatrix matrix, Type type) { if (map == null || x < 0 || x >= map.Length || y < 0 || y >= map[x].Length || matrix == null || !type.IsSubclassOf(typeof(Tile))) { throw new ArgumentException(); } int maxDistance = matrix.GetMaxMatrixDistanceForTile(type); if (maxDistance == 0) { return(true); } else if (maxDistance == -1) { return(false); } //проверка на максимальную дистанцию во все стороны int xFrom = x - maxDistance >= 0 ? x - maxDistance : 0; int xTo = x + maxDistance < map.Length ? x + maxDistance : map.Length; int yFrom = y - maxDistance >= 0 ? y - maxDistance : 0; for (int i = xFrom; i < xTo; i++) { int yTo = y + maxDistance < map[i].Length ? y + maxDistance : map[i].Length; for (int j = yFrom; j < yTo; j++) { int allowedDistance = matrix.AllowedDistance(type, map[i][j]?.GetType()); if (allowedDistance > 0 && (Math.Abs(x - i) < allowedDistance || Math.Abs(y - j) < allowedDistance)) { return(false); } } } return(true); }
//покрыть случайными лужами public static void FillPuddles(Tile[][] map, Tile tile, AdjacencyMatrix matrix) { int maxCount = map.Length / 5; int count = _random.Next(5 < maxCount ? 5 : 0, map.Length / 5); //сколько всего луж for (int i = 0; i < count; i++) { int cx, cy; int tryes = 50; //количество попыток бросить лужу в рандомное место, чтоб в бесконечный луп не уходил на маленьких картах do { //в координатах исключаю края карты(верхний и нижний), чтоб по ним можно было ходить (когда лужа в углу оказывается, из неё никак не выйти и не войти) //можно было бы отдельно генерить мосты для прохода в непроходимые углы, но чет уже лень cx = _random.Next(1, map.Length - 1); cy = _random.Next(0, map[cx].Length); tile.PlaceInstance(map, cx, cy, matrix); tryes--; }while (map[cx][cy]?.GetType() != tile.GetType() && tryes > 0); int r = _random.Next(8, 20); //радиус лужи FillEllipse(map, tile, matrix, cx, cy, r); } }
public abstract void PlaceInstance(Tile[][] map, int x, int y, AdjacencyMatrix matrix);