Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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
Add Comment
Please, Sign In to add comment