迷路生成アルゴリズムのソース

このエントリーをはてなブックマークに追加
1名無しさん@お腹いっぱい。
迷路を生成のアルゴリズムのサンプルコードどこかにないですか?

迷路生成アルゴリズムといっても色々あるかもしれませんが
知らないのでなんでもいいです。
言語もなんでもいいです。とにかく見たいです。

NetHack、Angband、Omega、ローグクローンのソースなんかも
見てみましたがいまいちです。
一本道の迷路じゃなくて部屋で区切られているというのが邪魔しているのかも、、、
お願いします。
2名無しさん@お腹いっぱい。 :2000/09/02(土) 22:48
xmaze を忘れていないか?
3名無しさん@お腹いっぱい。 :2000/09/02(土) 23:21
昔、ファンダムに面白いのが載ってたなあ。
4名無しさん@お腹いっぱい。 :2000/09/02(土) 23:29
ソースが迷路なものはいっぱい有るぞ。
51 :2000/09/03(日) 00:48
>2
ftp://ftp.scn.rain.com/pub/games/xmazewar.tar.Z
これですかーと思ったらコンパイルできない。
Xのバージョンが新しいのかな。
61 :2000/09/03(日) 01:02
ややりました!!
http://ring.etl.go.jp/archives/X/opengroup/unsupported/programs/maze/
ここです。
xmkmfは成功するけどmakeで失敗します。(VineLinux 2.0CR)
独自にgetoptを作っているのが原因なのでImakefileの真ん中辺りを
#else
SRCS = maze.c
OBJS = maze.o
#endif
とすればmake出来ますやった!
71 :2000/09/03(日) 01:15
今、globalでHTML化して読んでます。

initialize_mazeは外壁とか出入り口を作ります。
create_mazeで迷路本体を作ります。
choose_doorは壁を作る方向を決めるのかな????
8名無しさん@お腹いっぱい。 :2000/09/03(日) 02:29
壁や通路じゃなくてさ、三次元のグニャグニャのチューブみたいな
迷路の作成考えてよ。
91 :2000/09/03(日) 02:41
>8
三次元の基礎さえ知りません。
あ、でも今月のC MAGAZINEになんか書いてるので見てみます。
10名無しさん@お腹いっぱい。 :2000/09/03(日) 10:48
人間が迷路を作るとしたらどうするか考えて
それをアルゴリズム化しましょう。
11名無しさん@お腹いっぱい。 :2000/09/03(日) 11:36
グレッグ・ブライトの「迷路の本」に載っているやつは難しかった、
とゆーより、よほどの運が無いと抜けられなかったなぁ…
なにしろ、「行きどまりが無い」迷路だったからなぁ…
そういうのを自動生成してほしいなぁ、って、わけわかんねーな、これだけじゃ。
12某ランド :2000/09/03(日) 12:01
ホントの迷路じゃないけど、それっぽいのと短いのであげてみた
#include <stdio.h>
#include <stdlib.h>
void prtc0(int n@`char *s)
{while(n--){ *s++=rand()%2; }
}

void prtc1(int n@`char *s)
{while(n--){if(*s++){printf("%s"@`"/ ");}else{printf("%s"@`" \");};}
printf("\n");
}

void prtc2(int n@`char *s)
{while(n--){if(*s++){printf("%s"@`" /");}else{printf("%s"@`"\ ");};}
printf("\n");
}

int main()
{ char buf[19];
 int i;
 for(i=0;i<100;i++)
 {
  prtc0(sizeof buf@`buf);
  prtc1(sizeof buf@`buf);
  prtc2(sizeof buf@`buf);
 }
return 0;
}
13某ランド :2000/09/03(日) 12:05
実行結果はこんな感じ・・・上手く表示されるかな?
\  / /\  /\ \  / /\  / / / /\ 
/ / / / / /  \/  \ \ \/ / / / 
 / / / / / /\  /\ \ \  / / / /\
/  \/  \/ /  \/ /  \/ / / /  \
 /\  /\  / /\  / /\  / / / /\ \
 \/ /  \/ /  \/  \/ / /  \/ / 
\  / /\  / /\  /\  / / /\  / /\
 \/  \/  \/  \/ / / / /  \/  \
\  /\  /\  /\  / / / / /\  /\ \
 \/ / / /  \ \/  \ \/ /  \/  \
\  / / / /\ \  /\ \  / /\  /\ \
/  \/ /  \/ /  \/  \ \ \/ / / /
 /\  / /\  / /\  /\ \ \  / / /
/  \ \/ /  \ \/ /  \/  \/  \ \
 /\ \  / /\ \  / /\  /\  /\ \ \
14>11 :2000/09/03(日) 15:49
グレッグ・ブライトねぇ。

迷路を極めて、あっちの世界にいっちゃって。
天国で幸せに暮らしているかしら。
15名無しさん@便乗くん :2000/09/03(日) 19:16
Windows の 画面がゆがんだりするスクリンセーバがあったりするけど、
アレのソースってでている?

あと、xlock の swarm(?) とか julian(?) とかのソースもみてみたい。
16名無しさん@お腹いっぱい。 :2000/09/03(日) 19:48
基本的な考え方は…
1)入口と出口を決めて、それを一直線に結ぶ。
2)1)で決めた道を「移動」「折り曲げ」する。※
3)2)と並行して「分岐」を作っていく。※

