Владимир обнови решението на 20.12.2011 20:53 (преди около 13 години)
+module GameOfLife
+
+ class Board
+ include Enumerable
+
+ def initialize(*args)
+ @alive_cells = []
+ unless args.empty?
+ args.each {|coords| @alive_cells << Cell.new(coords.first, coords.last) }
+ end
+ @new_life = []
+ end
+
+ def each &block
+ @alive_cells.each do |cell|
+ if block_given?
+ block.call cell.x, cell.y
+ else
+ yield cell.x, cell.y
+ end
+ end
+ end
+
+ def next_generation
+ killed = []
+ @alive_cells.each {|cell| killed << cell if nb_alive(cell) < 2 || nb_alive(cell) > 3 }
+ @alive_cells.each {|cell| cell.neighbours.each {|nbour_xy| spurr_life(nbour_xy) } }
+ next_g = Board.new(*convert(@alive_cells - killed + @new_life))
+ end
+
+ def convert(cells)
+ result = []
+ cells.each {|cell| result << [cell.x, cell.y] }
+ result
+ end
+
+ def [](x, y)
+ @alive_cells.each {|cell| return true if cell.x == x && cell.y == y }
+ false
+ end
+
+ def count
+ @alive_cells.size
+ end
+
+ def spurr_life(cell_coords)
+ unless cell_alive?(cell_coords.first, cell_coords.last)
+ Cell.new(cell_coords.first, cell_coords.last).neighbours.each do |coords|
+ empty_cell = Cell.new(coords.first, coords.last)
+ check_and_add(empty_cell)
+ end
+ end
+ end
+
+ def check_and_add(empty_cell)
+ if nb_alive(empty_cell) == 3
+ @new_life << empty_cell unless included_already?(empty_cell)
+ end
+ end
+
+ def included_already?(new_cell)
+ @new_life.each {|cell| return true if cell.x == new_cell.x && cell.y == new_cell.y }
+ false
+ end
+
+ def nb_alive(cell)
+ result = 0
+ cell.neighbours.each {|coords| result += 1 if cell_alive?(coords.first, coords.last) }
+ result
+ end
+
+ alias :cell_alive? :[]
+ end
+
+ class Cell
+ attr_reader :x, :y, :neighbours
+
+ def initialize(x, y)
+ @x = x
+ @y = y
+ @neighbours = get_neighbours
+ end
+
+ private
+ def get_neighbours
+ neighbours = []
+ neighbours << [@x - 1, @y - 1] << [@x - 1, @y] << [@x - 1, @y + 1]
+ neighbours << [@x + 1, @y - 1] << [@x + 1, @y] << [@x + 1, @y + 1]
+ neighbours << [@x, @y - 1] << [@x, @y + 1]
+ end
+
+ end
+
+end