public static float[,] GetPreferredMap(this Ship ship) { float[,] map = new float[ship.parentBoard.tiles.GetLength(0), ship.parentBoard.tiles.GetLength(1)]; for (int i = 0; i < 2; i++) { map = map.AddHeat (new Vector2Int(UnityEngine.Random.Range(0, map.GetLength(0)), UnityEngine.Random.Range(0, map.GetLength(1))), dist => Mathf.Pow(0.85f, dist)); } return(map); }
public Map(Board board) { ratings = new float[board.tiles.GetLength(0), board.tiles.GetLength(1)]; tiles = new Tile[board.tiles.GetLength(0), board.tiles.GetLength(1)]; float[,] gaussian_map = new float[board.tiles.GetLength(0), board.tiles.GetLength(1)]; bool[,] permablock_map = new bool[tiles.GetLength(0), tiles.GetLength(1)]; for (int x = 0; x < tiles.GetLength(0); x++) { for (int y = 0; y < tiles.GetLength(1); y++) { Gameplay.Tile tile = board.tiles[x, y]; if (tile.hit) { if (tile.containedShip != null) { bool shipInTileDestroyed = tile.containedShip.health <= 0; permablock_map[x, y] = shipInTileDestroyed; for (int i = 0; i < 8; i += shipInTileDestroyed ? 1 : 2) { int x_toblock = x + Math.Sign((i - 1) * (5 - i)); int y_toblock = y + Math.Sign((3 - i) * (7 - i)); if (x_toblock >= 0 && x_toblock < permablock_map.GetLength(0) && y_toblock >= 0 && y_toblock < permablock_map.GetLength(1)) { permablock_map[x_toblock, y_toblock] = true; } } gaussian_map = gaussian_map.AddHeat(tile.coordinates, dist => Mathf.Pow(0.4f, dist) * 3.0f); Gameplay.Tile[] neighbours = new Gameplay.Tile[4]; for (int i = 0; i < 4; i++) { int nx = x + (1 - i) % 2; int ny = y + (2 - i) % 2; if (nx >= 0 && nx < tiles.GetLength(0) && ny >= 0 && ny < tiles.GetLength(1)) { neighbours[i] = board.tiles[nx, ny]; } } int hit_neighbours = neighbours.Count(c => c != null && c.hit && c.containedShip != null); if (hit_neighbours == 0) { for (int i = 0; i < 4; i++) { Gameplay.Tile neighbour = neighbours[i]; if (neighbour != null) { tiles[neighbour.coordinates.x, neighbour.coordinates.y].importance = 2.0f; } } } else if (hit_neighbours == 1) { for (int i = 0; i < 4; i++) { Gameplay.Tile neighbour = neighbours[i]; if (neighbour != null && neighbour.hit && neighbour.containedShip != null) { Gameplay.Tile opposite = neighbours[(i + 2) % 4]; if (opposite != null) { tiles[opposite.coordinates.x, opposite.coordinates.y].importance = 3.5f; } break; } } } } else { gaussian_map = gaussian_map.AddHeat(tile.coordinates, dist => Mathf.Pow(0.3f, dist) * UnityEngine.Random.Range(-3.0f, 0.5f)); permablock_map[x, y] = true; } } } } AircraftRecon[] recon = Array.ConvertAll(Battle.main.effects.Where(x => x is AircraftRecon && x.targetedPlayer == board.owner).ToArray(), x => x as AircraftRecon); for (int i = 0; i < recon.Length; i++) { int result = recon[i].result; int line = recon[i].target; int line_position = line % (board.tiles.GetLength(0) - 1); bool line_vertical = line == line_position; int start = result > 0 ? line_position + 1 : 0; int end = result > 0 ? board.tiles.GetLength(line_vertical ? 0 : 1) : line_position + 1; for (int a = start; a < end; a++) { for (int b = 0; b < board.tiles.GetLength(line_vertical ? 1 : 0); b++) { int x = line_vertical ? a : b; int y = line_vertical ? b : a; gaussian_map[x, y] *= 1.5f; } } } gaussian_map = gaussian_map.Normalize(); tiles.InjectArray(gaussian_map, (ref Tile a, float b) => a.gauss = b); int[,] space_map = new int[board.tiles.GetLength(0), board.tiles.GetLength(1)]; for (int i = 0; i < 2; i++) { for (int a = 0; a < tiles.GetLength(i); a++) { int sequence_start = 0; int sequence = 0; for (int b = 0; b < tiles.GetLength(1 - i); b++) { int x = i == 0 ? a : b; int y = i == 0 ? b : a; bool permablocked = permablock_map[x, y]; if (!permablocked) { if (sequence == 0) { sequence_start = b; } sequence++; } if (b == tiles.GetLength(1 - i) - 1 || permablocked) { for (int depth = 0; depth < sequence; depth++) { Vector2Int pos = new Vector2Int(i == 0 ? a : sequence_start + depth, i == 0 ? sequence_start + depth : a); if (sequence > space_map[pos.x, pos.y] && !board.tiles[pos.x, pos.y].hit) { space_map[pos.x, pos.y] = sequence; } } sequence = 0; } } } } tiles.InjectArray(space_map, (ref Tile x, int y) => x.possibleShips = board.ships.Where(ship => ship.health > 0 && ship.maxHealth <= y).ToArray()); int combined_ship_health = board.ships.Sum(ship => ship.health > 0 ? ship.maxHealth : 0); for (int x = 0; x < ratings.GetLength(0); x++) { for (int y = 0; y < ratings.GetLength(1); y++) { Tile tile = tiles[x, y]; ratings[x, y] = (tile.importance + tile.gauss) * (tile.possibleShips.Sum(ship => ship.maxHealth) / (float)combined_ship_health); } } }