ここでグラフィカルな迷路を生成してみたのですが、やっぱりコンソール版も欲しいよねということで作りました。
こんな感じ。
*****************************************どうですかね。
* * * * * * * *
*** * * * ***** * ***** * *** ******* ***
* * * * * * * * * * *
******* * * ******* * *** *** * *** *** *
* * * * * * * * * *
*** ******* * * ***** ***** * * ***** ***
* * * * * * * * * * *
* ******* *** *** ******* * *** * *** * *
* * * * * * *
* ***** * *** ******* * * *** * ***** ***
* * * * * * * * * * * *
*** * * * * * ***** * *** * ***** *** ***
* * * * * * * * * *
*****************************************
コード。
maze_another.rb
class Maze def initialize(x, y) raise "maze size error" unless x.odd? and y.odd? and x >= 5 and y >= 5 @x, @y = x, y @field = Array.new(y) {Array.new(x, 0)} co = 1 1.step(y - 2, 2) do |j| 1.step(x - 2, 2) {|i| @field[j][i] = co; co += 1} end @a, @b = (x - 3) / 2, (y - 3) / 2 @lx, @ly = @a * (@b + 1), (@a + 1) * @b @remain_wall = (0...(@lx + @ly)).to_a end def generate break_wall until finish @field end def break_wall wall = @remain_wall[rand(@remain_wall.size)] @remain_wall.delete(wall) if wall < @lx x, y = wall % @a * 2 + 2, wall / @a * 2 + 1 return if (m = @field[y][x - 1]) == (n = @field[y][x + 1]) else wall -= @lx x, y = wall % (@a + 1) * 2 + 1, wall / (@a + 1) * 2 + 2 return if (m = @field[y - 1][x]) == (n = @field[y + 1][x]) end @field[y][x] = m m, n = n, m if m > n replace(m, n) end def replace(m, n) 1.upto(@y - 2) do |y| 1.upto(@x - 2) {|x| @field[y][x] = m if @field[y][x] == n} end end def finish a = @field[1][1] 1.step(@y - 2, 2) do |j| 1.step(@x - 2, 2) {|i| return false if @field[j][i] != a} end true end end def show_maze(field) field.each do |line| puts line.map {|x| x.zero? ? "*" : " "}.join end end field = Maze.new(41, 15).generate show_maze(field)
迷路の生成と表示は分けています。アルゴリズムは前回と同じで、ここのそれを使わせていただきました。なお、迷路の大きさ(Maze.new(x, y) の x, y)は 5 以上の奇数にして下さい。