Skip to content

Instantly share code, notes, and snippets.

@Nemo157
Created January 31, 2011 00:04
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nemo157/803450 to your computer and use it in GitHub Desktop.
Save Nemo157/803450 to your computer and use it in GitHub Desktop.
class Map
def initialize width, height
@values = Array.new(width){ Array.new(height){ nil } }
end
def [](x, y)
@values[x][y]
end
def []=(x, y, value)
@values[x][y] = value
end
end
class Maze
def initialize config={}
@width = config[:width] || 100
@height = config[:height] || 100
@num_runners = config[:num_runners] || 5
@dead_end_chance = config[:dead_end_chance] || 0.05
case Random.rand
when 0..0.25
@start_index = [0, Random.rand(@height)]
when 0.25..0.5
@start_index = [@width - 1, Random.rand(@height)]
when 0.5..0.75
@start_index = [Random.rand(@width), 0]
when 0.75..1
@start_index = [Random.rand(@width), @height - 1]
end
end
def generate
@map = Map.new(@width, @height)
@map[*@start_index] = :empty
runners = [@start_index]
while (! runners.empty?)
current = runners.shift
nixt = self.choose_direction current
while runners.length < @num_runners && nixt != nil
# if Random.rand < @dead_end_chance
# @map[*nixt] = :wall
# else
@map[*nixt] = :empty
runners << nixt
# end
nixt = self.choose_direction current
end
self.neighbours(current).each do |point|
@map[*point] = :wall
end
end
@map[*current] = :treasure
end
def choose_direction point
n = self.neighbours point
n.empty? ? nil : n[Random.rand(n.length)]
end
def all_neighbours point
[
[point[0] - 1, point[1] ],
[point[0] - 1, point[1] + 1],
[point[0] - 1, point[1] - 1],
[point[0] + 1, point[1] ],
[point[0] + 1, point[1] + 1],
[point[0] + 1, point[1] - 1],
[point[0] , point[1] - 1],
[point[0] , point[1] + 1]
].select {|point| point[0] > 0 and point[0] < @width and point[1] > 0 and point[1] < @height }
end
def horiz_neighbours point
[
[point[0] - 1, point[1] ],
[point[0] + 1, point[1] ],
].select {|point| point[0] > 0 and point[0] < @width }
end
def four_neighbours point
[
[point[0] - 1, point[1] ],
[point[0] + 1, point[1] ],
[point[0] , point[1] - 1],
[point[0] , point[1] + 1]
].select {|point| point[0] > 0 and point[0] < @width and point[1] > 0 and point[1] < @height }
end
def neighbours point
[
[point[0] - 1, point[1]],
[point[0] + 1, point[1]],
[point[0], point[1] - 1],
[point[0], point[1] + 1]
].select {|point| point[0] > 1 and point[0] < @width - 1 and point[1] > 1 and point[1] < @height - 1 and @map[*point] == nil }
end
def determine_wall_char x, y
if all_neighbours([x,y]).map{|p|@map[*p]}&[:empty, :treasure] == []
' '
else
case (four_neighbours([x,y]).map{|p|@map[*p]}.select{|y|[:empty,:treasure].include? y}).length
when 0, 3, 4
'+'
when 1
case (horiz_neighbours([x,y]).map{|p|@map[*p]}.select{|y|[:empty,:treasure].include? y}).length
when 0
'-'
when 1
'|'
end
when 2
case (horiz_neighbours([x,y]).map{|p|@map[*p]}.select{|y|[:empty,:treasure].include? y}).length
when 0
'-'
when 1
'+'
when 2
'|'
end
else
'?'
end
end
end
def determine_char x, y
case @map[x,y]
when :treasure
'#'
when :empty
' '
when :wall, nil
determine_wall_char x, y
else
'?'
end
end
def draw
@height.times do |y|
@width.times do |x|
print determine_char x, y
end
puts
end
end
end
if $0 == __FILE__
if ARGV.length != 2
puts "Usage: ruby #{$0} <width> <height>"
exit -1
end
maze = Maze.new :width => ARGV[0].to_i, :height => ARGV[1].to_i
maze.generate
maze.draw
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment