using System.Collections; using System.Collections.Generic; using UnityEngine; namespace MoreMountains.Tools { /// /// Generates a grid with a path carved by a drunkard walk algorithm that will avoid another grid's walls /// public class MMGridGeneratorRandomWalkAvoider : MMGridGenerator { /// /// Generates a grid with a path carved by a drunkard walk algorithm that will avoid another grid's walls /// /// /// /// /// /// public static int[,] Generate(int width, int height, int seed, int fillPercentage, Vector2Int startingPoint, int[,] obstacles, int obstacleDistance, int maxIterations) { int[,] grid = PrepareGrid(ref width, ref height); grid = MMGridGeneratorFull.Generate(width, height, true); System.Random random = new System.Random(seed); int requiredFillQuantity = ((width * height) * fillPercentage) / 100; int fillCounter = 0; int currentX = startingPoint.x; int currentY = startingPoint.y; grid[currentX, currentY] = 0; fillCounter++; int iterationsCount = 0; while ((fillCounter < requiredFillQuantity) && (iterationsCount < maxIterations)) { int direction = random.Next(4); switch (direction) { case 0: // up if ( ((currentY + 1) <= height) && !ObstacleAt(obstacles, currentX, currentY + obstacleDistance) ) { currentY++; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 1: // down if ( ((currentY - 1) > 1) && !ObstacleAt(obstacles, currentX, currentY - obstacleDistance) ) { currentY--; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 2: // left if (((currentX - 1) > 1) && !ObstacleAt(obstacles, currentX - obstacleDistance, currentY ) ) { currentX--; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 3: // right if (((currentX + 1) <= width) && !ObstacleAt(obstacles, currentX + obstacleDistance, currentY) ) { currentX++; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; } iterationsCount++; } return grid; } /// /// Returns true if an obstacle is found at the specified coordinates, false otherwise /// /// /// /// /// private static bool ObstacleAt(int[,] obstacles, int x, int y) { return (MMGridGenerator.GetValueAtGridCoordinate(obstacles, x, y, 1) == 1); } /// /// /// /// /// /// /// /// private static int[,] Carve(int[,] grid, int x, int y, ref int fillCounter) { if (GetValueAtGridCoordinate(grid, x, y, 0) == 1) { SetGridCoordinate(grid, x, y, 0); fillCounter++; } return grid; } } }