Mercurial > maze-src
diff ellers.rb @ 0:1eef88068f9f tip
initial commit of maze game source
| author | ferencd |
|---|---|
| date | Sun, 15 Sep 2019 11:46:47 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ellers.rb Sun Sep 15 11:46:47 2019 +0200 @@ -0,0 +1,89 @@ +#--- +# Excerpted from "Mazes for Programmers", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/jbmaze for more book information. +#--- +class Ellers + + class RowState + def initialize(starting_set=0) + @cells_in_set = {} + @set_for_cell = [] + @next_set = starting_set + end + + def record(set, cell) + @set_for_cell[cell.column] = set + + @cells_in_set[set] = [] if !@cells_in_set[set] + @cells_in_set[set].push cell + end + + def set_for(cell) + if !@set_for_cell[cell.column] + record(@next_set, cell) + @next_set += 1 + end + + @set_for_cell[cell.column] + end + + def merge(winner, loser) + @cells_in_set[loser].each do |cell| + @set_for_cell[cell.column] = winner + @cells_in_set[winner].push cell + end + + @cells_in_set.delete(loser) + end + + def next + RowState.new(@next_set) + end + + def each_set + @cells_in_set.each { |set, cells| yield set, cells } + self + end + end + + def on(grid) + row_state = RowState.new + + grid.each_row do |row| + row.each do |cell| + next unless cell.west + + set = row_state.set_for(cell) + prior_set = row_state.set_for(cell.west) + + should_link = set != prior_set && + (cell.south.nil? || rand(2) == 0) + + if should_link + cell.link(cell.west) + row_state.merge(prior_set, set) + end + end + + if row[0].south + next_row = row_state.next + + row_state.each_set do |_, list| + list.shuffle.each_with_index do |cell, index| + if index == 0 || rand(3) == 0 + cell.link(cell.south) + next_row.record(row_state.set_for(cell), cell.south) + end + end + end + + row_state = next_row + end + end + end + +end
