class Life::Board

Attributes

height[R]
width[R]

Public Class Methods

from_array(cells) click to toggle source
# File lib/life/board.rb, line 35
def self.from_array(cells)
  width = cells[0].size
  height = cells.size
  board = new(width, height)
  board.update_from_array(cells)
  board
end
from_text(text) click to toggle source
# File lib/life/board.rb, line 43
def self.from_text(text)
  lines = text.split("\n")

  width = lines[0].size
  height = lines.size
  board = Life::Board.new(width, height)

  lines.each_with_index do |line, y|
    line.each_char.with_index do |char, x|
      board[x, y] = (char == "#")
    end
  end

  board
end
new(width, height) click to toggle source
# File lib/life/board.rb, line 5
def initialize(width, height)
  if width < 3 || height < 3
    raise ArgumentError.new("Life Board dimensions must be bigger than 3")
  end

  @width = width
  @height = height
  @cells = Array.new(height) do
    Array.new(width) { false }
  end
end

Public Instance Methods

[](x, y) click to toggle source
# File lib/life/board.rb, line 17
def [](x, y)
  wx, wy = wrapped_coords(x, y)
  @cells[wy][wx]
end
[]=(x, y, value) click to toggle source
# File lib/life/board.rb, line 22
def []=(x, y, value)
  wx, wy = wrapped_coords(x, y)
  @cells[wy][wx] = value
end
clone() click to toggle source
# File lib/life/board.rb, line 69
def clone
  self.class.from_array(@cells)
end
count_neighbors(x, y) click to toggle source
# File lib/life/board.rb, line 59
def count_neighbors(x, y)
  count = 0

  each_neighbor(x, y) do |nx, ny, alive|
    count += 1 if alive
  end

  count
end
each() { |x, y, self| ... } click to toggle source
# File lib/life/board.rb, line 73
def each
  (0...height).each do |y|
    (0...width).each do |x|
      yield x, y, self[x, y]
    end
  end
end
each_neighbor(x, y) { |nx, ny, self| ... } click to toggle source
# File lib/life/board.rb, line 81
def each_neighbor(x, y)
  (-1..1).each do |dy|
    (-1..1).each do |dx|
      next if dx == 0 && dy == 0

      nx = x + dx
      ny = y + dy
      yield nx, ny, self[nx, ny]
    end
  end
end
tick() click to toggle source
# File lib/life/board.rb, line 93
def tick
  old_board = clone()
  each do |x, y, alive|
    neighbor_count = old_board.count_neighbors(x, y)

    if alive
      self[x, y] = (2..3).include?(neighbor_count)
    else
      self[x, y] = (neighbor_count == 3)
    end
  end
end
to_a() click to toggle source
# File lib/life/board.rb, line 27
def to_a
  clone_2d_array(@cells)
end
update_from_array(cells) click to toggle source
# File lib/life/board.rb, line 31
def update_from_array(cells)
  @cells = clone_2d_array(cells)
end

Private Instance Methods

clone_2d_array(arr) click to toggle source
# File lib/life/board.rb, line 108
def clone_2d_array(arr)
  arr.map { |row| row.clone }
end
wrapped_coords(x, y) click to toggle source
# File lib/life/board.rb, line 112
def wrapped_coords(x, y)
  [x % width, y % height]
end