terminal_game_of_life 1.0.0 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b949e4ff807eb374946cc0c2647f9aa5cf3f79b2427cab818b492ecdbb9a3b24
4
- data.tar.gz: b0e82c40b3c53972f52382728281cc2b83219835ffe1ad65c89f9e446beadf02
3
+ metadata.gz: 2f01833ac38b2fcfb9f8ea6581642e2d95a9f40521d79773178c5499e23a2530
4
+ data.tar.gz: 5f8540b420def7ca4eb0a9371140419bd47489089bed0c5f68f204a266d9946c
5
5
  SHA512:
6
- metadata.gz: 96e1fd3c329a3d775a7d332351303c53a2767857ccef421ad372ec8abbebae7bd4f7d07ae2ad23210cd360d889d21fa7ccafc6c9dc08388a6ffb967dd44afa52
7
- data.tar.gz: 8674f279918813b3cf8c4ee1ed9a2d257c48755a3c06e687a2f5f17cdf6707e85509277042e3176d6eaa5e7c69ae143bc5d4e996572a55fa73900c2bc8e9ac1d
6
+ metadata.gz: 3fbf0db73b5fb37de4b2565813f4ba5ab5500930630fea8151f627b972ed7ef1bdfd95253675da6160451734b9d24d688802e92a36532140b1920fdb4b45d00e
7
+ data.tar.gz: ec4959be702a801f10229c9f85edcd148326d60d919c6b099c1bcd0b06a8f2b1efb24fa225121d14ab28f6239583ab05aacde14c659e74c77ff2262e7b466e8f
data/README.md CHANGED
@@ -9,7 +9,11 @@ $ gem install terminal_game_of_life
9
9
 
10
10
  ## Usage
11
11
 
12
- Run `$game-of-life -i https://gitlab.com/a14m --live-cell +`
12
+ ```bash
13
+ $game-of-life -i https://meta.sr.ht/~a14m.keys --live-cell +
14
+ $game-of-life -i /path/to/file.txt --height 35 --width 35
15
+ $game-of-life -s 1337 --delay 250
16
+ ```
13
17
 
14
18
  Check `game-of-life --help` for usage info.
15
19
 
@@ -26,7 +30,7 @@ Options:
26
30
  [--height=HEIGHT] # Specify the hight of generated universe. (default to terminal height)
27
31
  [--dead-cell=CHAR] # Specify the dead-cell representation
28
32
  # Default:
29
- [--live-cell=CHAR] # Specify the dead-cell representation
33
+ [--live-cell=CHAR] # Specify the live-cell representation
30
34
  # Default: █
31
35
  -d, [--delay=Milli-Seconds] # Specify the introduced delay between each generation
32
36
  # Default: 50
@@ -40,14 +44,15 @@ Options:
40
44
  - Clone the repo.
41
45
  - Navigate to the ruby CLI implementation `cd game-of-life/CLI/ruby`.
42
46
  - run `bundle install` to install dependencies.
43
- - run `bundle rake build` to build the gem/CLI into the `pkg` directory.
44
- - run `bundle rake install` to build and install gem/CLI into system gems.
47
+ - you can run `bundle rake build` to build the gem/CLI into the `pkg` directory.
48
+ - you can run `bundle rake install` to build and install gem/CLI into system gems.
49
+ - you can run `bundle exec ./bin/game-of-life` to run the code for development/testing purposes
45
50
 
46
51
  ## Linting
47
52
  Run `bundle exec rubocop`
48
53
 
49
54
  ## Testing
50
- Run `bundle exec rspec` or `bundle exec rake spec`
55
+ Run `bundle exec rspec`
51
56
 
52
57
  ## Documentation
53
58
  Run `bundle exec yard`
@@ -56,12 +61,12 @@ Run `bundle exec yard`
56
61
  - Update the [version](./lib/game_of_live/version.rb) number
57
62
  - Run `bundle install` and commit changes
58
63
  - Update the [CHANGELOG](./CHANGELOG.md)
