static void ExpandPath(List <Coord> path, List <MazeLink> links, Random random, int desiredRoomCount, float linkThreshold) { int coordsLeft = desiredRoomCount - path.Count; var directions = new Coord[] { new Coord(0, 1), new Coord(1, 0), new Coord(0, -1), new Coord(-1, 0) }; while (coordsLeft > 0) { Shuffle(directions, random); // note: this random selection is very fast for path sizes of standard use cases, but scales poorly // for very large sizes. If trying to optimize for a non-standard use case with very large paths, // improve the way the branch coord is chosen. Coord branchCoord = path[random.Next(1, path.Count - 1)]; Coord openNeighbour; var neighbours = directions.Select(dir => dir + branchCoord); if (TryGetOpenNeighbour(neighbours, path, out openNeighbour)) { coordsLeft--; var link = new MazeLink(branchCoord, openNeighbour); // Insert into the second last spot, so the last coord doesn't change. path.Insert(path.Count - 1, openNeighbour); links.Add(link); // The new neighbour may be adjacent to existing cells in the maze. We randomly select // those cells and open links to them, with probability based on linkThreshold var coordsAdjacentToOpenNeighbour = directions.Select(dir => dir + openNeighbour) .Where(coord => coord != branchCoord) .Where(coord => coord != path[0] && coord != path[path.Count - 1]) .Where(coord => random.NextDouble() < linkThreshold) .Where(path.Contains); foreach (Coord coordAdjacentToOpenNeighbour in coordsAdjacentToOpenNeighbour) { links.Add(new MazeLink(openNeighbour, coordAdjacentToOpenNeighbour)); } } } }
void Deselect(MazeLink link) { if (selectedLinks.Contains(link)) { selectedLinks.Remove(link); mazeTexture.ColorLink(link, WALL_COLOR); } }
void Select(MazeLink link) { if (!selectedLinks.Contains(link)) { selectedLinks.Add(link); mazeTexture.ColorLink(link, SELECTED_COLOR); // Ensure the link is between linked cells. Select(link.CellA); Select(link.CellB); } }
void ToggleSelectedLink(MazeLink link) { if (selectedLinks.Contains(link)) { Deselect(link); } else { Select(link); } }
public void ColorLink(MazeLink link, Color color) { if (link.IsHorizontal) { Coord cell = new Coord(Math.Max(link.CellA.x, link.CellB.x), link.CellB.y); ColorVerticalBar(cell, color); } else { Coord cell = new Coord(link.CellA.x, Math.Max(link.CellA.y, link.CellB.y)); ColorHorizontalBar(cell, color); } cellsChanged = true; }
public MazeTexture CreateTexture(Maze maze, TagDrawTable tagTable) { if (maze == null) { throw new ArgumentNullException("maze"); } Coord numCells = CalculateCells(maze.GetCells()); var mazeTexture = new MazeTexture(numCells.x, numCells.y); mazeTexture.SetBackgroundColor(BACKGROUND_COLOR); Coord[] cells = maze.GetCells(); Coord bottomLeft = GetBottomLeft(cells); foreach (Coord actualCell in cells) { mazeTexture.ColorCell(actualCell - bottomLeft, CELL_COLOR); } foreach (MazeLink link in maze.GetLinks()) { var shiftedLink = new MazeLink(link.CellA - bottomLeft, link.CellB - bottomLeft); mazeTexture.ColorLink(shiftedLink, CELL_COLOR); } if (tagTable != null) { foreach (CellTag tag in maze.GetTags()) { Coord shiftedCell = tag.Cell - bottomLeft; MetaData metaData = tag.MetaData; foreach (var pair in metaData) { TagDrawer drawer = tagTable[pair.Key]; mazeTexture.ColorTag(shiftedCell, drawer.Coords, drawer.Color); } } } mazeTexture.Apply(); return(mazeTexture); }
MazeLink Flip(MazeLink link) { return(new MazeLink(Flip(link.CellA), Flip(link.CellB))); }
MazeLink RotateCW(MazeLink link, int xMax) { return(new MazeLink(RotateCW(link.CellA, xMax), RotateCW(link.CellB, xMax))); }