/// <summary>
        /// Generates a grid with a path carved by a drunkard walk algorithm
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="seed"></param>
        /// <param name="fillPercentage"></param>
        /// <returns></returns>
        public static int[,] Generate(int width, int height, int seed, int fillPercentage, Vector2Int startingPoint, 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 iterationsCounter = 0;

            while ((fillCounter < requiredFillQuantity) && (iterationsCounter < maxIterations))
            {
                int direction = random.Next(4);

                switch (direction)
                {
                case 0:
                    if ((currentY + 1) < height)
                    {
                        currentY++;
                        grid = Carve(grid, currentX, currentY, ref fillCounter);
                    }
                    break;

                case 1:
                    if ((currentY - 1) > 1)
                    {
                        currentY--;
                        grid = Carve(grid, currentX, currentY, ref fillCounter);
                    }
                    break;

                case 2:
                    if ((currentX - 1) > 1)
                    {
                        currentX--;
                        grid = Carve(grid, currentX, currentY, ref fillCounter);
                    }
                    break;

                case 3:
                    if ((currentX + 1) < width)
                    {
                        currentX++;
                        grid = Carve(grid, currentX, currentY, ref fillCounter);
                    }
                    break;
                }

                iterationsCounter++;
            }
            return(grid);
        }
        /// <summary>
        /// Generates a grid with a path carved by a drunkard walk algorithm that will avoid another grid's walls
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="seed"></param>
        /// <param name="fillPercentage"></param>
        /// <returns></returns>
        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; 
        }
Esempio n. 3
0
        /// <summary>
        /// Generates a simple grid filled with random points
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="seed"></param>
        /// <param name="fillPercentage"></param>
        /// <returns></returns>
        public static int[,] Generate(int width, int height, int seed, int fillPercentage)
        {
            int[,] grid = PrepareGrid(ref width, ref height);

            grid = MMGridGeneratorFull.Generate(width, height, true);
            System.Random random = new System.Random(seed);

            for (int i = 0; i <= width; i++)
            {
                for (int j = 0; j <= height; j++)
                {
                    int value = (random.Next(0, 100) < fillPercentage)? 1: 0;
                    SetGridCoordinate(grid, i, j, value);
                }
            }

            return(grid);
        }
Esempio n. 4
0
        /// <summary>
        /// Generates a layer grid, and renders it
        /// </summary>
        /// <param name="layer"></param>
        protected virtual void GenerateLayer(MMTilemapGeneratorLayer layer)
        {
            if (!layer.Active)
            {
                return;
            }

            if (layer.TargetTilemap == null)
            {
                Debug.LogError("Tilemap Generator : you need to specify a Target Tilemap to paint on.");
            }
            if (layer.Tile == null)
            {
                Debug.LogError("Tilemap Generator : you need to specify a Tile to paint with.");
            }
            if (layer.GridWidth == 0)
            {
                Debug.LogError("Tilemap Generator : grid width can't be 0.");
            }
            if (layer.GridHeight == 0)
            {
                Debug.LogError("Tilemap Generator : grid height can't be 0.");
            }

            float seedFloat       = 0f;
            float layerSeedFloat  = 0f;
            float globalSeedFloat = 0f;


            UnityEngine.Random.InitState(GlobalSeed);
            int width  = layer.OverrideGridSize ? layer.GridWidth : UnityEngine.Random.Range(GridWidth.x, GridWidth.y);
            int height = layer.OverrideGridSize ? layer.GridHeight : UnityEngine.Random.Range(GridHeight.x, GridHeight.y);

            globalSeedFloat = UnityEngine.Random.value;

            // random outside of the global seed
            if (layer.DoNotUseGlobalSeed)
            {
                Random.InitState((int)System.DateTime.Now.Ticks);
                if (layer.RandomizeSeed)
                {
                    layer.Seed = Mathf.Abs(Random.Range(int.MinValue, int.MaxValue));
                }
                UnityEngine.Random.InitState(layer.Seed);
                layerSeedFloat = UnityEngine.Random.value;
            }

            int seed = layer.DoNotUseGlobalSeed ? layer.Seed : GlobalSeed;

            seedFloat = layer.DoNotUseGlobalSeed ? layerSeedFloat : globalSeedFloat;

            switch (layer.GenerateMethod)
            {
            case GenerateMethods.Full:
                _grid      = MMGridGeneratorFull.Generate(width, height, layer.FullGenerationFilled);
                layer.Grid = _grid;
                break;

            case GenerateMethods.Perlin:
                _grid      = MMGridGeneratorPerlinNoise.Generate(width, height, seedFloat);
                layer.Grid = _grid;
                break;

            case GenerateMethods.PerlinGround:
                _grid      = MMGridGeneratorPerlinNoiseGround.Generate(width, height, seedFloat);
                layer.Grid = _grid;
                break;

            case GenerateMethods.Random:
                _grid      = MMGridGeneratorRandom.Generate(width, height, seed, layer.RandomFillPercentage);
                layer.Grid = _grid;
                break;

            case GenerateMethods.RandomWalk:
                _grid      = MMGridGeneratorRandomWalk.Generate(width, height, seed, layer.RandomWalkPercent, layer.RandomWalkStartingPoint, layer.RandomWalkMaxIterations);
                layer.Grid = _grid;
                break;

            case GenerateMethods.RandomWalkAvoider:

                int[,] obstacleGrid = MMGridGenerator.TilemapToGrid(layer.RandomWalkAvoiderObstaclesTilemap, width, height);
                _grid      = MMGridGeneratorRandomWalkAvoider.Generate(width, height, seed, layer.RandomWalkAvoiderPercent, layer.RandomWalkAvoiderStartingPoint, obstacleGrid, layer.RandomWalkAvoiderObstaclesDistance, layer.RandomWalkAvoiderMaxIterations);
                layer.Grid = _grid;
                break;

            case GenerateMethods.RandomWalkGround:
                _grid = MMGridGeneratorRandomWalkGround.Generate(width, height, seed,
                                                                 layer.RandomWalkGroundMinHeightDifference, layer.RandomWalkGroundMaxHeightDifference,
                                                                 layer.RandomWalkGroundMinFlatDistance, layer.RandomWalkGroundMaxFlatDistance, layer.RandomWalkGroundMaxHeight);
                layer.Grid = _grid;
                break;

            case GenerateMethods.Path:
                _grid = MMGridGeneratorPath.Generate(width, height, seed, layer.PathDirection, layer.PathStartPosition, layer.PathMinWidth,
                                                     layer.PathMaxWidth, layer.PathDirectionChangeDistance, layer.PathWidthChangePercentage,
                                                     layer.PathDirectionChangePercentage);
                layer.Grid = _grid;
                break;

            case GenerateMethods.Copy:
                layer.TargetTilemap.ClearAllTiles();
                DelayedCopy(layer);
                break;
            }

            if (layer.Smooth)
            {
                _grid = MMGridGenerator.SmoothenGrid(_grid);
            }
            if (layer.InvertGrid)
            {
                _grid = MMGridGenerator.InvertGrid(_grid);
            }

            _grid = MMGridGenerator.BindGrid(_grid, layer.BoundsTop, layer.BoundsBottom, layer.BoundsLeft, layer.BoundsRight);
            _grid = MMGridGenerator.ApplySafeSpots(_grid, layer.SafeSpots);

            RenderGrid(layer);
        }
        /// <summary>
        /// Generates a grid with a path in the specified direction
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="seed"></param>
        /// <param name="direction"></param>
        /// <param name="startPosition"></param>
        /// <param name="pathMinWidth"></param>
        /// <param name="pathMaxWidth"></param>
        /// <param name="directionChangeDistance"></param>
        /// <param name="widthChangePercentage"></param>
        /// <param name="directionChangePercentage"></param>
        /// <returns></returns>
        public static int[,] Generate(int width, int height, int seed, Directions direction, Vector2Int startPosition, int pathMinWidth, int pathMaxWidth, int directionChangeDistance, int widthChangePercentage, int directionChangePercentage)
        {
            int[,] grid = PrepareGrid(ref width, ref height);
            grid        = MMGridGeneratorFull.Generate(width, height, true);
            System.Random random = new System.Random(seed);
            Random.InitState(seed);

            int pathWidth = 1;
            int initialX  = startPosition.x;
            int initialY  = startPosition.y;

            SetGridCoordinate(grid, initialX, initialY, 0);

            switch (direction)
            {
            case Directions.TopToBottom:
                int x1 = initialX;
                for (int i = -pathWidth; i <= pathWidth; i++)
                {
                    SetGridCoordinate(grid, x1 + i, initialY, 0);
                }
                for (int y = initialY; y > 0; y--)
                {
                    pathWidth = ComputeWidth(random, widthChangePercentage, pathMinWidth, pathMaxWidth, pathWidth);
                    x1        = DetermineNextStep(random, x1, directionChangeDistance, directionChangePercentage, pathMaxWidth, width);
                    for (int i = -pathWidth; i <= pathWidth; i++)
                    {
                        SetGridCoordinate(grid, x1 + i, y, 0);
                    }
                }
                break;

            case Directions.BottomToTop:
                int x2 = initialX;
                for (int i = -pathWidth; i <= pathWidth; i++)
                {
                    SetGridCoordinate(grid, x2 + i, initialY, 0);
                }
                for (int y = initialY; y < height; y++)
                {
                    pathWidth = ComputeWidth(random, widthChangePercentage, pathMinWidth, pathMaxWidth, pathWidth);
                    x2        = DetermineNextStep(random, x2, directionChangeDistance, directionChangePercentage, pathMaxWidth, width);
                    for (int i = -pathWidth; i <= pathWidth; i++)
                    {
                        SetGridCoordinate(grid, x2 + i, y, 0);
                    }
                }
                break;

            case Directions.LeftToRight:
                int y1 = initialY;
                for (int i = -pathWidth; i <= pathWidth; i++)
                {
                    SetGridCoordinate(grid, initialX, y1 + i, 0);
                }
                for (int x = initialX; x < width; x++)
                {
                    pathWidth = ComputeWidth(random, widthChangePercentage, pathMinWidth, pathMaxWidth, pathWidth);
                    y1        = DetermineNextStep(random, y1, directionChangeDistance, directionChangePercentage, pathMaxWidth, width);
                    for (int i = -pathWidth; i <= pathWidth; i++)
                    {
                        SetGridCoordinate(grid, x, y1 + i, 0);
                    }
                }
                break;

            case Directions.RightToLeft:
                int y2 = initialY;
                for (int i = -pathWidth; i <= pathWidth; i++)
                {
                    SetGridCoordinate(grid, initialX, y2 + i, 0);
                }
                for (int x = initialX; x > 0; x--)
                {
                    pathWidth = ComputeWidth(random, widthChangePercentage, pathMinWidth, pathMaxWidth, pathWidth);
                    y2        = DetermineNextStep(random, y2, directionChangeDistance, directionChangePercentage, pathMaxWidth, width);
                    for (int i = -pathWidth; i <= pathWidth; i++)
                    {
                        SetGridCoordinate(grid, x, y2 + i, 0);
                    }
                }
                break;
            }
            return(grid);
        }