public void NewSelectedRegion() { Region newRegion = new Region(); foreach (Tile tile in selectedTiles) { newRegion.AddTile(tile); if (tile.Region != null) { tile.Region.RemoveTile(tile); } tile.Region = newRegion; } selectedTiles.Clear(); }
/// <summary> /// This function is the maze generation. We use a simple growing tree /// algorithm to build our maze. This works with a few steps: /// 1) Pick a starting cell and add it to our list /// 2) while we have cells to pick /// 3) pick a random cell /// 4) pick a random unvisted neighbor /// 5) add the neighbor to the list /// 6) if no neighbors exist remove the cell from the list /// /// We then repeat this until all our cells are either visited /// or surrounded by visted cells. /// </summary> private void GeneratePaths() { for (int y = 1; y < MapSize.y; y += 2) { for (int x = 1; x < MapSize.x; x += 2) { Tile start = GetTile(x, y); if (start.IsFloor() || IsBorderTile(start)) { continue; } Stack <Tile> unvisited = new Stack <Tile>(); unvisited.Push(start); Region currentRegion = new Region(); // take a cell out of the list // carve a random cell next to it // add that cell to the list while (unvisited.Count > 0) { Tile currentTile = unvisited.Peek(); currentTile.Type = ETileType.FLOOR; currentRegion.AddTile(currentTile); Tile nextTile = CarveTile(currentTile); if (nextTile == null) { unvisited.Pop(); lastDirection = ETileDirection.NONE; } else { unvisited.Push(nextTile); } } Regions.Add(currentRegion); } } }
// use floodfill to detect regions private List <Region> DetectRegions(int[,] newMap, int size) { // count will indicate regions. each region will have it's own number int currentRegionID = startingRegionsID; //int[,] newMap = oldMap; List <Region> regions = new List <Region>(); // can ignore first and last rows/columns because they're set to always be walls // this numbering system is bad / inconstent. change 1 to unfilled, 0 to filled. for (int y = 1; y < size - 1; y++) { for (int x = 1; x < size - 1; x++) { if (newMap[y, x] == filled) { // ignore it, it's a wall } else if (newMap[y, x] == empty) // if it's not already marked as a new region { // floodfill to create a new region Vector2i currentPoint = new Vector2i(x, y); Queue <Vector2i> cellsToCheck = new Queue <Vector2i>(); cellsToCheck.Enqueue(currentPoint); Region newRegion = new Region(); while (cellsToCheck.Count > 0) { // get the first point currentPoint = cellsToCheck.Dequeue(); // if the dequeued point isn't part of this region if (newMap[currentPoint.y, currentPoint.x] != currentRegionID) { // add the point to the region newMap[currentPoint.y, currentPoint.x] = currentRegionID; // if it's an edge cell if (newMap[currentPoint.y + 1, currentPoint.x] == filled || newMap[currentPoint.y - 1, currentPoint.x] == filled || newMap[currentPoint.y, currentPoint.x + 1] == filled || newMap[currentPoint.y, currentPoint.x - 1] == filled) { newRegion.AddTile(currentPoint, true); } else { newRegion.AddTile(currentPoint, false); } // because the border is always set to be walls, we don't need to worry about out of bounds errors if (newMap[currentPoint.y, currentPoint.x + 1] == empty) { cellsToCheck.Enqueue(new Vector2i(currentPoint.x + 1, currentPoint.y)); } if (newMap[currentPoint.y, currentPoint.x - 1] == empty) { cellsToCheck.Enqueue(new Vector2i(currentPoint.x - 1, currentPoint.y)); } if (newMap[currentPoint.y + 1, currentPoint.x] == empty) { cellsToCheck.Enqueue(new Vector2i(currentPoint.x, currentPoint.y + 1)); } if (newMap[currentPoint.y - 1, currentPoint.x] == empty) { cellsToCheck.Enqueue(new Vector2i(currentPoint.x, currentPoint.y - 1)); } } } regions.Add(newRegion); currentRegionID++; } } } return(regions); }