class Mazinator::MazeGenerator

Attributes

cols[R]
current[RW]
maze[R]
rows[R]
stack[RW]
start[RW]
unvisited[RW]
visited[RW]

Public Class Methods

new(dimension) click to toggle source
# File lib/mazinator/maze_generator.rb, line 10
def initialize(dimension)
  @stack = []
  @visited=[]
  @unvisited = []
  @current = nil
  @rows = dimension
  @cols = dimension
  @maze = Matrix.build(@rows, @cols) {|row, col| Mazinator::Cell.new(row, col) }
end

Public Instance Methods

generate() click to toggle source
# File lib/mazinator/maze_generator.rb, line 20
def generate
  # set entry to the maze
  self.maze.first.walls[:left] = false
  # set exit from the maze
  self.maze[rows-1, cols-1].walls[:right] = false
  self.current = self.maze.first

  self.maze.each{ |cell| self.unvisited << cell }
  while self.unvisited.any? do
    self.visit
  end

  Mazinator::Maze.new(self.rows, self.cols, self.maze)
end
get_left_neighbour(cell) click to toggle source
# File lib/mazinator/maze_generator.rb, line 100
def get_left_neighbour(cell)
  return nil if (cell.col - 1 < 0)
  neighbour = self.maze[cell.row, cell.col-1]
  return nil if self.visited.include?(neighbour)
  neighbour
end
get_lower_neighbour(cell) click to toggle source
# File lib/mazinator/maze_generator.rb, line 121
def get_lower_neighbour(cell)
  return nil if (cell.row + 1 >= self.rows)
  neighbour = self.maze[cell.row+1, cell.col]
  return nil if self.visited.include?(neighbour)
  neighbour
end
get_neighbours(cell) click to toggle source
# File lib/mazinator/maze_generator.rb, line 54
def get_neighbours(cell)
  nbrs = []
  nbrs << self.get_left_neighbour(cell)
  nbrs << self.get_right_neighbour(cell)
  nbrs << self.get_upper_neighbour(cell)
  nbrs << self.get_lower_neighbour(cell)

  nbrs.compact.shuffle
end
get_right_neighbour(cell) click to toggle source
# File lib/mazinator/maze_generator.rb, line 107
def get_right_neighbour(cell)
  return nil if (cell.col+ 1 >= self.cols)
  neighbour = self.maze[cell.row, cell.col+1]
  return nil if self.visited.include?(neighbour)
  neighbour
end
get_upper_neighbour(cell) click to toggle source
# File lib/mazinator/maze_generator.rb, line 114
def get_upper_neighbour(cell)
  return nil if (cell.row - 1 < 0)
  neighbour = self.maze[cell.row-1, cell.col]
  return nil if self.visited.include?(neighbour)
  neighbour
end
make_visited(cell) click to toggle source
# File lib/mazinator/maze_generator.rb, line 64
def make_visited(cell)
  i = self.unvisited.index(cell)
  # this cell has been visited, return now
  return false unless i
  self.visited << cell
  self.unvisited.delete(cell)
end
visit() click to toggle source
# File lib/mazinator/maze_generator.rb, line 35
def visit
  neighbours = self.get_neighbours(self.current)
  if neighbours.any?
    cell = neighbours.first
    self.stack << self.current
    wreck_wall(self.current, cell)
    self.current = cell
    make_visited(cell)
  elsif self.stack.any?
    cell = self.stack.pop
    self.current = cell
  else
    unvisited_len = self.unvisited.length
    cell = self.unvisited[rand(unvisited_len)]
    self.current = cell
    make_visited(cell)
  end
end
wreck_wall(cell_a, cell_b) click to toggle source
# File lib/mazinator/maze_generator.rb, line 73
def wreck_wall(cell_a, cell_b)
  if cell_a.row == cell_b.row
    if cell_a.col == (cell_b.col - 1)
      cell_a.walls[:right] = false
      cell_b.walls[:left] = false
    elsif cell_a.col == (cell_b.col + 1)
      cell_a.walls[:left] = false
      cell_b.walls[:right] = false
    else
      nil
    end
  elsif cell_a.col == cell_b.col
    if cell_a.row == (cell_b.row - 1)
      cell_a.walls[:down] = false
      cell_b.walls[:up] = false
    elsif cell_a.row == (cell_b.row + 1)
      cell_a.walls[:up] = false
      cell_b.walls[:down] = false
    else
      nil
    end
  else
    # passed random cells, do nothing
    nil
  end 
end