private bool MarkProvinceCell(int x, int y, int provinceId, int[,] tileMap, List <IntIntPair> neighbors, bool useStricterRules) { if (tileMap[x, y] > 0 || tileMap[x, y] == provinceId) { return(false); } tileMap[x, y] = provinceId; HexBorder[] borders = HexBorder.GetBorderDirections(x % 2 == 1); for (int i = 0; i < borders.Length; i++) { int neighborX = x + borders[i].GetDeltaX(); int neighborY = y + borders[i].GetDeltaY(); IntIntPair neighbor = new IntIntPair(neighborX, neighborY); bool passesBasicRules = IsInnerCell(neighborX, neighborY, tileMap) && tileMap[neighborX, neighborY] <= 0; // stricter rules means having at least two neighboring cells // belonging to the same province // it's used to avoid serpentine forms bool passesStricterRules = false; if (useStricterRules) { int sameProvinceNeighbors = 0; HexBorder[] newBorders = HexBorder.GetBorderDirections(neighborX % 2 == 1); for (int j = 0; j < newBorders.Length; j++) { int xx = neighborX + newBorders[j].GetDeltaX(); int yy = neighborY + newBorders[j].GetDeltaY(); if (IsInnerCell(xx, yy, tileMap) && tileMap[xx, yy] == provinceId) { sameProvinceNeighbors++; if (sameProvinceNeighbors >= 2) { passesStricterRules = true; break; } } } } // is within the map area, is a water cell, and either doesn't care // about stricter rules or satisfies them if (passesBasicRules && (!useStricterRules || passesStricterRules)) { neighbors.Add(neighbor); } } return(true); }
private bool SearchForNeighbors(int x, int y, bool updateDistances) { bool foundNeighboringProvince = false; HexBorder[] borders = HexBorder.GetBorderDirections(x % 2 == 1); for (int i = 0; i < borders.Length; i++) { int neighborX = x + borders[i].GetDeltaX(); int neighborY = y + borders[i].GetDeltaY(); if (IsInnerCell(neighborX, neighborY, _cellMap) && _cellMap[neighborX, neighborY] > 0 && _cellMap[x, y] != _cellMap[neighborX, neighborY]) { MarkNeighboringProvinces(_cellMap[x, y], _cellMap[neighborX, neighborY], updateDistances); foundNeighboringProvince = true; } } return(foundNeighboringProvince); }
/// <summary> /// Establish a relation with a neighboring map cell /// </summary> /// <param name="neighbor">Neighboring map cell</param> /// <param name="deltaX">X coordinate offset to the neighbor</param> /// <param name="deltaY">Y coordinate offset to the neighbor</param> public void SetNeighbor(MapCell neighbor, int deltaX, int deltaY) { if (neighbor != null) { int borderIndex = HexBorder.ConvertDeltaToBorderIndex(deltaX, deltaY, _data.x % 2 == 1); if (neighbor.GetProvinceId() == GetProvinceId()) { // if the neighboring map cell belongs to the same province, // there should be no border between them, so // set the corresponding bit to zero int index = 1 << borderIndex; _provinceBordersIndex = _provinceBordersIndex ^ index; } else { _province.AddNeighbor(neighbor.GetProvince()); neighbor.GetProvince().AddNeighbor(_province); } } }
private void DryLake(int x, int y) { List <int> provinceIds = new List <int>(); HexBorder[] borders = HexBorder.GetBorderDirections(x % 2 == 1); for (int i = 0; i < borders.Length; i++) { int neighborX = x + borders[i].GetDeltaX(); int neighborY = y + borders[i].GetDeltaY(); if (neighborX > 0 && neighborX < _cellMap.GetLength(0) && neighborY > 0 && neighborY < _cellMap.GetLength(1) && _cellMap[neighborX, neighborY] > 0) { provinceIds.Add(_cellMap[neighborX, neighborY]); } } int randomIndex = UnityEngine.Random.Range(0, provinceIds.Count - 1); _cellMap[x, y] = provinceIds[randomIndex]; }
/// <summary> /// Set up map cells /// Depends on provinces being set up /// </summary> private void SetUpMapCells() { Dictionary <Province, List <MapCell> > provinceCells = new Dictionary <Province, List <MapCell> >(); _cells = new Dictionary <int, Dictionary <int, MapCell> >(); for (int i = 0; i < _data.cells.Length; i++) { Province province = GetProvince(_data.cells[i].provinceId); if (province != null) { int x = _data.cells[i].x; int y = _data.cells[i].y; if (!_cells.ContainsKey(x)) { _cells[x] = new Dictionary <int, MapCell>(); } MapCell newCell = new MapCell(_data.cells[i], province); // set up cell's neighbors HexBorder[] borders = HexBorder.GetBorderDirections(x % 2 == 1); for (int j = 0; j < borders.Length; j++) { int deltaX = borders[j].GetDeltaX(); int deltaY = borders[j].GetDeltaY(); MapCell neighbor = GetCellAt(x + deltaX, y + deltaY); if (neighbor != null) { newCell.SetNeighbor(neighbor, deltaX, deltaY); neighbor.SetNeighbor(newCell, -deltaX, -deltaY); } } _cells[x][y] = newCell; _maxX = UnityEngine.Mathf.Max(x, _maxX); _maxY = UnityEngine.Mathf.Max(y, _maxY); if (newCell.IsCenterOfProvince()) { province.SetCenterMapCell(newCell); } if (!provinceCells.ContainsKey(province)) { provinceCells[province] = new List <MapCell>(); } provinceCells[province].Add(newCell); } } List <Province> provinces = new List <Province>(provinceCells.Keys); for (int i = 0; i < provinces.Count; i++) { Province province = provinces[i]; double sumX = 0; double sumY = 0; List <MapCell> cells = provinceCells[province]; for (int j = 0; j < cells.Count; j++) { sumX += cells[j].GetX(); sumY += cells[j].GetY(); } double avgX = sumX / cells.Count; double avgY = sumY / cells.Count; int index = -1; double minDeltaSquared = Double.MaxValue; for (int j = 0; j < cells.Count; j++) { double deltaSquared = (cells[j].GetX() - avgX) * (cells[j].GetX() - avgX) + (cells[j].GetY() - avgY) * (cells[j].GetY() - avgY); if (deltaSquared < minDeltaSquared) { index = j; minDeltaSquared = deltaSquared; } } if (index >= 0) { province.SetCenterMapCell(cells[index]); } } }