Мая обнови решението на 18.12.2011 21:51 (преди около 13 години)
+module GameOfLife
+ class Point
+ attr_reader :x, :y
+
+ def initialize coordinates
+ @x, @y = coordinates[0], coordinates[1]
+ end
+
+ def neighbours
+ neighbours_helper = [@x-1, @x, @x+1].product [@y-1, @y, @y+1]
+ neighbours_helper.delete [@x, @y]
+ neighbours_helper.map {|p| Point.new p}
+ end
+
+ def ==(p2)
+ self.x == p2.x and self.y == p2.y
+ end
+ end
+
+ class Board
+ include Enumerable
+
+ def initialize *coordinates
+ @alive = []
+ coordinates.each do |cell|
+ p = Point.new(cell)
+ @alive << p unless @alive.include? p
+ end
+ end
+
+ def count
+ @alive.size
+ end
+
+ def [](x, y)
+ (@alive.include? Point.new [x,y]) ? true : false
+ end
+
+ def each
+ @alive.each do |point|
+ yield [point.x, point.y]
+ end
+ end
+
+ def next_generation
+ Board.new *next_alive
+ end
+
+ #private
+
+ def next_alive
+ upcoming = []
+ @alive.each do |point|
+ upcoming = check_area upcoming, point
+ end
+
+ upcoming
+ end
+
+ def becomes_alive? cell
+ alive_neighbours(cell) == 3 and not @alive.include? cell
+ end
+
+ def check_area(upcoming, point)
+ if alive_neighbours(point) == 2 or alive_neighbours(point) == 3
+ upcoming << [point.x, point.y]
+ end
+
+ cells = point.neighbours.select {|t| becomes_alive? t and not upcoming.include? [t.x, t.y]}
+ upcoming += cells.map {|cell| [cell.x, cell.y]}
+ end
+
+ def alive_neighbours point
+ point.neighbours.select {|t| @alive.include? t}.size
+ end
+
+ def to_a
+ @alive.map {|t| [t.x, t.y]}
+ end
+ end
+end