blob: f4296ddbfbb5a0b5eda76ff37ee8b31cb13e861a (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# frozen_string_literal: true
require "forwardable"
module GameOfLife
# Representation of the current and future state of the game of life universe
class Universe
extend Forwardable
delegate :[] => :@current
delegate :[]= => :@current
# Initialize the empty initial universe 2D plane (circular arrays)
# @param width [Integer] the width of the universe array
# @param height [Integer] the height of the universe array
def initialize(width:, height:)
@current = GameOfLife::Plane.new(height) { GameOfLife::Plane.new(width) }
@future = GameOfLife::Plane.new(height) { GameOfLife::Plane.new(width) }
end
# Representation of the game of life universe
# @return [String] representing the current state
# @see GameOfLife::Cell#to_s
def to_s
@current.map(&:join).join("\n")
end
# Update the current state of the universe (according to the game of life laws) and
# set the current state to the next future generation
#
# This have computational order `O(n^2) = O(width * height)`
# It loops over all the universe cells and evolves them to the next generation
# @see #neighbors
def evolve!
@current.each do |row|
row.each do |cell|
@future[cell.y][cell.x] = cell.evolve!(neighbors(cell))
end
end
@current = Marshal.load(Marshal.dump(@future))
end
# Return the array of all the neighboring cells using the circular universe array, <br/>
# given a cell "C" in a universe of cells "." the immediate neighbors would be "x" as in
# the following different examples
#
# ..... | .xxx. | .xCx. | xCx.. | Cx..x | xx..x |
# .xxx. | .xCx. | .xxx. | xxx.. | xx..x | Cx..x |
# .xCx. | .xxx. | ..... | ..... | ..... | xx..x |
# .xxx. | ..... | ..... | ..... | ..... | ..... |
# ..... | ..... | .xxx. | xxx.. | xx..x | ..... |
#
# @param cell [GameOfLife::Cell] the to return the neighboring cells from the universe current plane
# @return [Array<GameOfLife::Cell>] of all the immediate neighboring cells
# @smell AbcSize higher than configuration, but needed to return the neighboring cells array
#
# rubocop:disable Metrics/AbcSize
private def neighbors(cell)
x, y = cell.x, cell.y # rubocop:disable Style/ParallelAssignment
[
@current[y - 1][x - 1], @current[y - 1][x], @current[y - 1][x + 1],
@current[y][x - 1], @current[y][x + 1],
@current[y + 1][x - 1], @current[y + 1][x], @current[y + 1][x + 1]
]
end
# rubocop:enable Metrics/AbcSize
end
end
|