不思議なダンジョン風マップ自動生成
参考にしたのはここ 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()
実行したらこんな感じ。
//////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //// //////////////////////////////////// //// //////////////////////////////////// //// //////////////////////////////////// ////////////// //////////////////////////////////////////// ////////////// ////////////// //// ////////////////// //// ////// //// ////////////////// //// ////// //// ////////////////// //// ////// //// ////////////////// //// ////// //// ////////////////// //// //// ////// //// //// //// ////////////////// //// //// // //// //// //// ////////////// // //// //// //// ////////////// // ////////////// //////////// ////////////////////// // ////////////// //////////// ////////////////////// // //// //// ////////////////////// // ////////////// //////////// ////////////////////// // ////////////// ////////////////////// // //////////////////////////// //////////////////////// // //////////////////////////// //////////////////////// // //////////////////////////// //////////////////////// // ////////////////// // ////////////////////////////// //////////////////////////// ////////////////////////////// //////////////////////////// ////////////////////////////// //////////////////////////// //////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////