おかしなところを対症療法的に治していったらどんどん複雑な問題になっていきました。
http://racanhack.sourceforge.jp/rhdoc/intromaze.html
ここなどを参考にしました。
敵AIを作る都合上、完成目標は以下の感じなのです。
壁は0、1以上全ては床。それ以外の種類の地形は考えていません。
0000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000
0000222222222200000000000000000000000000000000000000000
0000222222222200000000000000000000000000000000000000000
0000222222222231111111000000000000000000000000000000000
0000222222222200000001000000000066666600000000000000000
0000000000000000000001000000000066666600000000000000000
0000000000000000000001111111111766666600000000000000000
0000000000000000000000000000000066666600000000000000000
0000000000000000000000000000000000070000000000000000000
0000000000000000000000000000000000010000000000000000000
0000000000000000000000000000000000010000000000000000000
0000000000000000000000000000000000010000000000000000000
0000088888800000000000000000000000010000000000000000000
0000088888891111111110000000000000010000000000000000000
0000088888800000000010000000000000050000000000000000000
0000009000000000000010000004444444444400000000000000000
0000001000000000000010000004444444444400000000000000000
0000001000000000000011111154444444444400000000000000000
0000001000000000000000000000000000000000000000000000000
0000001000000000000000000000000000000000000000000000000
0000001000000000000000000000000000000000000000000000000
0000001000000000000000000000000000000000000000000000000
0000001000000000000000000000000000000000000000000000000
...以下略
1.ランダムでエリアを区切って、それぞれのエリア番号に関して、開始のx,yと縦、横を求める。(※いきなりここでつまっています)
2.それぞれのエリアのなかに1つの部屋を作る。(最も端の一マスは全て0)
3.部屋からランダムに1~4本の通路を1でエリアの区切り線まで伸ばす(ただしエリアの区切り線にたどり着かずに、端まで付いてしまう通路は作らない)
4.(4444441444441444)となっているなら(4444441111111444)と変更、(4444444444444444)となっているなら放置、(4444441444444444)となっているなら、
繋げられていない側の部屋から通路を呼び出す。
5.1でないエリアの区切り線を全て消去。
視覚的に表現すると、
1.
0000000000000000000000004000000000000000000
0000000000000000000000004000000000000000000
0000000000000000000000004000000000000000000
0000000000000000000000004000000000000000000
0000000000000000000000004000000000000000000
2222222222222222222222222222222222222222222
0000000000000600000000000000000000000000000
0000000000000600000000000000000000000000000
0000000000000600000000000000000000000000000
0000000000000600000000000000000000000000000
area[0].x=0
area[0].y=0
area[0].yoko=24
area[0].tate=5
area[1]...以下略
2.
0000000000000000000000004000000000000000000
0000022222220000000000004000004444440000000
0000022222220000000000004000004444440000000
0000022222220000000000004000000000000000000
0000000000000000000000004000000000000000000
2222222222222222222222222222222222222222222
0000000000000600000000000000000000000000000
0000066000000608888888800000000000000000000
0000066000000608888888800000000000000000000
0000000000000600000000000000000000000000000
room[0].x=5
room[0].y=1
room[0].yoko=7
room[0].tate=3
3.
↓(例えばこの行は1が一つしかないので4の部屋から通路を呼び出す。)
0000000000000000000000004000000000000000000
0000022222220000000000004000004444440000000
0000022222223111111111111000004444440000000
0000022222220000000000004000000005000000000
0000000003000000000000004000000001000000000
2222212221222222222222122222222221222222222
0000070000000600000000900000000000000000000
0000066000000608888888800000000000000000000
0000066000000198888888800000000000000000000
0000000000000600000000000000000000000000000
4.
0000000000000000000000004000000000000000000
0000022222220000000000001111154444440000000
0000022222223111111111111000004444440000000
0000022222220000000000004000000005000000000
0000000003000000000000004000000001000000000
2222211111111111111111111111111111222222222
0000070000000600000000900000000000000000000
0000066000000608888888800000000000000000000
0000066000000198888888800000000000000000000
0000000000000600000000000000000000000000000
0000000000000000000000000000000000000000000
0000022222220000000000001111154444440000000
0000022222223111111111111000004444440000000
0000022222220000000000000000000005000000000
0000000003000000000000000000000001000000000
0000011111111111111111111111111111000000000
0000070000000000000000900000000000000000000
0000066711111108888888800000000000000000000
0000066000000198888888800000000000000000000
0000000000000000000000000000000000000000000
簡単そうに見える1.で既に僕には意味のわからない問題が起こっています。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
typedef struct{
int x,y;
int tate;
int yoko;
} area_t;
typedef struct{
int x,y;
int tate;
int yoko;
} room_t;
int GetRandom(int min,int max)
{
return min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX));
}
int main(void)
{//min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX));
int i,j,k,l,m,n;int cut;//切る方向。0なら縦、1なら横。
int line=1;int where;//切るとこ
int cut_count;//切る回数
int block[35][55];
int area_select;
int area_select_MAX=0;
area_t area[30];
room_t room[30];
area[0].x=0;
area[0].y=0;
area[0].tate=35;
area[0].yoko=55;
/* 乱数系列の変更 */
srand((unsigned) time(NULL));
for (i=0; i<=34; i++) {
for (j=0; j<=54; j++) {
block[i][j]=0;
}
}
cut_count=GetRandom(2,9);
printf("cut_count:%d\n",cut_count);
for(k=1;k<=cut_count;k++){
do{
cut=GetRandom(0,1);
printf("cut:%d\n",cut);
area_select=GetRandom(0,area_select_MAX);
printf("area_select:%d\n",area_select);
printf("area_select_MAX:%d\n",area_select_MAX);
printf("cut==0 && area[area_select].yoko-5>=4:%d\n",cut==0 && area[area_select].yoko-5>=4);
printf("cut==1 && area[area_select].tate-5>=4:%d\n",cut==1 && area[area_select].tate-5>=4);
}while((cut==0 && area[area_select].yoko-5>=4)==0 && (cut==1 && area[area_select].tate-5>=4)==0);
if(cut==0){//縦
where=GetRandom(5,area[area_select].yoko-5);
printf("where:%d\n",where);
if(area[area_select].y!=0){//このifは意味もわからないまま対症療法的に追加した要素(cut_countが小さい時は上手く成り立つ)
for (i=area[area_select].y-1; i<=area[area_select].y+area[area_select].tate-2; i++) {
block[i][area[area_select].x+where-1]=line;
}
}
if(area[area_select].y==0){
for (i=area[area_select].y; i<=area[area_select].y+area[area_select].tate-1; i++) {
block[i][area[area_select].x+where-1]=line;
}
}
area_select_MAX++;
area[area_select_MAX].x=area[area_select].x+where+1;
area[area_select_MAX].y=area[area_select].y;
area[area_select_MAX].yoko=area[area_select].yoko-where;
area[area_select_MAX].tate=area[area_select].tate;
area[area_select].yoko=where-1;
}
if(cut==1){//横
where=GetRandom(5,area[area_select].tate-5);
printf("where:%d\n",where);
if(area[area_select].x!=0){
for (j=area[area_select].x-1; j<=area[area_select].x+area[area_select].yoko-2; j++) {
block[area[area_select].y+where-1][j]=line;
}
}
if(area[area_select].x==0){
for (j=area[area_select].x; j<=area[area_select].x+area[area_select].yoko-1; j++) {
block[area[area_select].y+where-1][j]=line;
}
}
area_select_MAX++;
area[area_select_MAX].x=area[area_select].x;
area[area_select_MAX].y=area[area_select].y+where+1;
area[area_select_MAX].yoko=area[area_select].yoko;
area[area_select_MAX].tate=area[area_select].tate-where;
area[area_select].tate=where-1;
}
line++;
for(l=0;l<=area_select_MAX;l++){
printf("---------------\n");
printf("area[%d].x:%d\n",l,area[l].x);
printf("area[%d].y:%d\n",l,area[l].y);
printf("area[%d].yoko:%d\n",l,area[l].yoko);
printf("area[%d].tate:%d\n",l,area[l].tate);
printf("---------------\n\n");
}
for (m=0; m<=34; m++) {
for (n=0; n<=54; n++) {
printf("%d",block[m][n]);
}
printf("\n");
}
}
return 0;
}
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003000000000000090000
0000000000000000000000000000000000003444444444444444444
0000000000000000000000000000000000003000000000000000000
0000000000000000000000000000000000003000000000000000000
0000000000000000000000000000000000003000000000000000000
0000000000000000000000000000000000003000000000000000000
2222222222222222222222222222222222222222222222222222222
0000000000000000000000000000500000000000800000000000000
0000000000000000000000000000500000000000800000000000000
0000000000000000000000000000500000000000800000000000000
0000000000000000000000000000500000000000800000000000000
0000000000000000000000000000500000000000800000000000000
0000000000000000000000000000500000000000800000000000000
6666666666666666666666666666500000000000800000000000000
0000000000000000000000000000500000000000800000000000000
0000000000000000000000000000500000000000800000000000000
0000000000000000000000000000500000000000800000000000000
0000000000000000000000000000500000000000000000000000000//8が一個少なかったり
0000000000000000000000000000577777777777777777777777777
7000000000000000000000000000500000000000000000000000000//7が一個多かったり
0000000000000000000000000000500000000000000000000000000
0000000000000000000000000000500000000000000000000000000
0000000000000000000000000000500000000000000000000000000
0000000000000000000000000000500000000000000000000000000
0000000000000000000000000000500000000000000000000000000
0000000000000000000000000000500000000000000000000000000
0000000000000000000000000000500000000000000000000000000
area[9].x=51
area[9].y=0
area[9].yoko=5//一個多い
//そもそも強制終了したり
是非問題点を教えていただけると嬉しいです。