59
- - Create a git(lab) tag `ruby/v#{version_number}` ex: `ruby/v0.1.1-pre`
64
+ - Create a git tag `ruby/v#{version_number}` ex: `ruby/v0.1.1-pre`
60
65
 
61
66
  The tag will automatically trigger the release workflow after successful build/test
62
67
  and release the changes to [rubygems.org](https://rubygems.org/gems/terminal_game_of_life)
63
68
 
64
69
  ## Extra information
65
- ### [Contributing](https://gitlab.com/a14m/game-of-life/-/blob/master/CONTRIBUTING.md)
66
- ### [License](https://gitlab.com/a14m/game-of-life/-/blob/master/LICENSE.md)
67
- ### [Code of Conduct](https://gitlab.com/a14m/game-of-life/-/blob/master/CODE_OF_CONDUCT.md)
70
+ ### [Contributing](../../CONTRIBUTING.md)
71
+ ### [License](../../LICENSE.md)
72
+ ### [Code of Conduct](../../CODE_OF_CONDUCT.md)
data/bin/game-of-life CHANGED
@@ -3,13 +3,12 @@
3
3
 
4
4
  require "game_of_life"
5
5
  require "thor"
6
- require "io/console"
7
6
 
8
7
  class CLI < Thor
9
8
  map %w[-v --version] => :version
10
9
  desc "--version, -v", "Prints the Game of Life version information"
11
10
  def version
12
- puts "Game of Life version #{GameOfLife::VERSION}"
11
+ print "Game of Life version #{GameOfLife::VERSION}"
13
12
  end
14
13
 
15
14
  default_task :start
@@ -30,35 +29,14 @@ class CLI < Thor
30
29
  desc: "Specify the dead-cell representation"
31
30
 
32
31
  class_option "live-cell", type: :string, banner: :CHAR, default: "\u2588",
33
- desc: "Specify the dead-cell representation"
32
+ desc: "Specify the live-cell representation"
34
33
 
35
34
  class_option "delay", aliases: "-d", type: :numeric, banner: "Milli-Seconds", default: 50,
36
35
  desc: "Specify the introduced delay between each generation"
37
- # rubocop:disable Metrics/AbcSize
38
- # rubocop:disable Metrics/MethodLength
39
36
  def start
40
- max_height = IO.console.winsize[0] - 2
41
- max_width = IO.console.winsize[1]
42
- if options["width"]&.> max_width
43
- fail GameOfLife::Error, "Invalid --width value, must not exceed current terminal width: #{max_width}"
44
- end
45
- if options["height"]&.> max_height
46
- fail GameOfLife::Error, "Invalid --height value, must not exceed current terminal height: #{max_height}"
47
- end
48
-
49
- options_with_console_defaults = {
50
- # Defaults the hight to less then the height of the terminal to allow banner info
51
- # and an extra emtpy line to avoid triggering terminal scroll while flushing
52
- "height" => max_height,
53
- "width" => max_width,
54
- "seed" => rand(100_000),
55
- }.merge(options)
56
-
57
- universe = GameOfLife.generate(options_with_console_defaults)
37
+ universe = GameOfLife.generate(GameOfLife.parsed_options(options))
58
38
  GameOfLife.run(universe)
59
39
  end
60
- # rubocop:enable Metrics/AbcSize
61
- # rubocop:enable Metrics/MethodLength
62
40
 
63
41
  class << self
64
42
  # Allow exit with status 1 on failure
@@ -72,8 +50,10 @@ end
72
50
  begin
73
51
  CLI.start(ARGV)
74
52
  rescue SystemExit, Interrupt
75
- "Do nothing when user exits with Interrupt (CMD/Ctrl + C)"
53
+ # Print Seed/File used in previous run when user exits with Interrupt (CMD/Ctrl + C)
54
+ print "\e[?1049l"
55
+ print "#{GameOfLife::BANNER}\n\e[0m"
76
56
  rescue NotImplementedError, GameOfLife::Error => e
77
- puts e.message
57
+ print e.message
78
58
  exit(-1)
79
59
  end
data/game_of_life.gemspec CHANGED
@@ -10,15 +10,15 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = "Game of Life CLI"
12
12
  spec.description = "Conway's game of life implementation as a CLI ruby gem."
13
- spec.homepage = "https://gitlab.com/a14m/game-of-life"
13
+ spec.homepage = "https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/README.md"
14
14
  spec.license = "MIT"
15
15
  spec.required_ruby_version = ">= 2.5.0"
16
16
 
17
17
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
18
  spec.metadata["homepage_uri"] = spec.homepage
19
- spec.metadata["source_code_uri"] = "https://gitlab.com/a14m/game-of-life/-/tree/master/CLI/ruby/"
19
+ spec.metadata["source_code_uri"] = "https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby"
20
20
  spec.metadata["documentation_uri"] = "https://rubydoc.info/gems/terminal_game_of_life"
21
- spec.metadata["changelog_uri"] = "https://gitlab.com/a14m/game-of-life/-/blob/master/CLI/ruby/CHANGELOG.md"
21
+ spec.metadata["changelog_uri"] = "https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/CHANGELOG.md"
22
22
 
23
23
  spec.executables = ["game-of-life"]
24
24
  spec.require_paths = ["lib"]
@@ -31,6 +31,10 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "rake"
32
32
  spec.add_development_dependency "rspec"
33
33
  spec.add_development_dependency "rubocop"
34
+ spec.add_development_dependency "rubocop-rspec"
35
+ # Code Coverage dependencies
36
+ spec.add_development_dependency "codecov"
37
+ spec.add_development_dependency "simplecov"
34
38
  # Documentation dependencies
35
39
  spec.add_development_dependency "redcarpet"
36
40
  spec.add_development_dependency "yard"
data/lib/game_of_life.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "io/console"
3
4
  require "game_of_life/version"
4
5
  require "game_of_life/plane"
5
6
  require "game_of_life/universe"
@@ -11,6 +12,58 @@ module GameOfLife
11
12
  class Error < StandardError; end
12
13
 
13
14
  class << self
15
+ # Validate and parse the CLI options and set defaults for the dynamic options.
16
+ # @param options [Hash] CLI options to generate initial conditions
17
+ # @option options [String | nil] "input" path to a local file or URL to open
18
+ # @option options [Numeric | nil] "seed" number to use if no "input" is provided
19
+ # @option options [Numeric] "width" of the universe
20
+ # @option options [Numeric] "height" of the universe
21
+ # @option options [Numeric] "delay" introduced after each cycle
22
+ # @option options [String] "live-cell" representation
23
+ # @option options [String] "dead-cell" representation
24
+ # @smell AbcSize, MethodLenght, Cyclomatic and Perceived Complexity needed for parsing and validating options
25
+ # rubocop:disable Metrics/AbcSize
26
+ # rubocop:disable Metrics/MethodLength
27
+ # rubocop:disable Metrics/CyclomaticComplexity
28
+ # rubocop:disable Metrics/PerceivedComplexity
29
+ # return [Hash] of the parsed options with dynamic defaults based on window size and kernel random
30
+ def parsed_options(options)
31
+ max_height = IO.console.winsize[0] - 2
32
+ max_width = IO.console.winsize[1]
33
+
34
+ if options["delay"].to_i.negative?
35
+ fail GameOfLife::Error, "Invalid --delay value. must be positive value (sadly this is how time works -so far-)"
36
+ end
37
+ if (options["width"]&.< 1) || (options["width"]&.> max_width)
38
+ fail GameOfLife::Error, "Invalid --width value. " \
39
+ "must be between 1 and #{max_width} (current terminal width)"
40
+ end
41
+ if (options["height"]&.< 1) || (options["height"]&.> max_height)
42
+ fail GameOfLife::Error, "Invalid --height value. " \
43
+ "must be between 1 and #{max_height} (current terminal height)"
44
+ end
45
+
46
+ fail GameOfLife::Error, "Invalid --live-cell value. must be a single character" if options["live-cell"].length > 1
47
+
48
+ fail GameOfLife::Error, "Invalid --dead-cell value. must be a single character" if options["dead-cell"].length > 1
49
+
50
+ if options["dead-cell"] == options["live-cell"]
51
+ fail GameOfLife::Error, "Invalid --dead-cell value. must be a different character than --live-cell"
52
+ end
53
+
54
+ {
55
+ # Defaults the hight to less then the height of the terminal to allow banner info
56
+ # and an extra emtpy line to avoid triggering terminal scroll while flushing
57
+ "height" => max_height,
58
+ "width" => max_width,
59
+ "seed" => rand(100_000),
60
+ }.merge(options)
61
+ end
62
+ # rubocop:enable Metrics/AbcSize
63
+ # rubocop:enable Metrics/MethodLength
64
+ # rubocop:enable Metrics/CyclomaticComplexity
65
+ # rubocop:enable Metrics/PerceivedComplexity
66
+
14
67
  # Generate a universe based on the options (from an input file/URI) or using a random/passed seed
15
68
  # This method also sets the Classes/Modules constants for the run defining the options for
16
69
  # Cell (Dead/Live) state representations, and the delay introduced after rendering each universe/generation
@@ -53,9 +106,13 @@ module GameOfLife
53
106
  # and rendering of the current universe/banner info
54
107
  # based on the delay/cell configured by the user
55
108
  def render(universe)
56
- puts "\33c\e[3J" # Clears the screen and scrollback buffer.
57
- puts universe.to_s
58
- puts BANNER
109
+ # Use Alternate Screen (\e[?1049h) and move cursor to top left (\e[H)
110
+ # Ref: https://github.com/ruby/ruby/blob/ruby_2_7/lib/irb/easter-egg.rb#L112-L131
111
+ # Ref: https://stackoverflow.com/questions/11023929/using-the-alternate-screen-in-a-bash-script
112
+ # Ref: https://superuser.com/questions/122911/what-commands-can-i-use-to-reset-and-clear-my-terminal
113
+ print "\e[?1049h\e[H"
114
+ print universe.to_s
115
+ print "\n #{BANNER}"
59
116
  sleep(DELAY / 1000.0)
60
117
  end
61
118
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module GameOfLife
4
4
  # Game of life version number
5
- VERSION = "1.0.0"
5
+ VERSION = "1.0.5"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terminal_game_of_life
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - a14m
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-12 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -94,6 +94,48 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: codecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
97
139
  - !ruby/object:Gem::Dependency
98
140
  name: redcarpet
99
141
  requirement: !ruby/object:Gem::Requirement
@@ -141,16 +183,16 @@ files:
141
183
  - lib/game_of_life/plane.rb
142
184
  - lib/game_of_life/universe.rb
143
185
  - lib/game_of_life/version.rb
144
- homepage: https://gitlab.com/a14m/game-of-life
186
+ homepage: https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/README.md
145
187
  licenses:
146
188
  - MIT
147
189
  metadata:
148
190
  allowed_push_host: https://rubygems.org
149
- homepage_uri: https://gitlab.com/a14m/game-of-life
150
- source_code_uri: https://gitlab.com/a14m/game-of-life/-/tree/master/CLI/ruby/
191
+ homepage_uri: https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/README.md
192
+ source_code_uri: https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby
151
193
  documentation_uri: https://rubydoc.info/gems/terminal_game_of_life
152
- changelog_uri: https://gitlab.com/a14m/game-of-life/-/blob/master/CLI/ruby/CHANGELOG.md
153
- post_install_message:
194
+ changelog_uri: https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/CHANGELOG.md
195
+ post_install_message:
154
196
  rdoc_options: []
155
197
  require_paths:
156
198
  - lib
@@ -165,8 +207,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
207
  - !ruby/object:Gem::Version
166
208
  version: '0'
167
209
  requirements: []
168
- rubygems_version: 3.2.0
169
- signing_key:
210
+ rubygems_version: 3.1.4
211
+ signing_key:
170
212
  specification_version: 4
171
213
  summary: Game of Life CLI
172
214
  test_files: []