blob: d61834aa5e829c01e9da3ba547fe665a7b5aa71f (
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
68
|
# frozen_string_literal: true
require "game_of_life/version"
require "game_of_life/plane"
require "game_of_life/universe"
require "game_of_life/cell"
# Game of Life module entry point
module GameOfLife
# Base Error class
class Error < StandardError; end
class << self
# Generate a universe based on the options (from an input file/URI) or using a random/passed seed
# This method also sets the Classes/Modules constants for the run defining the options for
# Cell (Dead/Live) state representations, and the delay introduced after rendering each universe/generation
# and the banner for the info/options
#
# @param options [Hash] CLI options to generate initial conditions
# @option options [String | nil] "input" path to a local file or URL to open
# @option options [Numeric] "seed" number to use if no "input" is provided (defaults to random)
# @option options [Numeric] "width" of the universe
# @option options [Numeric] "height" of the universe
# @option options [Numeric] "delay" introduced after each cycle
# @option options [String] "live-cell" representation
# @option options [String] "dead-cell" representation
# @return [GameOfLife::Universe] populated with the parsed input/seed
def generate(options)
# Define the constants for Cell representation
GameOfLife::Cell.const_set(:LIVE_CELL, options["live-cell"])
GameOfLife::Cell.const_set(:DEAD_CELL, options["dead-cell"])
# Define the constant used for delay
GameOfLife.const_set(:DELAY, options["delay"].to_f)
banner = options["input"] ? "Input: #{options['input']}" : "Seed: #{options['seed']}"
# Define the constant used for banner info
GameOfLife.const_set(:BANNER, banner)
return GameOfLife::Generators::Input.new(options) if options["input"]
GameOfLife::Generators::Seed.new(options)
end
# The infinite running loop for rendering the current state of a universe
# and then evolving it and repeating.
def run(universe)
Kernel.loop do
GameOfLife.render(universe)
universe.evolve!
end
end
# Private method to do the terminal screen/scrollback buffer cleaning
# and rendering of the current universe/banner info
# based on the delay configured by the user
def render(universe)
puts "\33c\e[3J" # Clears the screen and scrollback buffer.
puts universe.to_s
puts BANNER
sleep(DELAY / 1000.0)
end
end
# Generators module for generating the universe initial state
module Generators
autoload :Input, "game_of_life/generators/input.rb"
autoload :Seed, "game_of_life/generators/seed.rb"
end
end
|