stackprobe7s_memo

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

RPGのフィールドマップらしきものを自動生成する(C#)

単純なアルゴリズムの割に、それなりのマップができる。

2値(海と陸のみ)

MakeLikeAFieldMap()

public static void MakeLikeAFieldMap()
{
	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 * 10; 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] = count / 5;
	}
	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.Turquoise : Color.Sienna);
			}
		}
		bmp.Save(@"C:\temp\LikeAFieldMap.bmp", ImageFormat.Bmp); // 適当な場所にビットマップで出力する。
	}
}

出力例

グラデーションあり

MakeLikeAFieldMap()

public static void MakeLikeAFieldMap()
{
	const int w = 100; // マップの幅
	const int h = 100; // マップの高さ

	Color[] tileColors = new Color[] // 各地形の色
	{
		Color.FromArgb(0, 0, 55), // ここから海?
		Color.FromArgb(20, 20, 105),
		Color.FromArgb(40, 40, 155),
		Color.FromArgb(60, 60, 205),
		Color.FromArgb(80, 80, 255),
		Color.FromArgb(120, 80, 40), // ここから地面?
		Color.FromArgb(150, 100, 50),
		Color.FromArgb(180, 120, 60),
		Color.FromArgb(210, 140, 70),
		Color.FromArgb(240, 160, 80),
		Color.FromArgb(0, 180, 0), // ここから森?
		Color.FromArgb(0, 150, 0),
		Color.FromArgb(0, 120, 0),
		Color.FromArgb(10, 90, 0),
		Color.FromArgb(20, 60, 0),
		Color.FromArgb(40, 30, 0),
	};

	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 * 10; 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] = count / 5;
	}
	for (int x = 0; x < w; x++)
	{
		for (int y = 0; y < h; y++)
		{
			map[x, y] *= tileColors.Length - 1;
		}
	}
	for (int c = 0; c < w * h * 20; c++)
	{
		int x1 = rand.Next(w);
		int x2 = x1;
		int y1 = rand.Next(h);
		int y2 = y1;

		if (rand.Next(2) == 0)
			x2 = (x2 + 1) % w;
		else
			y2 = (y2 + 1) % h;

		if (map[x1, y1] < map[x2, y2])
		{
			map[x1, y1]++;
			map[x2, y2]--;
		}
		else if (map[x2, y2] < map[x1, y1])
		{
			map[x1, y1]--;
			map[x2, y2]++;
		}
	}
	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, tileColors[map[x, y]]);
			}
		}
		bmp.Save(@"C:\temp\LikeAFieldMap.bmp", ImageFormat.Bmp); // 適当な場所にビットマップで出力する。
	}
}

出力例