public static DynamicMap[,] GenerateValidDynamicMap(StaticMap[,] static_map, int player_quantity, int random_seed) { //Create the players Random.InitState(random_seed); DynamicPlayer[] players = new DynamicPlayer[player_quantity]; for (int i = 0; i < player_quantity; i++) { players[i] = new DynamicPlayer(); } //Generate an invalid map DynamicMap[,] new_map = GenerateDynamicMap(static_map, players, player_quantity); //Smooth for (int k = 0; k < 3; k++) { new_map = SmoothDynamicMap(new_map, static_map); } return(new_map); }
static DynamicMap[,] GenerateDynamicMap(StaticMap[,] static_map, DynamicPlayer[] players, int player_quantity) { int sizex = static_map.GetLength(0); int sizey = static_map.GetLength(1); DynamicMap[,] new_map = new DynamicMap[sizex, sizey]; for (int y = 0; y < sizey; y++) { for (int x = 0; x < sizex; x++) { DynamicMap new_cell = new DynamicMap(); new_cell.is_capital = false; new_cell.owner_id = -1; new_cell.coordinates = new Vector2(x, y); new_map[x, y] = new_cell; } } //Get the empty cells List <DynamicMap> empty_cells = new List <DynamicMap>(); for (int y = 0; y < sizey; y++) { for (int x = 0; x < sizex; x++) { if (static_map[x, y].type == 1) { empty_cells.Add(new_map[x, y]); } } } Debug.Log("Generated empty cells list with " + empty_cells.Count); //Each player will receive a capital that will be removed from the empty cells general list List <Vector2> capitals = new List <Vector2>(); for (int i = 0; i < players.Length; i++) { DynamicPlayer new_player = players[i]; new_player.occupied_cells = new List <DynamicMap>(); int r = -1; bool is_valid; bool is_done = false; while (!is_done) { is_valid = true; r = Random.Range(0, empty_cells.Count); for (int o = 0; o < capitals.Count; o++) { if (Vector2.Distance(capitals[o], empty_cells[r].coordinates) < 25) { is_valid = false; } } if (is_valid) { capitals.Add(empty_cells[r].coordinates); is_done = true; } } empty_cells[r].is_capital = true; new_player.occupied_cells.Add(empty_cells[r]); new_player.capital_coord = empty_cells[r].coordinates; empty_cells.RemoveAt(r); players[i] = new_player; Debug.Log("Created a capital for player ID: " + i); } //Each player will take the empty list and create its own, ordered by the closest to furthest for (int i = 0; i < players.Length; i++) { players[i].empty_cells = new List <DynamicMap>(); List <float> distances = new List <float>(); for (int o = 0; o < empty_cells.Count; o++) { float distance_from_capital = Vector2.Distance(empty_cells[o].coordinates, players[i].capital_coord); int add_at = 0; for (int p = 0; p < players[i].empty_cells.Count; p++) { if (distance_from_capital < distances[p]) { add_at = p; p = players[i].empty_cells.Count; } else { add_at = p + 1; } } players[i].empty_cells.Insert(add_at, empty_cells[o]); distances.Insert(add_at, distance_from_capital); } Debug.Log("Created empty list for player id " + i + " with " + players[i].empty_cells.Count + " 1st " + players[i].empty_cells[0].coordinates + " last " + players[i].empty_cells[players[i].empty_cells.Count - 1].coordinates); } //Enquanto estiverem celulas vazias while (empty_cells.Count > 0) { //Pra cada jogador até acabarem as células vazias for (int id = 0; id < player_quantity; id++) { int provinces_it_had = players[id].occupied_cells.Count; //For each occupied cells DynamicPlayer current_player = players[id]; DynamicMap checking_dynamic; StaticMap checking_static; bool found_neighbour = false; for (int c = current_player.occupied_cells.Count - 1; c >= 0; c--) { checking_dynamic = current_player.occupied_cells[c]; checking_static = static_map[(int)checking_dynamic.coordinates.x, (int)checking_dynamic.coordinates.y]; //Check if it has any available neighbours List <DynamicMap> neighbours = new List <DynamicMap>(); for (int i = 0; i < checking_static.adjacent_land.Length; i++) { neighbours.Add(new_map[(int)checking_static.adjacent_land[i].x, (int)checking_static.adjacent_land[i].y]); } bool has_available_neighbour = false; while (neighbours.Count > 0) { int r = Random.Range(0, neighbours.Count); DynamicMap checking_neighbour = neighbours[r]; neighbours.RemoveAt(r); if (!found_neighbour) { if (checking_neighbour.owner_id == -1 && checking_neighbour.owner_id != id) { //Found available neighbour checking_neighbour.owner_id = id; current_player.occupied_cells.Add(checking_neighbour); //Remove it from general and private list for (int i = empty_cells.Count - 1; i >= 0; i--) { if (empty_cells[i] == checking_neighbour) { empty_cells.RemoveAt(i); } } for (int i = 0; i < players.Length; i++) { for (int o = players[i].empty_cells.Count - 1; o >= 0; o--) { if (players[i].empty_cells[o] == checking_neighbour) { players[i].empty_cells.RemoveAt(o); } } } c = -1; found_neighbour = true; has_available_neighbour = true; } } } //If not, remove it from list if (!has_available_neighbour) { current_player.occupied_cells.RemoveAt(c); } } if (current_player.empty_cells.Count > 0) { if (!found_neighbour) { if (current_player.empty_cells[0].owner_id == -1) { //Get a random cell from its ordered list DynamicMap new_cell = current_player.empty_cells[0]; new_cell.owner_id = id; current_player.occupied_cells.Add(new_cell); //Remove it from the general list for (int i = empty_cells.Count - 1; i >= 0; i--) { if (empty_cells[i] == new_cell) { empty_cells.RemoveAt(i); } } for (int i = 0; i < players.Length; i++) { for (int o = players[i].empty_cells.Count - 1; o >= 0; o--) { if (players[i].empty_cells[o] == new_cell) { players[i].empty_cells.RemoveAt(o); } } } } } } //Debug.Log("Player of id "+id+" from "+provinces_it_had+ " to "+players[id].occupied_cells.Count+ " gain "+(players[id].occupied_cells.Count-provinces_it_had)); } } return(new_map); }