※すでに道が置かれて部分には適用できない。
まだ道が出来ていない部分に「移動」「折り曲げ」「分岐」が可能。

1)で入口から出口までつながっているのは保障されるので
2)3)の処理はテキトーに行えばOK。
17名無しさん@便乗くん :2000/09/03(日) 21:52
俺のしっているやりかた。
A線とB線をくっつけないように、再起的に延ばせば、出来上がり。
18名無しさん@お腹いっぱい。 :2000/09/03(日) 23:08
・迷路の作成
塊を掘り進む形で、塊の外部は既に掘ったところとみなした上で再帰的に、
1.開始点となる点を座標(2,2)とし、そこを掘った上で着目点とする。
2.着目点の四方を順に(或いは乱数で)チェックする。
  a.そこを掘るとすでに掘った部分に貫通してしまう場合。
    次の方向をチェックする。
  b.そこを掘ってもすでに掘った部分に貫通しない場合。
    そこを掘り着目点をそことして、2.を再帰的に呼び出す。
  c.全部の方向を調べても貫通しない場所が無い場合。
    再帰を戻る。

3.最上位レベルまで戻ったときは迷路は完成している。
  外周の掘った部分と繋がる任意の2点に穴を開けそこを入り口と
  出口として終了。

あ、このやり方で100*100位の迷路を作ると再帰が深くなりすぎて
DOS環境じゃスタックがオーバーフローするからWin32環境などで
やること。

って、17が荒っぽく書いてんじゃん。
19名無しさん@お腹いっぱい。 :2000/09/04(月) 00:34
再帰をつかわなくても、迷路のすべての部分について18みたいな事を繰り返して、
どこも掘れなくなったら終りっていう方法もあるね。
20名無しさん@お腹いっぱい。 :2000/09/04(月) 00:37
要するに、ランダムな方向に塗りつぶしていく
ペイントルーチンを作ればいいのだ。……なんか違う気もするが。
21名無しさん@お腹いっぱい。 :2000/09/04(月) 00:39
かべは作らなくちゃだが、やってる事は似たようなもんだな。
22>15 :2000/09/04(月) 01:57
swarmは結構簡単に見つかると思うよ。検索すれば。
たしかVectorの本にも収録されていたような気が…。
2315>22 :2000/09/04(月) 12:01
サンクス&haerts;

