Мария обнови решението на 19.12.2011 00:32 (преди около 13 години)
+require 'enumerator'
+
+module GameOfLife
+
+ class Cell
+ attr_accessor :x, :y
+
+ def initialize(x,y)
+ if x.is_a? Integer and y.is_a? Integer
+ @x, @y = x, y
+ else raise "Invalid values for coordinates - Only Integer allowed"
+ end
+ end
+ def to_arr
+ [x,y]
+ end
+ def ==(other)
+ @x == other.x and @y == other.y
+ end
+
+ def is_n?(cell)
+ (((@x - cell[0]).abs == 1) and ((@y - cell[1]).abs < 2)) or
+ (((@y - cell[1]).abs == 1) and ((@x - cell[0]).abs < 2))
+ end
+ end
+
+ class Board
+ include Enumerable
+
+ attr_accessor :live_cells
+
+ def initialize(*cells)
+ @live_cells = []
+ cells.each do |x,y|
+ @live_cells << Cell.new(x,y) unless self[x,y]
+ end
+ end
+
+ def [](x,y)
+ @live_cells.include? Cell.new(x,y)
+ end
+
+ def each
+ 0.upto(@live_cells.length - 1) do |cell|
+ yield @live_cells[cell].to_arr()
+ end
+ end
+
+ def count
+ @live_cells.count
+ end
+
+ def get_live_n(cell)
+ @live_cells.find_all do |c|
+ c.is_n? cell
+ end
+ end
+
+ def get_n(cell)
+ neighbours = []
+ [-1,0,1].each do |x|
+ [-1,0,1].each { |y| neighbours << [cell.x+x, cell.y+y] }
+ end
+ neighbours
+ end
+
+ def dead_or_alive?(cell)
+ neighbours = get_live_n(cell).count
+ (self[cell[0], cell[1]] && neighbours.between?(2,3)) or
+ ((not self[cell[0], cell[1]]) && neighbours == 3 )
+ end
+
+ def next_generation
+ dead_or_alive = {}
+ @live_cells.each do |c|
+ dead_or_alive.merge! get_n(c).inject({}) { |s,e| s.merge({e => dead_or_alive?(e)}) }
+ end
+ Board.new *dead_or_alive.select{|k, v| v}.keys
+ end
+ end
+
+end