自動マップ生成

アバター
大白定義
記事: 14
登録日時: 14年前
住所: 三重県

自動マップ生成

投稿記事 by 大白定義 » 14年前

いつだったか、Mixcの頃にNNKさんにやってみませんかと言われた自動ダンジョンマップ作成アルゴリズムに挑戦してみることに。

参考にできそうなページなんかがなかったので、脳みそこねくり回して考えてみることに。
そこで、
0、マップの初期化を行う
   0-1、マップのサイズをランダムで決定する
   0-2、マップの領域を取得する
   0-3、マップの全マスの種類を1(壁である)で塗りつぶす
1、マップの分割を行う
   1-1、分割する回数をランダムで決定する
   1-2、分割を行う
2、分割されたそれぞれの部分で四角形の部屋を作る
   2-1、分割された一番右上の座標から、四角形の左上にあたる座標Aをランダムで決定する
   2-2、四角形の右下にあたる座標Bをランダムで決定する
   2-3、AのXY座標以上、BのXY座標以下に当てはまるマスの種類を0(壁ではない)で塗りつぶす
3、部屋同士を通路で結ぶ
   3-1、隣り合っている部屋AとBを選択する
   3-2、AからBへの通路の始点となるX、BからAへの通路の視点となるYをランダムで選択する
   3-3、(AとBが横方向で隣接している場合)X、Yをそれぞれ横に伸ばす
   3-4、XとYのY座標が一致したら、それぞれを縦に伸ばす
という感じの処理をやっていけばいけるんじゃないかなー、と思ったわけです。

で、まずはマップの分割を行う処理を作ってみた。
ただし、処理がまだ未完成(今日はもう弄っている暇がない)ですんで、エラーが発生します。

CODE:

#include 
#include 
#include 

struct field_data{
	int kind;	//マスの種類(壁か、否か等)
	int flag;	//プレイヤーが存在しているかどうか
};

struct map_data{
	struct field_data *field;	//フィールドの領域
	int size;	//サイズ
	int width;	//横幅
	int height;	//縦幅
};

//範囲を限定した乱数を生成する
int getRandomRange(int min, int max){
	return rand() % (max - min) + min;
}

//範囲を限定した、指定した以上の差がある乱数を生成する
int getRandomRangeDiff(int sample, int dif, int min, int max){
	int x;
	do{
		x = getRandomRange(min, max);
		printf("%d - %d = %d\n", sample, x, x-sample);
	}while((x - sample) width / 2;	//縦
	int half_size_hor = map->height / 2;	//横

	int i, j;		//ループ変数
	int buf;	//記憶用

	for(i=0,buf=0; i width - (map->width - buf) / 2;
	}

	for(i=0,buf=0; i height - (map->height - buf) / 2;
	}

	//分割された場所を壁にする
	for(i=0; i size; i++){
		//iと縦の長さの余りがx座標になる
		buf = i % map->height;
		for(j=0; j field[i].kind = 1;
			}
		}

		//iと縦の高さを割った数がy座標になる
		buf = i / map->height;
		for(j=0; j field[i].kind = 1;
			}
		}
	}

	//動的に取得した部分の開放
	free(div_place_ver);
	free(div_place_hor);
}

//フィールドの初期化
void initField(struct map_data *map){
	int i, j;
	for(i=0; i size; i++){
		map->field[i].kind = 0;
		map->field[i].flag = 0;
	}
}

//フィールドの初期化
void drawField(struct map_data *map){
	int i, j;
	for(i=0; i size; i++){
		printf("%2d", map->field[i].kind);
		if(i % map->height == map->height - 1) printf("\n");
	}
}

int main(void){
	//ダンジョンデータの宣言
	struct map_data map;

	//乱数の初期化
	srand((unsigned int)time(NULL));

	//フィールドのサイズを乱数で生成
	map.width  = getRandomRange(20, 30);
	map.height = getRandomRange(20, 30);
	map.size = map.width * map.height;

	//フィールドの領域を取得
	map.field = (struct field_data *)malloc(sizeof(struct field_data) * map.size);

	//フィールドを初期化
	initField(&map);

	setDivision(&map);

	//フィールドを描画
	drawField(&map);

	//フィールドを開放
	free(map.field);

	return 0;
}
見たらわかりますが言語がCです。
いまいちC++はとっつきにくいんですよね。

ちなみに実行結果が以下の通りです
(もちろん毎回結果は変わりますが)

buf:0 half:13
0 - 10 = 10
buf:10 half:19
10 - 14 = 4
buf:14 half:21
14 - 14 = 0
14 - 14 = 0
14 - 15 = 1
14 - 20 = 6
buf:20 half:24
20 - 23 = 3
buf:0 half:11
0 - 0 = 0
0 - 4 = 4
buf:4 half:11
4 - 5 = 1
4 - 4 = 0
4 - 7 = 3
buf:7 half:11
7 - 9 = 2
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
最後に編集したユーザー 大白定義 on 2010年12月17日(金) 23:34 [ 編集 2 回目 ]
理由: 実行結果もつけとこう。

ああ
記事: 49
登録日時: 14年前

Re: 自動マップ生成

投稿記事 by ああ » 14年前

まさかさらっと言った事を実行に移すなんて・・・、行動力に感服です!

これは完成が楽しみ♪

アバター
大白定義
記事: 14
登録日時: 14年前
住所: 三重県

Re: 自動マップ生成

投稿記事 by 大白定義 » 14年前

最近iPhoneでNetHackを始めたんですよね。
そこで、「俺もこういうの作ってみてえ!」とか思っちゃった、というのもちょっと背景にあったりして…。

用事とか放り出して(そこまで重要でもないんで)ソースコード弄り回してたら、
ソースコードにジャイアントスウィングよろしく振り回されて、ほんのりノックダウン気味ですが頑張りますw

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 14年前

Re: 自動マップ生成

投稿記事 by Dixq (管理人) » 14年前

おぉ~♪
私は最初に作ったゲームはRGBだったのですが、当時配列に1つずつマップチップ手打ちだったので、それはそれは大変でした(笑
ゲーム制作時にいかに作成支援ツールを作るかが作業を楽にする鍵になりますよね。

アバター
大白定義
記事: 14
登録日時: 14年前
住所: 三重県

Re: 自動マップ生成

投稿記事 by 大白定義 » 14年前

風来のシレンみたいな、いわゆる不思議なダンジョンのダンジョンを自動で作るプログラムですんで、
作成支援ツールとはちょっと違うかもしれません(説明力が皆無です、すみませんorz)

まぁでも、自動ダンジョン生成ライブラリみたいなので配布すれば役に立ったり…
いや、1次配列を2次的に扱ってたりする時点で論外ですな…^^;