C# 如何在C语言中生成不同大小单元的随机泛洪填充#

C# 如何在C语言中生成不同大小单元的随机泛洪填充#,c#,arrays,algorithm,for-loop,C#,Arrays,Algorithm,For Loop,在二维空间中,我需要创建一种特殊的泛洪填充方法,该方法将基于一组预定义对象生成随机数组,如下图中的红色、蓝色、绿色和黄色对象 编辑:任何一个“填充对象”都不应该与另一个重叠,它们的位置应该看起来是随机的,但可以为每个对象添加某种发生的概率。甚至可以放置除红色1x1之外的所有对象,直到达到一定容量,然后用红色填充其余对象 现在想象一个随机结果,如下所示 编辑:我提供的结果图像显示,所有东西总是用红色方块隔开,这当然是可能的,但不是范围的必要部分。我以这种方式绘制图像是为了消除除了红色之外的一些颜

在二维空间中,我需要创建一种特殊的泛洪填充方法,该方法将基于一组预定义对象生成随机数组,如下图中的红色、蓝色、绿色和黄色对象

编辑:任何一个“填充对象”都不应该与另一个重叠,它们的位置应该看起来是随机的,但可以为每个对象添加某种发生的概率。甚至可以放置除红色1x1之外的所有对象,直到达到一定容量,然后用红色填充其余对象

现在想象一个随机结果,如下所示

编辑:我提供的结果图像显示,所有东西总是用红色方块隔开,这当然是可能的,但不是范围的必要部分。我以这种方式绘制图像是为了消除除了红色之外的一些颜色对象被认为与其他类似颜色对象“可接合”的任何概念。换句话说,作为算法的一部分,我不想让人们认为一个3x3的绿色物体可以变成6x3。应将其视为两个单独的3x3,随机相邻放置。为了解决@jdweng注释问题,部分解决方案可能需要向FillObject类添加某种出现概率字段,然后始终将1x1红色方块视为构成空间的对象

这是我到目前为止提出的代码。我很难把这件事想到底。我熟悉标准的泛洪填充,但我不确定如何使用随机大小的“填充对象”

