Ангел обнови решението на 17.12.2011 17:11 (преди около 13 години)
+module GameOfLife
+ class Board
+ include Enumerable
+
+ def initialize(*alive_cells)
+ @alive_cells = alive_cells.uniq.map {|cell| Cell.new *cell}
+ neighbour_cells = @alive_cells.inject([]) {|buff, cell| buff + cell.neighbours}.uniq
+ @dead_neighbour_cells = (neighbour_cells - alive_cells).map {|cell| Cell.new *cell}
+ end
+
+ def [](x, y)
+ include? [x, y]
+ end
+
+ def each
+ if block_given?
+ @alive_cells.each {|cell| yield cell.coordinates}
+ else
+ Enumerator.new @alive_cells.map(&:coordinates), :each
+ end
+ end
+
+ def next_generation
+ remaining_alive = @alive_cells.select {|cell| (2..3) === alive_neighbours(cell)}
+ reproducted = @dead_neighbour_cells.select {|cell| alive_neighbours(cell) == 3}
+ self.class.new *(remaining_alive + reproducted).map(&:coordinates)
+ end
+
+ private
+ def alive_neighbours(cell)
+ cell.neighbours.select {|neighbour| self[*neighbour]}.size
+ end
+ end
+
+ class Cell
+ def initialize(x, y)
+ @x, @y = x, y
+ end
+
+ def coordinates
+ [@x, @y]
+ end
+
+ def neighbours
+ square = (@x-1..@x+1).to_a.product (@y-1..@y+1).to_a
+ square - [coordinates]
+ end
+ end
+end