summaryrefslogtreecommitdiffstats
path: root/CLI/ruby
diff options
context:
space:
mode:
authora14m <[email protected]>2020-12-14 12:59:41 +0100
committera14m <[email protected]>2020-12-14 12:59:41 +0100
commit674a838588d3d1f8700bd1553b56b3e63c22db55 (patch)
tree0907f8b79b78667eeeaf1d1957746367a749c061 /CLI/ruby
parentb7bc6ff98bae87409f28f9d8dc210a60998a2812 (diff)
Add parsing method to get the defaults and fix negative issues
Diffstat (limited to 'CLI/ruby')
-rw-r--r--CLI/ruby/lib/game_of_life.rb45
1 files changed, 45 insertions, 0 deletions
diff --git a/CLI/ruby/lib/game_of_life.rb b/CLI/ruby/lib/game_of_life.rb
index 879c527..a2ce27a 100644
--- a/CLI/ruby/lib/game_of_life.rb
+++ b/CLI/ruby/lib/game_of_life.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+require "io/console"
require "game_of_life/version"
require "game_of_life/plane"
require "game_of_life/universe"
@@ -11,6 +12,50 @@ module GameOfLife
class Error < StandardError; end
class << self
+ # Validate and parse the CLI options and set defaults for the dynamic 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 | nil] "seed" number to use if no "input" is provided
+ # @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
+ # @smell AbcSize, MethodLenght, Cyclomatic and Perceived Complexity needed for parsing and validating options
+ # rubocop:disable Metrics/AbcSize
+ # rubocop:disable Metrics/MethodLength
+ # rubocop:disable Metrics/CyclomaticComplexity
+ # rubocop:disable Metrics/PerceivedComplexity
+ # return [Hash] of the parsed options with dynamic defaults based on window size and kernel random
+ def parsed_options(options)
+ max_height = IO.console.winsize[0] - 2
+ max_width = IO.console.winsize[1]
+
+ if options["delay"].to_i.negative?
+ fail GameOfLife::Error, "Invalid --delay value. must be positive value (sadly this is how time works -so far-)"
+ end
+ if (options["width"]&.< 1) || (options["width"]&.> max_width)
+ fail GameOfLife::Error, "Invalid --width value. " \
+ "must be between 1 and #{max_width} (current terminal width)"
+ end
+ if (options["height"]&.< 1) || (options["height"]&.> max_height)
+ fail GameOfLife::Error, "Invalid --height value. " \
+ "must be between 1 and #{max_height} (current terminal height)"
+ end
+
+ {
+ # Defaults the hight to less then the height of the terminal to allow banner info
+ # and an extra emtpy line to avoid triggering terminal scroll while flushing
+ "height" => max_height,
+ "width" => max_width,
+ "seed" => rand(100_000),
+ }.merge(options)
+ end
+ # rubocop:enable Metrics/AbcSize
+ # rubocop:enable Metrics/MethodLength
+ # rubocop:enable Metrics/CyclomaticComplexity
+ # rubocop:enable Metrics/PerceivedComplexity
+
# 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