terminal_game_of_life 0.1.2 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +8 -0
- data/README.md +16 -10
- data/bin/game-of-life +4 -13
- data/game_of_life.gemspec +10 -4
- data/lib/game_of_life.rb +47 -2
- data/lib/game_of_life/generators/input.rb +18 -5
- data/lib/game_of_life/generators/seed.rb +40 -1
- data/lib/game_of_life/version.rb +2 -1
- metadata +52 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c26cd26c1b4aa435be502ab5d4490f9aac0c9b7213349daa3c7c74ff284a62b
|
4
|
+
data.tar.gz: bb7b96d7d61c2d77bb0d23fc900abe6484553f8f8aff384033fa9cba3b2b9d6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 400bfb3d4e758c4b610bbbee25d839969ea9ee2c1e68c5c0d3a29e51d90e3e4cd42d113c2d8f80ab2c89e539c7091220abdbd8cc70fe66c9c9209f163fc8cdbb
|
7
|
+
data.tar.gz: af2edea622e9325201e4c9380b9fea8ebeedb749d6b0cbaaa6b59d154568c5049dac14033c6843cb18242f472a272904eaaa18db7de175e070341e86b2a6db46
|
data/.yardopts
ADDED
data/README.md
CHANGED
@@ -9,44 +9,50 @@ $ gem install terminal_game_of_life
|
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
|
-
|
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
|
|
16
20
|
```
|
21
|
+
Commands:
|
17
22
|
game-of-life --version, -v # Prints the Game of Life version information
|
18
23
|
game-of-life help [COMMAND] # Describe available commands or one specific command
|
19
|
-
game-of-life start [OPTIONS] # Start the Game of Life simulations
|
24
|
+
game-of-life start [OPTIONS] # Start the Game of Life simulations
|
20
25
|
|
21
26
|
Options:
|
22
27
|
-s, [--seed=SEED] # Specify the seed number to use as an initial state (default to random).
|
23
28
|
-i, [--input=VALUE] # Specify the path/URL for the file to use as an initial state. (used instead of seed)
|
24
|
-
|
25
|
-
|
29
|
+
[--width=WIDTH] # Specify the width of generated universe. (default to terminal width)
|
30
|
+
[--height=HEIGHT] # Specify the hight of generated universe. (default to terminal height)
|
26
31
|
[--dead-cell=CHAR] # Specify the dead-cell representation
|
27
|
-
# Default:
|
28
|
-
[--live-cell=CHAR] # Specify the
|
32
|
+
# Default:
|
33
|
+
[--live-cell=CHAR] # Specify the live-cell representation
|
29
34
|
# Default: █
|
30
35
|
-d, [--delay=Milli-Seconds] # Specify the introduced delay between each generation
|
31
36
|
# Default: 50
|
32
37
|
```
|
33
38
|
|
34
39
|
## Demo
|
35
|
-
[![asciicast](https://asciinema.org/a/
|
40
|
+
[![asciicast](https://asciinema.org/a/PsKzaWaNwUq3ZEfrFATqMw0yF.svg)](https://asciinema.org/a/PsKzaWaNwUq3ZEfrFATqMw0yF)
|
36
41
|
|
37
42
|
## Development
|
38
43
|
|
39
44
|
- Clone the repo.
|
40
45
|
- Navigate to the ruby CLI implementation `cd game-of-life/CLI/ruby`.
|
41
46
|
- run `bundle install` to install dependencies.
|
42
|
-
- run `bundle rake build` to build the gem/CLI into the `pkg` directory.
|
43
|
-
- 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
|
44
50
|
|
45
51
|
## Linting
|
46
52
|
Run `bundle exec rubocop`
|
47
53
|
|
48
54
|
## Testing
|
49
|
-
Run `bundle exec rspec`
|
55
|
+
Run `bundle exec rspec`
|
50
56
|
|
51
57
|
## Documentation
|
52
58
|
Run `bundle exec yard`
|
data/bin/game-of-life
CHANGED
@@ -3,7 +3,6 @@
|
|
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
|
@@ -20,30 +19,22 @@ class CLI < Thor
|
|
20
19
|
class_option "input", aliases: "-i", type: :string, banner: :VALUE,
|
21
20
|
desc: "Specify the path/URL for the file to use as an initial state. (used instead of seed)"
|
22
21
|
|
23
|
-
class_option "width",
|
22
|
+
class_option "width", type: :numeric, banner: :WIDTH,
|
24
23
|
desc: "Specify the width of generated universe. (default to terminal width)"
|
25
24
|
|
26
|
-
class_option "height",
|
25
|
+
class_option "height", type: :numeric, banner: :HEIGHT,
|
27
26
|
desc: "Specify the hight of generated universe. (default to terminal height)"
|
28
27
|
|
29
28
|
class_option "dead-cell", type: :string, banner: :CHAR, default: "\s",
|
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
|
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
36
|
def start
|
38
|
-
|
39
|
-
# Defaults the hight to less then the height of the terminal to allow banner info
|
40
|
-
# and an extra emtpy line to avoid triggering terminal scroll while flushing
|
41
|
-
"height" => IO.console.winsize[0] - 3,
|
42
|
-
"width" => IO.console.winsize[1],
|
43
|
-
"seed" => rand(100_000),
|
44
|
-
}.merge(options)
|
45
|
-
|
46
|
-
universe = GameOfLife.generate(options_with_console_defaults)
|
37
|
+
universe = GameOfLife.generate(GameOfLife.parsed_options(options))
|
47
38
|
GameOfLife.run(universe)
|
48
39
|
end
|
49
40
|
|
data/game_of_life.gemspec
CHANGED
@@ -10,17 +10,19 @@ 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://
|
13
|
+
spec.homepage = "https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/README.md"
|
14
14
|
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = ">= 2.
|
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://
|
19
|
+
spec.metadata["source_code_uri"] = "https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby"
|
20
|
+
spec.metadata["documentation_uri"] = "https://rubydoc.info/gems/terminal_game_of_life"
|
21
|
+
spec.metadata["changelog_uri"] = "https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/CHANGELOG.md"
|
20
22
|
|
21
23
|
spec.executables = ["game-of-life"]
|
22
24
|
spec.require_paths = ["lib"]
|
23
|
-
spec.files = Dir["README.md", "game_of_life.gemspec", "bin/game-of-life", "lib/**/*.rb"]
|
25
|
+
spec.files = Dir["README.md", "game_of_life.gemspec", "bin/game-of-life", "lib/**/*.rb", ".yardopts"]
|
24
26
|
|
25
27
|
spec.add_dependency "thor", "~> 1.0"
|
26
28
|
|
@@ -29,6 +31,10 @@ Gem::Specification.new do |spec|
|
|
29
31
|
spec.add_development_dependency "rake"
|
30
32
|
spec.add_development_dependency "rspec"
|
31
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"
|
32
38
|
# Documentation dependencies
|
33
39
|
spec.add_development_dependency "redcarpet"
|
34
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,50 @@ 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
|
+
{
|
47
|
+
# Defaults the hight to less then the height of the terminal to allow banner info
|
48
|
+
# and an extra emtpy line to avoid triggering terminal scroll while flushing
|
49
|
+
"height" => max_height,
|
50
|
+
"width" => max_width,
|
51
|
+
"seed" => rand(100_000),
|
52
|
+
}.merge(options)
|
53
|
+
end
|
54
|
+
# rubocop:enable Metrics/AbcSize
|
55
|
+
# rubocop:enable Metrics/MethodLength
|
56
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
57
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
58
|
+
|
14
59
|
# Generate a universe based on the options (from an input file/URI) or using a random/passed seed
|
15
60
|
# This method also sets the Classes/Modules constants for the run defining the options for
|
16
61
|
# Cell (Dead/Live) state representations, and the delay introduced after rendering each universe/generation
|
@@ -49,9 +94,9 @@ module GameOfLife
|
|
49
94
|
end
|
50
95
|
end
|
51
96
|
|
52
|
-
#
|
97
|
+
# render method to do the terminal screen/scrollback buffer cleaning
|
53
98
|
# and rendering of the current universe/banner info
|
54
|
-
# based on the delay configured by the user
|
99
|
+
# based on the delay/cell configured by the user
|
55
100
|
def render(universe)
|
56
101
|
puts "\33c\e[3J" # Clears the screen and scrollback buffer.
|
57
102
|
puts universe.to_s
|
@@ -14,15 +14,27 @@ module GameOfLife
|
|
14
14
|
# @option options [Numeric] "width" (floored) and used as the width of the universe
|
15
15
|
# @option options [Numeric] "height" (floored) and used as the height of the universe
|
16
16
|
# @return [GameOfLife::Universe] populated with the parsed input
|
17
|
+
# @see ::GameOfLife::Generators::Input.generate_input_data
|
17
18
|
# @see ::GameOfLife::Generators::Input.populate
|
18
19
|
def new(options)
|
20
|
+
width = options["width"].to_i
|
21
|
+
height = options["height"].to_i
|
22
|
+
uri = options["input"]
|
23
|
+
input = generate_input_data(uri: uri)
|
24
|
+
populate(input: input, width: width, height: height)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Generate the seeding data for populating the {GameOfLife::Universe} from input URI
|
28
|
+
# @param uri [String] inputh path to local file or URL to open
|
29
|
+
# @return [Array<Array<True|False>>] covering the defined size of universe
|
30
|
+
# @see ::GameOfLife::Generators::Input.populate
|
31
|
+
private def generate_input_data(uri:)
|
19
32
|
# By design, it's intentional that we use URI.open to to allow seamless file and url access
|
20
|
-
raw = URI.open(
|
33
|
+
raw = URI.open(uri).read.split("\n") # rubocop:disable Security/Open
|
21
34
|
|
22
35
|
# Parse the file and convert it to a boolean 2D array
|
23
36
|
# where any alpha numeric character is considered a living cell (true)
|
24
37
|
raw.map! { |row| row.chars.map { |char| char.match?(/[[:alnum:]]/) } }
|
25
|
-
populate(parsed_input: raw, width: options["width"].to_i, height: options["height"].to_i)
|
26
38
|
rescue ::OpenURI::HTTPError, ::SocketError
|
27
39
|
raise GameOfLife::Error, "URL isn't avaialable, please check it again and make sure the URL is correct"
|
28
40
|
rescue ::Errno::ENOENT
|
@@ -31,16 +43,17 @@ module GameOfLife
|
|
31
43
|
end
|
32
44
|
|
33
45
|
# Populate the {GameOfLife::Universe} with reference to the parsed input 2D array (True/False)
|
34
|
-
# @param
|
46
|
+
# @param input [Array<Array<True|False>>]
|
35
47
|
# @param width [Integer] width of the generated cyclic universe
|
36
48
|
# @param height [Integer] height of the generated cyclic universe
|
37
49
|
# @return [GameOfLife::Universe] populated with the parsed input
|
38
|
-
|
50
|
+
# @see ::GameOfLife::Generators::Input.generate_input_data
|
51
|
+
private def populate(input:, width:, height:)
|
39
52
|
# Generate a universe based on the parsed raw file and fill it with the cells
|
40
53
|
universe = GameOfLife::Universe.new(height: height, width: width)
|
41
54
|
(0...height).each do |i|
|
42
55
|
(0...width).each do |j|
|
43
|
-
cell = { x: j, y: i, alive:
|
56
|
+
cell = { x: j, y: i, alive: input.fetch(i, nil)&.fetch(j, nil) }
|
44
57
|
universe[i][j] = ::GameOfLife::Cell.new(cell)
|
45
58
|
end
|
46
59
|
end
|
@@ -11,8 +11,47 @@ module GameOfLife
|
|
11
11
|
# @option options [Numeric] "width" (floored) and used as the width of the universe
|
12
12
|
# @option options [Numeric] "height" (floored) and used as the height of the universe
|
13
13
|
# @return [GameOfLife::Universe] populated with the parsed input
|
14
|
+
# @see ::GameOfLife::Generators::Seed.generate_seed_data
|
15
|
+
# @see ::GameOfLife::Generators::Seed.populate
|
14
16
|
def new(options)
|
15
|
-
|
17
|
+
width = options["width"].to_i
|
18
|
+
height = options["height"].to_i
|
19
|
+
seed = options["seed"].to_i
|
20
|
+
input = generate_seed_data(seed: seed, width: width, height: height)
|
21
|
+
populate(input: input, width: width, height: height)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Generate the seeding data for populating the {GameOfLife::Universe}
|
25
|
+
# @param seed [Integer] used to generate {Array<"0"|"1">} using Std ruby Random
|
26
|
+
# @param width [Integer] width of the generated cyclic universe
|
27
|
+
# @param height [Integer] height of the generated cyclic universe
|
28
|
+
# @return [Array<Array<True|False>>] covering the defined size of universe
|
29
|
+
# @see ::GameOfLife::Generators::Seed.populate
|
30
|
+
# @see https://ruby-doc.org/core-2.4.0/Random.html
|
31
|
+
private def generate_seed_data(seed:, width:, height:)
|
32
|
+
# Create a pseudo(stable) random generator from the seed
|
33
|
+
# Generate a sequence of bytes to cover the Game of Life Universe plane
|
34
|
+
# each byte can be unpacked into binary data string (ex. "01101011")
|
35
|
+
raw = Random.new(seed).bytes(width * height).unpack1("B*").split("").each_slice(width)
|
36
|
+
raw.map { |row| row.map { |char| char.eql?("1") } }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Populate the {GameOfLife::Universe} with reference to the parsed input 2D array (True/False)
|
40
|
+
# @param input [Array<Array<True|False>>]
|
41
|
+
# @param width [Integer] width of the generated cyclic universe
|
42
|
+
# @param height [Integer] height of the generated cyclic universe
|
43
|
+
# @return [GameOfLife::Universe] populated with the parsed input
|
44
|
+
# @see ::GameOfLife::Generators::Seed.generate_seed_data
|
45
|
+
private def populate(input:, width:, height:)
|
46
|
+
# Generate a universe based on the parsed raw file and fill it with the cells
|
47
|
+
universe = GameOfLife::Universe.new(height: height, width: width)
|
48
|
+
(0...height).each do |i|
|
49
|
+
(0...width).each do |j|
|
50
|
+
cell = { x: j, y: i, alive: input.fetch(i, nil)&.fetch(j, nil) }
|
51
|
+
universe[i][j] = ::GameOfLife::Cell.new(cell)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
universe
|
16
55
|
end
|
17
56
|
end
|
18
57
|
end
|
data/lib/game_of_life/version.rb
CHANGED
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: 0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- a14m
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
11
|
+
date: 2020-12-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
|
@@ -130,6 +172,7 @@ executables:
|
|
130
172
|
extensions: []
|
131
173
|
extra_rdoc_files: []
|
132
174
|
files:
|
175
|
+
- ".yardopts"
|
133
176
|
- README.md
|
134
177
|
- bin/game-of-life
|
135
178
|
- game_of_life.gemspec
|
@@ -140,13 +183,15 @@ files:
|
|
140
183
|
- lib/game_of_life/plane.rb
|
141
184
|
- lib/game_of_life/universe.rb
|
142
185
|
- lib/game_of_life/version.rb
|
143
|
-
homepage: https://
|
186
|
+
homepage: https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/README.md
|
144
187
|
licenses:
|
145
188
|
- MIT
|
146
189
|
metadata:
|
147
190
|
allowed_push_host: https://rubygems.org
|
148
|
-
homepage_uri: https://
|
149
|
-
source_code_uri: https://
|
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
|
193
|
+
documentation_uri: https://rubydoc.info/gems/terminal_game_of_life
|
194
|
+
changelog_uri: https://git.sr.ht/~a14m/game-of-life/tree/master/CLI/ruby/CHANGELOG.md
|
150
195
|
post_install_message:
|
151
196
|
rdoc_options: []
|
152
197
|
require_paths:
|
@@ -155,14 +200,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
200
|
requirements:
|
156
201
|
- - ">="
|
157
202
|
- !ruby/object:Gem::Version
|
158
|
-
version: 2.
|
203
|
+
version: 2.5.0
|
159
204
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
205
|
requirements:
|
161
206
|
- - ">="
|
162
207
|
- !ruby/object:Gem::Version
|
163
208
|
version: '0'
|
164
209
|
requirements: []
|
165
|
-
rubygems_version: 3.1.
|
210
|
+
rubygems_version: 3.1.2
|
166
211
|
signing_key:
|
167
212
|
specification_version: 4
|
168
213
|
summary: Game of Life CLI
|