Randomly generate blocks on a flat map

前端 未结 3 1028
一生所求
一生所求 2020-12-04 03:03

I\'m trying to randomly generate blocks on a flat map and make it so that they don\'t overlap each other. I have made a matrix (c# array) of the size of the map (500x500), t

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-04 03:41

    You shouldn't be getting that many collisions.

    Assuming your blocks were ALL 5 units wide and you're trying to fit them into a grid of 500,500 you would have 100*100 spaces for them at minimum, which gives 10,000 spaces into which to fit 1,000 blocks.

    Try playing around with this code:

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main()
            {
                var result = PlaceNonOverlappingBlocks(1000, 5, 500, 500);
            }
    
            static List PlaceNonOverlappingBlocks(int count, int maxBlockSize, int mapX, int mapY)
            {
                var map    = new bool[mapY, mapX];
                var rng    = new Random();
                var result = new List(count);
                int collisions = 0; 
    
                while (count > 0)
                {
                    int size = rng.Next(1, maxBlockSize + 1);
                    int x = rng.Next(0, mapX - size);
                    int y = rng.Next(0, mapY - size);
    
                    if (fits(map, x, y, size))
                    {
                        result.Add(new Block(x, y, size));
                        addToMap(map, x, y, size);
                        --count;
                    }
                    else
                    {
                        if (++collisions> 100000)
                            throw new InvalidOperationException("Hell has frozen over");
                    }
                }
    
                // This is just for diagnostics, and can be removed.
                Console.WriteLine($"There were {collisions} collisions.");
    
                return result;
            }
    
            static void addToMap(bool[,] map, int px, int py, int size)
            {
                for (int x = px; x < px+size; ++x)
                    for (int y = py; y < py + size; ++y)
                        map[y, x] = true;
            }
    
            static bool fits(bool[,] map, int px, int py, int size)
            {
                for (int x = px; x < px + size; ++x)
                    for (int y = py; y < py + size; ++y)
                        if (map[y, x])
                            return false;
    
                return true;
            }
    
            internal class Block
            {
                public int X    { get; }
                public int Y    { get; }
                public int Size { get; }
    
                public Block(int x, int y, int size)
                {
                    X = x;
                    Y = y;
                    Size = size;
                }
            }
        }
    }
    

提交回复
热议问题