Деян обнови решението на 20.12.2011 01:12 (преди около 13 години)
+require 'enumerator'
+
+class GameOfLife
+ class Board
+ include Enumerable
+
+ attr_reader :active_cells
+
+ def initialize(*args)
+ @active_cells = *args.uniq
+ end
+
+ def [](a, b)
+ @active_cells.include? [a, b]
+ end
+
+ def each
+ @active_cells.each { |n| yield n }
+ end
+
+ def count
+ @active_cells.length
+ end
+
+ def next_generation
+ @next_gen = NextGeneration.new(*@active_cells)
+
+ @next_gen.cells == [] ? Board.new() : Board.new(*@next_gen.cells)
+ end
+ end
+
+ class Neighbours
+ def self.coord_neighbours(x,y)
+ [[x - 1, y - 1], [x, y - 1], [x + 1, y - 1],
+ [x - 1, y], [x + 1, y],
+ [x - 1, y + 1], [x, y + 1], [x + 1, y + 1]]
+ end
+
+ def self.all(cell = [])
+ cell.nil? ? [] : coord_neighbours(cell.first, cell.last)
+ end
+ end
+
+ class NextGeneration
+ attr_reader :cells
+
+ def initialize(*args)
+ @active_cells = args
+ @cells = procreate + survive
+ end
+
+ def active_neighbours(cell = [])
+ cell.nil? or @active_cells.nil? ? [] : Neighbours.all(cell) & @active_cells
+ end
+
+ def dead_neighbours(cell = [])
+ cell.nil? or @active_cells.nil? ? [] : Neighbours.all(cell) - @active_cells
+ end
+
+ def activate_cells(cells)
+ cells.map { |n| dead_neighbours(n) } .flatten(1).select { |n| count_neighbours(n) == 3 } .uniq
+ end
+
+ def procreate
+ @active_cells.nil? ? nil : activate_cells(@active_cells)
+ end
+
+ def count_neighbours(cell = [])
+ active_neighbours(cell).length
+ end
+
+ def can_stay_alive?(cell = [])
+ count_neighbours(cell) == 2 or count_neighbours(cell) == 3
+ end
+
+ def survive
+ @active_cells.nil? ? nil : @active_cells.select { |n| can_stay_alive?(n) }
+ end
+ end
+end
Идеята зад това да има именовано собствено пространство GameOfLife
е ако ти трябват допълнителни класове/модули, да ги слагаш в това именовано пространство. В случая, NextGeneration
е най-добре да се намира също в GameOfLife
. Изобщо, всичко е добре да е капсуловано вътре.
- Не слагай интервали веднага след дефиницията на клас и веднага преди затварящия
end
. - Също, като дефинираш едноредов блок, слагай интервали около
{
и}