saws #5286(2008/01/12 18:05 GMT) [ Ruby ] Rating0/0=0.00
棒倒し法で実装しました. 1024 x 1024の迷路生成に約48秒 (CPU: Intel P4 Northwood 2.8 GHz) かかりました. mapメソッドとgen_wallメソッドの処理の1行目のコメントは, 各メソッドの1行バージョンです. 全体をone-lineにする方法が見つからなかったのでせめてもの抵抗ということで.
see: アルゴリズム講座:棒倒し法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
require 'matrix' N, M = 5, 4 class Maze MARK, SPC = '*', ' ' def initialize(n, m) #基準点を生成し, その上と左の壁の有無と真理値が対応. @map = Matrix[*Array.new(@n = n){Array.new(@m = m)}].map{Array.new(2)} gen_maze end def map #得たマップデータを対応する記号で表現 #Array.new(2*@n-1){|i| Array.new(2*@m-1){|j| i%2 == j%2 ? (i%2 == 1 ? MARK : SPC) : (@map[i.div(2), j.div(2)][i%2] ? MARK : SPC)}.unshift(MARK).push("#{MARK}\n")}.unshift(str = "#{MARK*(2*@m+1)}\n").push(str).join print "#{MARK*(2*@m+1)}\n" (2*@n-1).times{|i| print MARK (2*@m-1).times{|j| if i%2 == j%2 print i%2 == 1 ? MARK : SPC else print @map[i.div(2), j.div(2)][i%2] ? MARK : SPC end } print "#{MARK}\n" } print "#{MARK*(2*@m+1)}\n" end def gen_maze #左端の列だけ4種の壁がランダムで生成. 他は3種のみ. (@m-1).times{|j| (@n-1).times{|i| gen_wall(i, j, (j == 0 ? 4 : 3))}} end def gen_wall(i, j, n) #ランダムに壁を生成. もし壁がすでにあれば再帰. #@map[x = i+((r=rand(n))==1 ? 1 : 0), y = j+(r==2 ? 1 : 0)][r%2] ? gen_wall(i, j, n) : @map[x, y][r%2] = true case rand(n) when 0: x, y, k = i, j, 0 #上 when 1: x, y, k = i+1, j, 0 #下 when 2: x, y, k = i, j+1, 1 #右 when 3: x, y, k = i, j, 1 #左 end @map[x, y][k] ? gen_wall(i, j, n) : @map[x, y][k] = true end private :gen_maze, :gen_wall end maze = Maze.new(N, M) maze.gen_maze maze.map
Rating0/0=0.00-0+
[ reply ]
saws
#5286()
[
Ruby
]
Rating0/0=0.00
see: アルゴリズム講座:棒倒し法
Rating0/0=0.00-0+
[ reply ]