# 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