不思議なダンジョン風マップ自動生成
参考にしたのはここ http://racanhack.sourceforge.jp/rhdoc/index.html
方針
上記の説明だけ読んでコード参考にしなかったので全然違う実装になった。
大きな空部屋を作って、部屋のクラスごとに担当する領域を持っておく。再帰構造で次の部屋の参照をもっとく。隣の部屋へのルートを書けば全部の部屋が繋がる。
コード
部屋と部屋をつなぐ部分を手抜きでやったので他の部屋跨いだりする。
{pow,sqrt,abs,random,max,min} = Math
class Room
constructor:(@map,@depth, @ax,@ay)->
@max_size = 4
@next = null
if @depth > 0
@next = @split()
if @ax[1]-@ax[0] < 13
@rx = @ax
else
cx = ~~((@ax[0]+@ax[1])/2)
@rx = [cx-6, cx+6]
if @ay[1]-@ay[0] < 13
@ry = @ay
else
cy = ~~((@ay[0]+@ay[1])/2)
@ry = [cy-6, cy+6]
@center = [
~~((@rx[1]+@rx[0])/2)
~~((@ry[1]+@ry[0])/2)
]
@draw_area()
_v : ->
[sx , ex] = @ax
cx = ~~( (ex-sx)*(max(0.2,1-random()/@depth) )+sx )
@ax = [cx,ex]
new Room @map,--@depth, [sx,cx ],@ay
_s : ->
[sy , ey] = @ay
cy = ~~( (ey-sy)*(1-random()/@depth)+sy )
@ay = [cy,ey]
new Room @map,--@depth, @ax , [sy,cy]
split:->
if Math.random() > 0.5
@_s()
else
@_v()
draw_area : ->
[sx,ex] = @rx
[sy,ey] = @ry
for i in [sx ... ex]
for j in [sy ... ey]
if @center[0] is i and @center[1] is j
@map[i][j] = 2
console.log i,j
if (i == sx or i == (ex-1) ) or (j == sy or j == (ey-1))
@map[i][j] = 1
else
@map[i][j] = 0
draw_path : ->
if @next
[cx,cy] = @center
[nx,ny] = @next.center
while abs(cx-nx)+abs(cy-ny) > 0
if cx>nx then cx--
else if cx<nx then cx++
else if cy>ny then cy--
else if cy<ny then cy++
@map[cx][cy] = 0
@next.draw_path()
blank = (x,y)->
map = []
for i in [0 ... x]
map[i] = []
for j in [0 ... y]
map[i][j] = 1
return map
create_map = ->
x = 30
y = 30
root = new Room(blank(x,y),13 ,[1,x-1],[1,y-1])
root.draw_path()
root.map
main = ->
map = create_map()
for i in map
console.log i
.join('')
.split('0').join(' ')
.split('1').join('//')
.split('2').join('..')
main()
実行したらこんな感じ。
//////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //// //////////////////////////////////// //// //////////////////////////////////// //// //////////////////////////////////// ////////////// //////////////////////////////////////////// ////////////// ////////////// //// ////////////////// //// ////// //// ////////////////// //// ////// //// ////////////////// //// ////// //// ////////////////// //// ////// //// ////////////////// //// //// ////// //// //// //// ////////////////// //// //// // //// //// //// ////////////// // //// //// //// ////////////// // ////////////// //////////// ////////////////////// // ////////////// //////////// ////////////////////// // //// //// ////////////////////// // ////////////// //////////// ////////////////////// // ////////////// ////////////////////// // //////////////////////////// //////////////////////// // //////////////////////////// //////////////////////// // //////////////////////////// //////////////////////// // ////////////////// // ////////////////////////////// //////////////////////////// ////////////////////////////// //////////////////////////// ////////////////////////////// //////////////////////////// //////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////