private int SortByDistance(TerritoryPoint x, TerritoryPoint y) { float dist = x.Distance; float dist2 = y.Distance; if (dist < dist2) { return(-1); } if (dist > dist2) { return(1); } return(0); }
private void AddPointToRegion(TerritoryPoint newPoint) { int xx = newPoint.Position.X / RegionGridSize; int yy = newPoint.Position.Y / RegionGridSize; List <TerritoryPoint> list = null; if (!Regions.ContainsKey(new Point(xx, yy))) { list = new List <TerritoryPoint>(); Regions[new Point(xx, yy)] = list; } else { list = Regions[new Point(xx, yy)]; } list.Add(newPoint); }
private void CreateProvinces(int numProvinces, Color testColor, List <Point> pts, int w, int h, LockBitmap provinces, bool bSea) { Regions.Clear(); int numPoints = numProvinces * 50; if (bSea) { numPoints = numProvinces * 50; } #region GenerateRandomPoints var points = new List <TerritoryPoint>(); var usePts = new HashSet <Point>(pts); List <Vector2f> vpoints = new List <Vector2f>(); HashSet <Point> done = new HashSet <Point>(); // int numSeaPoints = numPoints / 140; int numSeaPoints = numPoints / 340; for (int n = 0; n < numPoints; n++) { Point newPoint = Point.Empty; bool duplicate = true; { int nn = Rand.Next(pts.Count); newPoint = pts[nn]; // pts.RemoveAt(nn); /* * foreach (TerritoryPoint p in points) * if (p.Position.X == newPoint.Position.X && p.Position.Y == newPoint.Position.Y) * { * duplicate = true; * break; * }*/ } { vpoints.Add(new Vector2f(newPoint.X, newPoint.Y)); } } points.Clear(); int vorStrength = 0; if (pts.Count > 150) { vorStrength += 2; } Voronoi v = new Voronoi(vpoints, new Rectf(0, 0, w, h), 0); var coords = v.SiteCoords(); coords = coords.Where(c => usePts.Contains(new Point((int)c.x, (int)c.y))).ToList(); for (int n = 0; n < coords.Count; n++) { TerritoryPoint newPoint = null; bool duplicate = true; newPoint = new TerritoryPoint((int)coords[n].x, (int)coords[n].y); if (newPoint != null) { points.Add(newPoint); } } #endregion if (points.Count == 0) { points.Add(new TerritoryPoint() { Position = usePts.OrderBy(o => Rand.Next(1000000)).First() }); } #region GenerateTerritories var colours = new List <Color>(); var origPoints = new List <TerritoryPoint>(points); for (int n = 0; n < numProvinces; n++) { TerritoryPoint initialPoint = null; int i = 0;//rand.Next(points.Count()); while (initialPoint == null) { i = Rand.Next(origPoints.Count()); initialPoint = origPoints[i]; if (initialPoint.Owner != -1) { initialPoint = null; } else { i = points.IndexOf(initialPoint); } } bool requireSea = false; if (initialPoint.Sea) { requireSea = true; } foreach (TerritoryPoint p in points) { int dx = p.Position.X - initialPoint.Position.X; int dy = p.Position.Y - initialPoint.Position.Y; p.Distance = (float)Math.Sqrt(dx * dx + dy * dy); } points.Sort(SortByDistance); int c = 0; for (c = 0; c < Math.Min(maxPointsPerTerritory, points.Count); c++) { if (points[c].Owner != -1) { break; } } int owner = n + totalGeneratedProvinces; while ((colorMap[owner + 1].G == 0 && colorMap[owner + 1].B == 0) || colorMap[owner + 1] == Color.FromArgb(255, 69, 91, 186) || colorMap[owner + 1] == Color.FromArgb(255, 130, 158, 75) || colorProvinceMap.ContainsKey(colorMap[owner + 1])) { owner = n + (++totalGeneratedProvinces); } // if (c >= minPointsPerTerritory)// || i >= seaStart) { for (int c2 = 0; c2 < c; c2++) { if (points[c2].Owner == -1) { points[c2].Owner = owner; origPoints.Remove(points[c2]); AddPointToRegion(points[c2]); } } } totalGeneratedProvinces++; } #endregion #region GenerateBitmap foreach (var point in usePts) { int x = point.X; int y = point.Y; float minDist = 1000000000; TerritoryPoint closest = null; List <TerritoryPoint> list = new List <TerritoryPoint>(); bool found = false; int range = 1; while (!found) { for (int xx = -range; xx <= range; xx++) { for (int yy = -range; yy <= range; yy++) { int gx = x / RegionGridSize; int gy = y / RegionGridSize; int tx = xx + gx; int ty = yy + gy; if (Regions.ContainsKey(new Point(tx, ty))) { var l = Regions[new Point(tx, ty)]; list.AddRange(l.Where(p => p.Owner != -1)); } } } if (list.Count > 1) { break; } range++; } foreach (TerritoryPoint p in list) { int dx = p.Position.X - x; int dy = p.Position.Y - y; p.Distance = (float)Math.Sqrt(dx * dx + dy * dy); if (p.Owner != -1 && p.Distance < minDist) { closest = p; minDist = p.Distance; } } if (closest.Owner != -1) { var col = colorMap[closest.Owner + 1]; if (!colorProvinceMap.ContainsKey(col)) { var p = new Province(); p.Color = col; p.isSea = bSea; colorProvinceMap[col] = p; this.provinces.Add(p); } colorProvinceMap[col].points.Add(new Point(x, y)); provinces.SetPixel(x, y, col); } } if (!bSea) { List <Point> choices = new List <Point>(); var pt = usePts.OrderBy(o => Rand.Next(10000000)); for (int nn = 0; nn < 2; nn++) { foreach (var point in pt) { int x = point.X; int y = point.Y; Color use = provinces.GetPixel(x, y); choices.Clear(); for (int xx = -1; xx <= 1; xx++) { for (int yy = -1; yy <= 1; yy++) { if (xx == 0 && yy == 0) { continue; } Color test = provinces.GetPixel(x + xx, y + yy); var p = new Point(x + xx, y + yy); if (test != use) { if (usePts.Contains(p)) { choices.Add(p); } } } } if (choices.Count == 1) { Point p = choices[Rand.Next(choices.Count)]; colorProvinceMap[provinces.GetPixel(p.X, p.Y)].points.Remove(p); provinces.SetPixel(p.X, p.Y, use); colorProvinceMap[use].points.Add(p); } } } List <Color> choicesc = new List <Color>(); foreach (var point in pt) { int x = point.X; int y = point.Y; Color use = provinces.GetPixel(x, y); choicesc.Clear(); for (int xx = -1; xx <= 1; xx++) { for (int yy = -1; yy <= 1; yy++) { if (xx == 0 && yy == 0) { continue; } Color test = provinces.GetPixel(x + xx, y + yy); var p = new Point(x + xx, y + yy); if (test != use) { if (usePts.Contains(p)) { choicesc.Add(test); } } } } if (choices.Count >= 7) { Color p = choicesc[Rand.Next(choicesc.Count)]; colorProvinceMap[provinces.GetPixel(x, y)].points.Remove(new Point(x, y)); provinces.SetPixel(x, y, p); colorProvinceMap[p].points.Add(new Point(x, y)); } } } #endregion }
public void Generate(int numTerritories = 1500) { this.numTerritories = numTerritories; numPoints = numTerritories * 50; #region GenerateRandomPoints this.generatedMap.TerrainMap.LockBits(); ProvinceMap.LockBits(); points = new List <TerritoryPoint>(); int tot = (int)(((Width / RegionGridSize) * 0.4190996) * ((Height / RegionGridSize) * 0.4190996)); List <Vector2f> vpoints = new List <Vector2f>(); HashSet <Point> done = new HashSet <Point>(); // int numSeaPoints = numPoints / 140; int numSeaPoints = numPoints / 340; int seaStart = numPoints - numSeaPoints; for (int n = 0; n < numPoints - numSeaPoints; n++) { TerritoryPoint newPoint = null; bool duplicate = true; while (duplicate) { duplicate = false; do { newPoint = new TerritoryPoint(Rand.Next(Width), Rand.Next(Height)); } while (done.Contains(newPoint.Position)); if (generatedMap.TerrainMap.GetPixel(newPoint.Position.X, newPoint.Position.Y) == Color.FromArgb(255, 69, 91, 186)) { duplicate = true; continue; } done.Add(newPoint.Position); /* * foreach (TerritoryPoint p in points) * if (p.Position.X == newPoint.Position.X && p.Position.Y == newPoint.Position.Y) * { * duplicate = true; * break; * }*/ } if (newPoint != null) { vpoints.Add(new Vector2f(newPoint.Position.X, newPoint.Position.Y)); points.Add(newPoint); } } points.Clear(); Voronoi v = new Voronoi(vpoints, new Rectf(0, 0, Width, Height), 32); var coords = v.SiteCoords(); coords = coords.Where(c => generatedMap.TerrainMap.GetPixel((int)c.x, (int)c.y) != Color.FromArgb(255, 69, 91, 186)).ToList(); for (int n = 0; n < coords.Count; n++) { TerritoryPoint newPoint = null; bool duplicate = true; newPoint = new TerritoryPoint((int)coords[n].x, (int)coords[n].y); if (newPoint != null) { points.Add(newPoint); int xx = newPoint.Position.X / RegionGridSize; int yy = newPoint.Position.Y / RegionGridSize; List <TerritoryPoint> list = null; if (!Regions.ContainsKey(new Point(xx, yy))) { list = new List <TerritoryPoint>(); Regions[new Point(xx, yy)] = list; } else { list = Regions[new Point(xx, yy)]; } newPoint.Sea = false; list.Add(newPoint); } } #endregion #region GenerateTerritories List <TerritoryPoint> assigned = new List <TerritoryPoint>(); List <TerritoryPoint> unassigned = new List <TerritoryPoint>(); colours = new List <Color>(); var origPoints = new List <TerritoryPoint>(points); for (int n = 0; n < numTerritories; n++) { TerritoryPoint initialPoint = null; int i = 0;//rand.Next(points.Count()); while (initialPoint == null) { i = Rand.Next(origPoints.Count()); initialPoint = origPoints[i]; if (initialPoint.Owner != -1) { initialPoint = null; } else { i = points.IndexOf(initialPoint); } } bool requireSea = false; if (initialPoint.Sea) { requireSea = true; } foreach (TerritoryPoint p in points) { int dx = p.Position.X - initialPoint.Position.X; int dy = p.Position.Y - initialPoint.Position.Y; p.Distance = (float)Math.Sqrt(dx * dx + dy * dy); } points.Sort(SortByDistance); int c = 0; if (i >= seaStart) { c = 1; } else { for (c = 0; c < maxPointsPerTerritory; c++) { if (points[c].Owner != -1) { break; } } } if (c >= minPointsPerTerritory || i >= seaStart) { for (int c2 = 0; c2 < c; c2++) { if (points[c2].Owner == -1) { points[c2].Owner = n; origPoints.Remove(points[c2]); } } } else { n--; } } #endregion #region GenerateBitmap int[] provinceSize = new int[numTerritories + 100]; Color[] provinceColor = new Color[numTerritories + 100]; for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { float minDist = 1000000000; TerritoryPoint closest = null; if (generatedMap.TerrainMap.GetPixel(x, y) == Color.FromArgb(255, 69, 91, 186)) { ProvinceMap.SetPixel(x, y, Color.White); continue; } List <TerritoryPoint> list = new List <TerritoryPoint>(); bool found = false; int range = 1; while (!found) { for (int xx = -range; xx <= range; xx++) { for (int yy = -range; yy <= range; yy++) { int gx = x / RegionGridSize; int gy = y / RegionGridSize; int tx = xx + gx; int ty = yy + gy; if (Regions.ContainsKey(new Point(tx, ty))) { var l = Regions[new Point(tx, ty)]; list.AddRange(l.Where(p => p.Owner != -1)); } } } if (list.Count > 1) { break; } range++; } foreach (TerritoryPoint p in list) { int dx = p.Position.X - x; int dy = p.Position.Y - y; p.Distance = (float)Math.Sqrt(dx * dx + dy * dy); if (p.Owner != -1 && p.Distance < minDist) { closest = p; minDist = p.Distance; } } if (closest.Owner != -1) { provinceSize[closest.Owner]++; var col = colorMap[closest.Owner + 1]; ProvinceMap.SetPixel(x, y, col); } } } ProvinceMap.UnlockBits(); ProvinceMap.Save24(Globals.MapOutputTotalDir + "map\\provincestest.bmp"); #endregion }