maze.rb
#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-
require 'rubygems'
require 'win32console'
require 'term/ansicolor'
include Win32::Console::ANSI
include Term::ANSIColor
class Maze
PATHWAY = 1
WALL = 2
attr_accessor :width, :height
def initialize(width, height)
@width = width * 2 + 1
@height = height * 2 + 1
@map = [ PATHWAY ] * @width * @height
@console = Win32::Console.new(STD_OUTPUT_HANDLE)
prologue
dig
epilogue
end
def prologue
@console.Cls
print on_white
dig_edge
end
def epilogue
print reset
@console.Cursor(0, 1)
print ' '
@console.Cursor(@width - 1, @height - 2)
print ' '
@console.Cursor(0, @height + 1)
end
def dig
loop do
w0, w1 = select_next
break unless w0
set_wall(*w0)
set_wall(*w1)
loop do
w0, w1 = candidates(*w1)
break unless w0
set_wall(*w0)
set_wall(*w1)
sleep 0
end
end
end
def select_next
r = walls
loop do
i = rand(r.size)
x, y = r[i]
r.delete_at(i)
z = candidates(x, y)
return z if z
break if r.empty?
end
end
def candidates(x, y)
c = []
f0(c, x + 1, y, x + 2, y)
f0(c, x - 1, y, x - 2, y)
f0(c, x, y + 1, x, y + 2)
f0(c, x, y - 1, x, y - 2)
c[rand(c.size)] unless c.empty?
end
def f0(z, x, y, x1, x2)
if PATHWAY == self[x1, x2]
z << [ [x, y], [x1, x2] ]
end
end
def walls
r = []
0.step(@height - 1, 2) do |y|
0.step(@width - 1, 2) do |x|
r << [x, y] if WALL == self[x, y]
end
end
r
end
def dig_edge
x = @width - 1
@height.times do |y|
set_wall(0, y)
set_wall(x, y)
end
y = @height - 1
@width.times do |x|
set_wall(x, 0)
set_wall(x, y)
end
end
def set_wall(x, y)
@map[x + y * @width] = WALL
@console.Cursor(x, y)
print ' '
end
def [](x, y)
return nil if x < 0 || @width <= x
return nil if y < 0 || @height <= y
@map[x + y * @width]
end
end
m = Maze.new(39, 30)
参考: 自動生成迷路
0 件のコメント:
コメントを投稿