追加便乗。
Windows 98 で RPM ファイルを解凍したいんだけど、どうすればいい?
243 :2000/09/04(月) 15:04
結構、いかすアルゴリズムだと思ったけどな、当時は。
今でも、おぼろげながら覚えてるよ。
説明は出来ないんだけどね。
25111111111 :2000/09/04(月) 17:29
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class MazeApplet extends Applet implements Runnable{
final int XMAX = 80;
final int YMAX = 24;
final int MAXSITE = XMAX*YMAX/4;
int map[][] = new int[XMAX+1][YMAX+1];
int nsite = 0;
int xx[] = new int[MAXSITE];
int yy[] = new int[MAXSITE];
int dx[] = { 2@` 0@`-2@` 0};
int dy[] = { 0@` 2@` 0@`-2};
int dirtable[][] = {
{ 0@`1@`2@`3 }@` { 0@`1@`3@`2 }@` { 0@`2@`1@`3 }@` { 0@`2@`3@`1 }@` { 0@`3@`1@`2 }@` { 0@`3@`2@`1 }@`
{ 1@`0@`2@`3 }@` { 1@`0@`3@`2 }@` { 1@`2@`0@`3 }@` { 1@`2@`3@`0 }@` { 1@`3@`0@`2 }@` { 1@`3@`2@`0 }@`
{ 2@`0@`1@`3 }@` { 2@`0@`3@`1 }@` { 2@`1@`0@`3 }@` { 2@`1@`3@`0 }@` { 2@`3@`0@`1 }@` { 2@`3@`1@`0 }@`
{ 3@`0@`1@`2 }@` { 3@`0@`2@`1 }@` { 3@`1@`0@`2 }@` { 3@`1@`2@`0 }@` { 3@`2@`0@`1 }@` { 3@`2@`1@`0 }};
int tmpi@`tmpj;
int Si=3@`Sj=3@`Ei=XMAX-3@`Ej=YMAX-3@`success=0;
int sp=0@`ri[]=new int[200]@`rj[]=new int[200];
Color col[] = {Color.magenta@`Color.black@`Color.orange};
Image offs;
Graphics grf;
Thread th = null;

public void init(){
offs = createImage(820@`260);
grf = offs.getGraphics();
}

public void add(int i@`int j){
xx[nsite] = i; yy[nsite] = j; nsite++;
}

public int select(int i@`int j){
int r;
if(nsite == 0) return 0;
nsite--; r = (int)(Math.random()*nsite+1);
tmpi = xx[r]; xx[r] = xx[nsite];
tmpj = yy[r]; yy[r] = yy[nsite];
return 1;
}

public void meiro(){
int i@`j@`i1=0@`j1=0@`d@`t@`tt;

for(i=0;i<=XMAX;i++)
for(j=0;j<=YMAX;j++)
map[i][j] = 2;
for(i=3;i<=XMAX-3;i++)
for(j=3;j<=YMAX-3;j++)
map[i][j] = 0;
map[2][3] = 0; map[XMAX-2][YMAX-3] = 0;
for(i=4;i<=XMAX-4;i+=2){
add(i@`2); add(i@`YMAX-2);
}
for(j=4;j<=YMAX-4;j+=2){
add(2@`j); add(XMAX-2@`j);
}
tmpi=i;tmpj=j;
while(select(tmpi@`tmpj)==1){
for(;;){
tt=(int)(Math.random()*24);
for(d=3;d>=0;d--){
t=dirtable[tt][d]; i1=tmpi+dx[t]; j1=tmpj+dy[t];
if(map[i1][j1]==0) break;
}
if(d<0) break;
map[(tmpi+i1)/2][(tmpj+j1)/2]=2;
tmpi=i1; tmpj=j1; map[tmpi][tmpj]=2; add(tmpi@`tmpj);
try{
th.sleep(100);
}catch(InterruptedException e){}
repaint();
}
}
}

26111111111 :2000/09/04(月) 17:30
public int visit(int i@`int j){
map[i][j]=1;
ri[sp]=i;rj[sp]=j;sp++;
repaint();
try{
th.sleep(110);
}catch(InterruptedException e){}
if(i==Ei&&j==Ej) success=1;

if(success!=1&&map[i][j+1]==0) visit(i@`j+1);
if(success!=1&&map[i+1][j]==0) visit(i+1@`j);
if(success!=1&&map[i][j-1]==0) visit(i@`j-1);
if(success!=1&&map[i-1][j]==0) visit(i-1@`j);

sp--;
return success;
}

public void update(Graphics g){
paint(g);
}

public void paint(Graphics g){
grf.setColor(Color.magenta);
grf.fillRect(0@`0@`820@`260);
for(int j=2;j<=YMAX-2;j++){
for(int i=2;i<=XMAX-2;i++){
grf.setColor(col[map[i][j]]);
grf.fillOval(i*10@`j*10@`10@`10);
}
}
g.drawImage(offs@`0@`0@`this);
}

public void start(){
th = new Thread(this);
th.start();
}

public void stop(){
th = null;
}

public void run(){
meiro();
map[2][3]=2; map[XMAX-2][YMAX-3]=2;
int k=visit(Si@`Sj);
}

}
27>12@`13
正方形に対してひし形のマップが多い理由が少しだけ判ったよ
2つのしかも鏡パターンで描けるんだねえ