rsb-gol 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9ef22276b52a97905119dbe734de22ed401c2be8
4
+ data.tar.gz: 95655cba534297d4a7161bad0ce80ea346382a60
5
+ SHA512:
6
+ metadata.gz: 9576085d3d4eb0fe36490a34bb269660248dd4d28fb910e86b16d52d9db66f183386ad58ba16337f576f9491a9b7abb17974247488768b7eefb1e55e399880b2
7
+ data.tar.gz: 22cf78a39f829303d8ba59572e5a824784a29c3bd8197b733d35f06eda9a7a32c1d5a759aae3bbf8083a474c9643082f7105d75d4155be7756e3f967442ca8d1
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --require rsb/gol
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.3
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rsb-gol.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Robert Scott-Buccleuch
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Conway's Game Of Life
2
+ The "game" is a zero-player game, meaning that its evolution is determined by
3
+ its initial state, requiring no further input. One interacts with the Game of
4
+ Life by creating an initial configuration and observing how it evolves or, for
5
+ advanced players, by creating patterns with particular properties.
6
+
7
+ ## Rules
8
+ The universe of the Game of Life is an infinite two-dimensional orthogonal grid
9
+ of square cells, each of which is in one of two possible states, alive or dead.
10
+ Every cell interacts with its eight neighbours, which are the cells that are
11
+ horizontally, vertically, or diagonally adjacent. At each step in time, the
12
+ following transitions occur:
13
+
14
+ 1. Any live cell with fewer than two live neighbours dies, as if caused by
15
+ under-population.
16
+ 2. Any live cell with two or three live neighbours lives on to the next generation.
17
+ 3. Any live cell with more than three live neighbours dies, as if by overcrowding.
18
+ 4. Any dead cell with exactly three live neighbours becomes a live cell, as if by
19
+ reproduction.
20
+
21
+ The initial pattern constitutes the seed of the system. The first generation is
22
+ created by applying the above rules simultaneously to every cell in the
23
+ seed—births and deaths occur simultaneously, and the discrete moment at which
24
+ this happens is sometimes called a tick (in other words, each generation is a
25
+ pure function of the preceding one). The rules continue to be applied repeatedly
26
+ to create further generations.
27
+
28
+ [read more at wikipedia](http://en.wikipedia.org/wiki/Conway's_Game_of_Life)
29
+
30
+ ## Installation
31
+
32
+ Add this line to your application's Gemfile:
33
+
34
+ ```ruby
35
+ gem 'rsb-gol'
36
+ ```
37
+
38
+ And then execute:
39
+
40
+ $ bundle
41
+
42
+ Or install it yourself as:
43
+
44
+ $ gem install rsb-gol
45
+
46
+ ## Usage
47
+
48
+ TODO: Write usage instructions here
49
+
50
+ ## Development
51
+
52
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
53
+
54
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
55
+
56
+ ## Contributing
57
+
58
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rsb-gol. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
59
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rsb/gol"
5
+ require "pry"
6
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/gol ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require "bundler/setup"
3
+ require "rsb/gol"
4
+
5
+ Rsb::Gol::Cli.start
data/lib/rsb/gol.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "rsb/gol/version"
2
+ require "rsb/gol/grid"
3
+ require "rsb/gol/universe"
4
+ require "rsb/gol/game"
5
+ require "rsb/gol/cli"
6
+
7
+ module Rsb
8
+ module Gol
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ require 'thor'
2
+
3
+ module Rsb
4
+ module Gol
5
+ class Cli < Thor
6
+ desc 'start', 'start the game of life'
7
+ def start
8
+ # ✺ ☻ ⬣ ● ⨀
9
+ Rsb::Gol::Game.new.start(1000,'●',' ')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,55 @@
1
+ module Rsb
2
+ module Gol
3
+ class Game
4
+ CLEAR_SCREEN_CHAR = "\e[H\e[2J"
5
+
6
+ attr_reader :universe
7
+
8
+ def initialize(options = {})
9
+ grid = Rsb::Gol::Grid.new(options[:rows] || 40, options[:cols] || 40)
10
+ @universe = options[:universe] || Rsb::Gol::Universe.new(grid: grid)
11
+ end
12
+
13
+ def clear_screen
14
+ puts CLEAR_SCREEN_CHAR
15
+ end
16
+
17
+ def seed
18
+ coords = [
19
+ [25, 1],
20
+ [23, 2], [25, 2],
21
+ [13, 3], [14, 3], [21, 3], [22, 3],
22
+ [12, 4], [16, 4], [21, 4], [22, 4], [35, 4], [36, 4],
23
+ [1, 5], [2, 5], [11, 5], [17, 5], [21, 5], [22, 5], [35, 5], [36, 5],
24
+ [1, 6], [2, 6], [11, 6], [15, 6], [17, 6], [18, 6], [23, 6], [25, 6],
25
+ [11, 7], [17, 7], [25, 7],
26
+ [12, 8], [16, 8],
27
+ [13, 9], [14, 9]
28
+ ]
29
+
30
+ universe.seed(coords)
31
+ end
32
+
33
+ def status_line(data)
34
+ "@@@ generation clock: #{data[:clock]} " +
35
+ "deaths: #{data[:deaths]} births: #{data[:births]}"
36
+ end
37
+
38
+ def start(iterations = 1000, alive='0', dead=' ', step=3)
39
+ clear_screen
40
+ seed
41
+ iterations.times do
42
+ data = universe.tick!
43
+ abort('empty universe') if data[:empty_universe]
44
+ status = status_line(data)
45
+ output = universe.visualize(alive, dead)
46
+
47
+ clear_screen
48
+
49
+ puts "#{output}\n\n #{status}\n"
50
+ sleep(1.0/ step)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,97 @@
1
+ require 'matrix'
2
+
3
+ module Rsb
4
+ module Gol
5
+ class Grid
6
+ TOP_RIGHT_CORNER = "┏"
7
+ TOP_LEFT_CORNER = "┓"
8
+ BOTTOM_RIGHT_CORNER = "┛"
9
+ BOTTOM_LEFT_CORNER = "┛"
10
+ HORIZONTAL_BAR = "━"
11
+ VERTICAL_BAR = "┃"
12
+ NEIGHBOR_NAMES = [
13
+ :north, :north_east, :north_west,
14
+ :east, :west,
15
+ :south, :south_east, :south_west
16
+ ]
17
+
18
+ attr_reader :rows, :columns, :top_border, :bottom_border
19
+
20
+ def initialize(rows, columns)
21
+ @rows = rows
22
+ @columns = columns
23
+ @matrix = Matrix.zero(rows, columns)
24
+ hbar = HORIZONTAL_BAR * columns
25
+ @top_border = TOP_RIGHT_CORNER + hbar + TOP_LEFT_CORNER
26
+ @bottom_border = BOTTOM_RIGHT_CORNER + hbar + BOTTOM_LEFT_CORNER
27
+ end
28
+
29
+ def spawn(x, y)
30
+ fail "coordinates #{x},#{y} are out of bounds" if out_of_bounds?(x,y)
31
+ @matrix.send(:[]=, x, y, 1)
32
+ end
33
+
34
+ def kill(x, y)
35
+ fail "coordinates #{x},#{y} are out of bounds" if out_of_bounds?(x,y)
36
+ @matrix.send(:[]=, x, y, 0)
37
+ end
38
+
39
+ def cell(x, y)
40
+ @matrix[x, y]
41
+ end
42
+
43
+ def out_of_bounds?(x, y)
44
+ x < 0 || y < 0 || x > rows - 1 || y > columns - 1
45
+ end
46
+
47
+ # Collects all live cells in a given neighborhood. A neighborhood is
48
+ # defined as all other cells within on cell from the coordinates given.
49
+ # At most a cell can have neighborhood of 8 cells, boundry cells will only
50
+ # have 3 cell neighborhoods
51
+ def neighborhood(x, y)
52
+ neighbors = []
53
+ NEIGHBOR_NAMES.each do |name|
54
+ nx, ny = neighbor_coordinates(name, x, y)
55
+ next if out_of_bounds?(nx, ny)
56
+ state = cell(nx, ny)
57
+ neighbors << state if state == 1
58
+ end
59
+
60
+ neighbors
61
+ end
62
+
63
+ def neighbor_coordinates(neighbor, x, y)
64
+ case neighbor
65
+ when :north then [x - 1, y]
66
+ when :north_east then [x - 1, y - 1]
67
+ when :north_west then [x - 1, y + 1]
68
+ when :east then [x, y - 1]
69
+ when :west then [x, y + 1]
70
+ when :south then [x + 1, y]
71
+ when :south_east then [x + 1, y - 1]
72
+ when :south_west then [x + 1, y + 1]
73
+ end
74
+ end
75
+
76
+ def cell_neighbors
77
+ @matrix.each_with_index do |state, x, y|
78
+ yield(state, x, y, neighborhood(x,y))
79
+ end
80
+ end
81
+
82
+ def visualize(alive = 'o', dead = ' ')
83
+ body = ''
84
+ vbar = VERTICAL_BAR
85
+ line = ''
86
+ @matrix.each_with_index do |state, x, y|
87
+ line << (state == 1 ? alive : dead)
88
+ if y + 1 == columns
89
+ body << "#{vbar}#{line}#{vbar}\n"
90
+ line = ''
91
+ end
92
+ end
93
+ "#{top_border}\n#{body}#{bottom_border}\n"
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,68 @@
1
+ require 'matrix'
2
+
3
+ module Rsb
4
+ module Gol
5
+ class Universe
6
+ DEFAULT_ROWS = 50
7
+ DEFAULT_COLUMNS = 50
8
+ attr_reader :clock
9
+
10
+ def initialize(options = {})
11
+ @grid = if options[:grid]
12
+ options[:grid]
13
+ elsif options[:cols] && options[:rows]
14
+ Rsb::Gol::Grid.new(options[:rows], options[:cols])
15
+ else
16
+ Rsb::Gol::Grid.new(DEFAULT_ROWS, DEFAULT_COLUMNS)
17
+ end
18
+ @clock = 0
19
+ end
20
+
21
+ def evolution
22
+ deaths = []
23
+ births = []
24
+
25
+ @grid.cell_neighbors do |state, x, y, neighbors|
26
+ if state == 1
27
+ deaths << [x, y] if neighbors.size < 2 || neighbors.size > 3
28
+ end
29
+
30
+ if state == 0
31
+ births << [x, y] if neighbors.size == 3
32
+ end
33
+ end
34
+
35
+ { deaths: deaths, births: births }
36
+ end
37
+
38
+ def populate(population)
39
+ population[:deaths].each {|(x, y)| @grid.kill(x, y)}
40
+ population[:births].each {|(x, y)| @grid.spawn(x, y)}
41
+ {
42
+ deaths: population[:deaths].size,
43
+ births: population[:births].size
44
+ }
45
+ end
46
+
47
+ def seed(coords)
48
+ coords.each do |x, y|
49
+ @grid.spawn(x,y)
50
+ end
51
+ end
52
+
53
+ def visualize(alive = 'o', dead = ' ')
54
+ @grid.visualize(alive, dead)
55
+ end
56
+
57
+ def tick!
58
+ @clock += 1
59
+ stats = populate(evolution())
60
+ {
61
+ empty_universe: stats[:deaths] == 0 && stats[:births] == 0,
62
+ population: stats,
63
+ clock: clock
64
+ }
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ module Rsb
2
+ module Gol
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
data/rsb-gol.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rsb/gol/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rsb-gol"
8
+ spec.version = Rsb::Gol::VERSION
9
+ spec.authors = ["Robert Scott-Buccleuch"]
10
+ spec.email = ["rsb.code@gmail.com"]
11
+ spec.license = "MIT"
12
+ spec.summary = %q{command line implementation of game of life}
13
+ spec.homepage = "https://github.com/rsb/rsb-gol"
14
+
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "thor", "0.19.1"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.10"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "pry", "~> 0.10.1"
28
+ spec.add_development_dependency "rspec", "~> 3.2.0"
29
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rsb-gol
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Robert Scott-Buccleuch
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-06-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.19.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.19.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.10.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.10.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 3.2.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.2.0
83
+ description:
84
+ email:
85
+ - rsb.code@gmail.com
86
+ executables:
87
+ - gol
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - CODE_OF_CONDUCT.md
95
+ - Gemfile
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - bin/console
100
+ - bin/setup
101
+ - exe/gol
102
+ - lib/rsb/gol.rb
103
+ - lib/rsb/gol/cli.rb
104
+ - lib/rsb/gol/game.rb
105
+ - lib/rsb/gol/grid.rb
106
+ - lib/rsb/gol/universe.rb
107
+ - lib/rsb/gol/version.rb
108
+ - rsb-gol.gemspec
109
+ homepage: https://github.com/rsb/rsb-gol
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.4.7
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: command line implementation of game of life
133
+ test_files: []