//构成网格填充的已定义对象
公共类对象
{
公共int xDim{get;set;}
公共int yDim{get;set;}
公共字符串颜色{get;set;}
公共FillObject(整数x,整数y,字符串c)
{
xDim=x;
yDim=y;
颜色=c;
}
}
//网格上位置信息的容器
公共类网格位置
{
公共int xPosition{get;set;}
公共int-yPosition{get;set;}
公共字符串颜色{get;set;}
}
公共类网格生成器
{
//声明初始可能的填充对象
公共静态FillObject[]fillObjects=新FillObject[]
{
新的FillObject(1,1,“红色”),
新的FillObject(2,2,“蓝色”),
新的FillObject(3,3,“绿色”),
新的FillObject(4,4,“黄色”)
};
//网格位置的通用列表
公共列表网格=新列表();
//方法生成填充对象的随机网格
public void GenerateGrid(int startX、int startY、int endX、int endY)
{
//迭代网格并根据原始填充对象将每个“单元”设置为颜色

对于(int x=startX;x好的,今天早上我有一个小时的空闲时间,所以我尝试了一下。为了加快速度,我使用了
不安全的
固定的
和指针。我不确定您是否想要图像,但是这也可以用于多维数组

FillObject

public class FillObject
{
   public FillObject(int width, Color color)
   {
      Width = width;
      Color = color.ToArgb();
   }

   public int Color { get; set; }

   public int Width { get; set; }
}
扩展方法

public static class Extensions
{
   public static Color NextColor(this Random r) => Color.FromArgb(r.Next(256), r.Next(256), r.Next(256));

   public static FillObject GetObject(this List<FillObject> objects, int maxSize, Random rand)
   {
      var nextObjs = objects.Where(o => o.Width <= maxSize)
                              .ToList();
      return nextObjs[rand.Next(nextObjs.Count)];
   }
}
测试100x100 5块1填充

测试100x100 5块2填充

测试100x100 10块2填充

测试100x100 b25锁2填充

测试100x100 25块1填充

测试100x100 25块0填充

摘要

好的,前提是

  • x
    然后
    y
  • 确定自由空间
  • 获取适合的对象列表
  • 随便选一个
  • 画出来
但是,如果你使用规格(即随机变量),你会发现有偏差。也就是说,在第一行它可以适合任何它喜欢的东西。但是,后续行它将受到限制,因此它将偏向于较小的块。然后朝远处,它将偏向最小的黑色来填充图像

还有一种偏向于对角线的效果,这基本上只是试图在下一行的随机块中进行拟合的结果

可能会有更多的微优化来加快这一速度,但是它非常好,可以在毫秒内工作

无论如何,我想这是一个很好的起点,你可以加入胡椒和盐来调味


祝你好运

好的,今天早上我有一个小时的空闲时间,所以我尝试了一下。为了加快速度,我使用了
不安全
固定
和指针。我不确定你是否想要图像,但是这也可以用于多维数组

FillObject

public class FillObject
{
   public FillObject(int width, Color color)
   {
      Width = width;
      Color = color.ToArgb();
   }

   public int Color { get; set; }

   public int Width { get; set; }
}
扩展方法

public static class Extensions
{
   public static Color NextColor(this Random r) => Color.FromArgb(r.Next(256), r.Next(256), r.Next(256));

   public static FillObject GetObject(this List<FillObject> objects, int maxSize, Random rand)
   {
      var nextObjs = objects.Where(o => o.Width <= maxSize)
                              .ToList();
      return nextObjs[rand.Next(nextObjs.Count)];
   }
}
测试100x100 5块1填充

测试100x100 5块2填充

测试100x100 10块2填充

测试100x100 b25锁2填充

测试100x100 25块1填充

测试100x100 25块0填充

摘要

好的,前提是

  • x
    然后
    y
  • 确定自由空间
  • 获取适合的对象列表
  • 随便选一个
  • 画出来
但是,如果你使用规格(即随机变量),你会发现有偏差。也就是说,在第一行它可以适合任何它喜欢的东西。但是,后续行它将受到限制,因此它将偏向于较小的块。然后朝远处,它将偏向最小的黑色来填充图像

还有一种偏向于对角线效应,这基本上是j
public static unsafe void Generate(Size size, int* array, int pad)
{
   for (var y = 0 + pad; y < size.Height; y++)
      for (var x = 0 + pad; x < size.Width; x++)
      {
         // no maxSize bail
         if (!GetMaxSize(x, y, size, array, pad, out var maxSize))
            continue;

         // pick a random one
         var nextObj = _objects.GetObject(maxSize, _rand);

         // draw the thing
         for (var y2 = y; y2 < y + nextObj.Width; y2++)
            for (var x2 = x; x2 < x + nextObj.Width; x2++)
               *(array + x2 + y2 * size.Width) = nextObj.Color;

         // start again outside that width
         // remembering the loop will increment this anyway 
         x += nextObj.Width + pad - 1;
      }
}
private static unsafe void Main(string[] args)
{

   _objects = Enumerable.Range(0, 25)
                        .Select((i, i1) => new FillObject(i, _rand.NextColor()))
                        .ToList();

   _largest = _objects.Max(x => x.Width);

   var size = _rand.Next(100, 100);

   using (var bmp = new Bitmap(size, size, PixelFormat.Format32bppPArgb))
   {
      var bitmapData = bmp.LockBits(new Rectangle(0, 0, size, size), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
      var data = (int*)bitmapData.Scan0;
      Generate(new Size(size, size), data, 1);
      bmp.UnlockBits(bitmapData);
      bmp.Save(@"D:\TestImage.bmp");
   }
}