stackprobe7s_memo

何処にも披露する見込みの無いものを書き落とす場所

RPGのダンジョンマップらしきものを自動生成する(C#)

フィールドマップのときとほとんど同じ。
単純なアルゴリズムの割に、それなりに色々なマップができる。

MakeLikeADungeonMap()

public static void MakeLikeADungeonMap(int pattern) // pattern: 0 ~ 1023
{
	const int w = 100; // マップの幅
	const int h = 100; // マップの高さ

	Random rand = new Random();
	int[,] map = new int[w, h];

	for (int x = 0; x < w; x++)
	{
		for (int y = 0; y < h; y++)
		{
			map[x, y] = rand.Next(2);
		}
	}
	for (int c = 0; c < w * h * 30; c++)
	{
		int x = rand.Next(w);
		int y = rand.Next(h);
		int count = 0;

		for (int xc = -1; xc <= 1; xc++)
		{
			for (int yc = -1; yc <= 1; yc++)
			{
				count += map[(x + w + xc) % w, (y + h + yc) % h];
			}
		}
		map[x, y] = (pattern >> count) & 1;
	}
	using (Bitmap bmp = new Bitmap(w, h))
	{
		for (int x = 0; x < w; x++)
		{
			for (int y = 0; y < h; y++)
			{
				bmp.SetPixel(x, y, map[x, y] == 0 ? Color.Blue : Color.Yellow);
			}
		}
		bmp.Save(@"C:\temp\LikeADungeonMap.bmp", ImageFormat.Bmp); // 適当な場所にビットマップで出力する。
	}
}

全パターンでの出力例

http://stackprobe.ccsp.mydns.jp:58946/_rosetta/Hatena/20191021/table-pattern-0-1023.html

出力例 (ピックアップ)

pattern=24pattern=49pattern=71pattern=82
pattern=139pattern=176pattern=225pattern=226
pattern=432pattern=463pattern=520pattern=783
pattern=808pattern=817pattern=867pattern=936

  • (0,1)の初期配置の1の密度を調節すると変わってくるかもしれないので試してみた。
    • あまり変化無し。
      • たまに変化あるのもある。
      • 奇数の場合、ほとんど変化無し。
        • count = 0 (1が無い3x3の中央) に 1 を置くので密度の濃淡が無くなってしまうのだと思う。多分

左から右にかけて密度が上がって行く

コード

public static void MakeLikeADungeonMap(int pattern) // pattern: -1 ~ 1023
{
	// 左端と右端で密度が違うので左右はループしない。上下はループする。
	// 左右の 100 px は緩衝地帯、後で除去する。

	const int w = 700; // マップの幅
	const int h = 100; // マップの高さ

	Random rand = new Random();
	int[,] map = new int[w, h];

	for (int x = 0; x < w; x++)
	{
		for (int y = 0; y < h; y++)
		{
			map[x, y] = rand.NextDouble() < (x - 100) * 1.0 / (w - 201) ? 1 : 0;
		}
	}
	if (pattern != -1)
	{
		for (int c = 0; c < w * h * 30; c++)
		{
			int x = rand.Next(1, w - 1);
			int y = rand.Next(h);
			int count = 0;

			for (int xc = -1; xc <= 1; xc++)
			{
				for (int yc = -1; yc <= 1; yc++)
				{
					count += map[x + xc, (y + h + yc) % h];
				}
			}
			map[x, y] = (pattern >> count) & 1;
		}
	}
	using (Bitmap bmp = new Bitmap(w - 200, h))
	{
		for (int x = 0; x < w - 200; x++)
		{
			for (int y = 0; y < h; y++)
			{
				bmp.SetPixel(x, y, map[x + 100, y] == 0 ? Color.Blue : Color.Yellow);
			}
		}
		bmp.Save(@"C:\temp\LikeADungeonMap_Gradation.bmp", ImageFormat.Bmp); // 適当な場所にビットマップで出力する。
	}
}

色々な密度で

コード

public static void MakeLikeADungeonMap(int pattern, double rate) // pattern: -1 ~ 1023, rate: 0.0 ~ 1.0
{
	const int w = 100; // マップの幅
	const int h = 100; // マップの高さ

	Random rand = new Random();
	int[,] map = new int[w, h];

	for (int x = 0; x < w; x++)
	{
		for (int y = 0; y < h; y++)
		{
			map[x, y] = rand.NextDouble() < rate ? 1 : 0;
		}
	}
	if (pattern != -1)
	{
		for (int c = 0; c < w * h * 30; c++)
		{
			int x = rand.Next(w);
			int y = rand.Next(h);
			int count = 0;

			for (int xc = -1; xc <= 1; xc++)
			{
				for (int yc = -1; yc <= 1; yc++)
				{
					count += map[(x + w + xc) % w, (y + h + yc) % h];
				}
			}
			map[x, y] = (pattern >> count) & 1;
		}
	}
	using (Bitmap bmp = new Bitmap(w, h))
	{
		for (int x = 0; x < w; x++)
		{
			for (int y = 0; y < h; y++)
			{
				bmp.SetPixel(x, y, map[x, y] == 0 ? Color.Blue : Color.Yellow);
			}
		}
		bmp.Save(@"C:\temp\LikeADungeonMap_Percentage.bmp", ImageFormat.Bmp); // 適当な場所にビットマップで出力する。
	}
}