public static TileSelection SelectContiguous(Tile start, TileSelection tiles) { var time = Time.realtimeSinceStartup; TileSelection result = new TileSelection(); TileSelection open = new TileSelection(); open.Add(start); var i = 0; while (open.Count() > 0) { i++; if (i > tiles.Count()) { throw(new Exception("Fill fail")); } var t = open[0]; open.Remove(t); result.Add(t); foreach (var n in t.adjacent.tiles) { if (result.DoesNotContain(n) && tiles.Contains(n)) { open.Add(n); } } } _gui_manager.selected_tiles = result; return(result); }
public static TileSelection Grow(TileSelection tiles) { var time = Time.realtimeSinceStartup; TileSelection result = new TileSelection(); foreach (var t in tiles.tiles) { result.Add(t); foreach (var n in t.adjacent.tiles) { result.Add(n); } } _gui_manager.selected_tiles = result; return(result); }
public TileSelection All() { TileSelection result = new TileSelection(); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { result.Add(grid[x, y]); } } return(result); }
public static Region ClosestRegion(TileSelection tiles, Region to_ignore = null, HashSet <Region> whitelist = null) { var open = new List <SearchRecord>(); var openTiles = new TileSelection(); var closed = new TileSelection(); foreach (var t in tiles.tiles) { var record = new SearchRecord(); record.t = t; record.cost = 0; open.Add(record); } var i = 0; while (open.Count > 0) { i++; if (i > 1000) { throw(new Exception("Finding closest Region took too long")); } open.Sort((a, b) => a.cost - b.cost); var node = open[0]; closed.Add(node.t); open.RemoveAt(0); openTiles.Remove(node.t); if (node.t.region != null && node.t.region != to_ignore) { if (whitelist == null || whitelist.Contains(node.t.region)) { return(node.t.region); } } foreach (var n in node.t.adjacent.tiles) { if (closed.DoesNotContain(n) && openTiles.DoesNotContain(n)) { var record = new SearchRecord(); record.t = n; record.cost = node.cost + 1; open.Add(record); openTiles.Add(record.t); } } } _gui_manager.selected_region = null; _gui_manager.selected_tiles = tiles; throw new Exception("Could not find any other Regions after " + i + " iterations"); }
public static List <TileSelection> SeperateContiguous(TileSelection tiles) { var time = Time.realtimeSinceStartup; TileSelection src = new TileSelection(); List <TileSelection> result = new List <TileSelection>(); foreach (var t in tiles.tiles) { src.Add(t); } while (src.Count() > 0) { var region = MapGen.SelectContiguous(src[0], src); result.Add(region); foreach (var t in region.tiles) { src.Remove(t); } } return(result); }
public static TileSelection Shrink(TileSelection tiles) { TileSelection result = new TileSelection(); foreach (var t in tiles.tiles) { bool valid = true; foreach (var n in t.adjacent.tiles) { if (tiles.DoesNotContain(n)) { valid = false; break; } } if (valid) { result.Add(t); } } _gui_manager.selected_tiles = result; return(result); }
public IEnumerator Generate() { var image_scale = 10; image_scale = heightmap.width / this.width; image_scale = Math.Max(image_scale, heightmap.height / this.height); /************************/ Stamp("Init and Preinit"); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { var t = grid[x, y]; //t.land = heightmap.GetPixel(x*image_scale, y*image_scale).grayscale < 0.5f; t.land = Perlin.OctavePerlin(x * scale + x_offset, y * scale + y_offset, 0, 7, 0.3) < land_threshold; t.x = x; t.y = y; grid[x, y] = t; } } /************************/ Stamp("Building Land"); yield return(new WaitForSeconds(0)); /************************/ Stamp("Finding Land"); var land = this.All().FindAll((t) => t.land); /************************/ Stamp("Shrinking Land"); land = MapGen.Shrink(land); land = MapGen.Shrink(land); land = MapGen.Shrink(land); /************************/ Stamp("Seperating into base regions"); var selection_list = SeperateContiguous(land); yield return(new WaitForSeconds(0)); /************************/ Stamp("Expanding into base regions"); selection_list = MapGen.ExpandRegions(selection_list); yield return(new WaitForSeconds(0)); /************************/ Stamp("Finding Islands"); var island_tiles = new TileSelection(); foreach (var t in this.All().tiles) { if (!t.land) { continue; } bool in_region = false; foreach (var region in selection_list) { if (region.Contains(t)) { in_region = true; } } if (!in_region) { island_tiles.Add(t); } } /************************/ Stamp("Seperating Islands"); var island_selections = SeperateContiguous(island_tiles); selection_list.AddRange(island_selections); Color[] colors = new[] { new Color(0.6f, 0.1f, 0.1f), new Color(0, 0.6f, 0), new Color(0, 0, 0.6f), new Color(0.6f, 0.5f, 0), new Color(1, 0, 1), new Color(0, 1, 1), new Color(0.6f, 0.5f, 1), new Color(1, 0.5f, 1), new Color(0, 0.3f, 0.7f), new Color(0.6f, 0.5f, 0.5f), new Color(0.5f, 0, 1), new Color(0, 0.6f, 0.4f) }; /************************/ Stamp("Founding Region Objects"); yield return(new WaitForSeconds(0)); var i = 0; foreach (var region_tiles in selection_list) { i++; i = i % colors.Length; var region = new Region(); this.regions.Add(region); region.color = colors[i]; foreach (var t in region_tiles.tiles) { region.Assign(t); } } for (var splitcount = 0; splitcount < 20; splitcount++) { foreach (var too_big_region in this.regions.FindAll((r) => r.tiles.Count() > max_size)) { /************************/ Stamp("Spliting Region"); yield return(new WaitForSeconds(2)); i++; i = i % colors.Length; var region = new Region(); region.color = colors[i]; this.regions.Add(region); too_big_region.Split(region); _gui_manager.selected_tiles = new TileSelection(); } } _gui_manager.selected_tiles = new TileSelection(); /************************/ Stamp("Merging in Islands"); foreach (var too_small_region in this.regions.FindAll((r) => r.tiles.Count() < min_size)) { yield return(new WaitForSeconds(0)); if (too_small_region.tiles.Count() != 0) { too_small_region.MergeInto(too_small_region.ClosestRegion()); _gui_manager.selected_tiles = too_small_region.tiles; } } _gui_manager.selected_tiles = new TileSelection(); /************************/ Stamp("Removing Edge Regions"); foreach (var region in this.regions) { if (region.tiles.Any((t) => t.adjacent.Count() != 4)) { foreach (var t in region.tiles.ToList()) { t.land = false; t.region = null; } } } /************************/ Stamp("Finished"); yield return(new WaitForSeconds(0)); }
public void Split(Region r, int fraction = 2) { var target = this.tiles.Count() / (float)fraction; var i = 0; var original_fragments = MapGen.SeperateContiguous(this.tiles).Count(); var open = new TileSelection(); var start = tiles.Sample(); open.Add(start); while (r.tiles.Count() < target && open.Count() > 0) { i++; var t = open.Sample(); open.Remove(t); r.Assign(t); if (i % 10 == 1) { JoinCutOffAreas(r, original_fragments); } foreach (var n in t.adjacent.tiles) { if (n.region == this) { if (n.land) { open.Add(n); } } } } this.JoinCutOffAreas(r, original_fragments); var core = r.tiles; //core = MapGen.Shrink(core); var original_core = this.tiles; //original_core = MapGen.Shrink(original_core); var to_switch_back = new TileSelection(); foreach (var t in r.tiles.tiles) { if (core.DoesNotContain(t)) { to_switch_back.Add(t); } } foreach (var t in this.tiles.tiles) { if (original_core.DoesNotContain(t)) { to_switch_back.Add(t); } } Dictionary <Tile, Region> switchMap = new Dictionary <Tile, Region>(); var allowed_regions = new HashSet <Region>(); allowed_regions.Add(r); allowed_regions.Add(this); foreach (var t in to_switch_back.tiles) { t.region = null; r.tiles.Remove(t); TileSelection t_as_list = new TileSelection(); t_as_list.Add(t); try{ switchMap.Add(t, MapGen.ClosestRegion(t_as_list, null, allowed_regions)); }catch (Exception e) { Debug.LogError(e); // Swallow } } foreach (KeyValuePair <Tile, Region> entry in switchMap) { entry.Value.Assign(entry.Key); } r.JoinCutOffAreas(this, 1); this.JoinCutOffAreas(r, original_fragments); }