glimmer-dsl-libui 0.2.21 → 0.2.22

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: 47a6ef9ebfc0564ae4489dc2981baad90d307aa8beaf0b109c8830370db4f02b
4
- data.tar.gz: 3752be2f3972bc7ab9c054444ff99934d4e1e2cb47bb7724059e69b96d6793b0
3
+ metadata.gz: 9ed417f87bfb329535969efe60a61a444d59c7b0e2bdb68196ecf29642b9d628
4
+ data.tar.gz: b0cb2a08fe3ef7d666408bc2dbfa9f6a7ada5151257b55aca2cd11abda09253d
5
5
  SHA512:
6
- metadata.gz: e20361b29c5ccbe1f7a9de7a4929c7384d3db8ca8deafe016ee35e1f239dd2152500018919586e4ad173bb67bfb746fc2a062db449817d33a745a8871b82d455
7
- data.tar.gz: 98b75a7e30e0d05f79b7669e26d3f4afeeeaf19ed57e1acfb56a760c5eb052739f4f4d890840c47eb43b2b841e849f44dd727d0ba0bc06189cfea606cec38380
6
+ metadata.gz: 12e49121d599a00cdf5c3e6638081c8c3d2c6aea263428a1966ce221949d8602fe27c5a03f7506809e5ce877465c5b4b03b909909b8e8c2bba39e698b25f25da
7
+ data.tar.gz: c0e345c1c9e3d1348a6add04910ecd6a4b58934094d2b688253688e8aa860af00613a0c275aac6ace4a97e46f7341b66dc2eebeec511eaa6e36feb4bcfe8d19b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.2.22
4
+
5
+ - examples/snake.rb implemented test-first
6
+
3
7
  ## 0.2.21
4
8
 
5
9
  - examples/tic_tac_toe.rb
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.2.21
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.2.22
2
2
  ## Prerequisite-Free Ruby Desktop Development GUI Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
4
4
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -218,9 +218,10 @@ NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is fe
218
218
  Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interested in:
219
219
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
220
220
  - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
221
+ - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
222
+ - [glimmer-dsl-gtk](https://github.com/AndyObtiva/glimmer-dsl-gtk): Ruby-GNOME Desktop Development GUI Library
221
223
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
222
224
  - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
223
- - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
224
225
 
225
226
  ## Table of Contents
226
227
 
@@ -279,6 +280,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
279
280
  - [Method-Based Custom Keyword](#method-based-custom-keyword)
280
281
  - [Tetris](#tetris)
281
282
  - [Tic Tac Toe](#tic-tac-toe)
283
+ - [Snake](#snake)
282
284
  - [Applications](#applications)
283
285
  - [Manga2PDF](#manga2pdf)
284
286
  - [Befunge98 GUI](#befunge98-gui)
@@ -371,7 +373,7 @@ gem install glimmer-dsl-libui
371
373
  Or install via Bundler `Gemfile`:
372
374
 
373
375
  ```ruby
374
- gem 'glimmer-dsl-libui', '~> 0.2.21'
376
+ gem 'glimmer-dsl-libui', '~> 0.2.22'
375
377
  ```
376
378
 
377
379
  Add `require 'glimmer-dsl-libui'` at the top, and then `include Glimmer` into the top-level main object for testing or into an actual class for serious usage.
@@ -1221,7 +1223,7 @@ class MetaExample
1221
1223
 
1222
1224
  def run_example(example)
1223
1225
  Thread.new do
1224
- command = "ruby -r #{glimmer_dsl_libui_file} #{example} 2>&1"
1226
+ command = "#{RbConfig.ruby} -r #{glimmer_dsl_libui_file} #{example} 2>&1"
1225
1227
  result = ''
1226
1228
  IO.popen(command) do |f|
1227
1229
  sleep(0.0001) # yield to main thread
@@ -6765,6 +6767,125 @@ end
6765
6767
  TicTacToe.new.launch
6766
6768
  ```
6767
6769
 
6770
+ ### Snake
6771
+
6772
+ Snake provides an example of building a desktop application [test-first](/spec/examples/snake/model/game_spec.rb) following the MVP ([Model](/examples/snake/model/game.rb) / [View](/examples/snake.rb) / [Presenter](/examples/snake/presenter/grid.rb)) architectural pattern.
6773
+
6774
+ [examples/snake.rb](examples/snake.rb)
6775
+
6776
+ Run with this command from the root of the project if you cloned the project:
6777
+
6778
+ ```
6779
+ ruby -r './lib/glimmer-dsl-libui' examples/snake.rb
6780
+ ```
6781
+
6782
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
6783
+
6784
+ ```
6785
+ ruby -r glimmer-dsl-libui -e "require 'examples/snake'"
6786
+ ```
6787
+
6788
+ Mac
6789
+
6790
+ ![glimmer-dsl-libui-mac-snake.png](images/glimmer-dsl-libui-mac-snake.png)
6791
+
6792
+ ![glimmer-dsl-libui-mac-snake-game-over.png](images/glimmer-dsl-libui-mac-snake-game-over.png)
6793
+
6794
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
6795
+
6796
+ ```ruby
6797
+ require 'glimmer-dsl-libui'
6798
+ require 'glimmer/data_binding/observer'
6799
+
6800
+ require_relative 'snake/presenter/grid'
6801
+
6802
+ class Snake
6803
+ CELL_SIZE = 15
6804
+ SNAKE_MOVE_DELAY = 0.1
6805
+ include Glimmer
6806
+
6807
+ def initialize
6808
+ @game = Model::Game.new
6809
+ @grid = Presenter::Grid.new(@game)
6810
+ @game.start
6811
+ create_gui
6812
+ register_observers
6813
+ end
6814
+
6815
+ def launch
6816
+ @main_window.show
6817
+ end
6818
+
6819
+ def register_observers
6820
+ @game.height.times do |row|
6821
+ @game.width.times do |column|
6822
+ Glimmer::DataBinding::Observer.proc do |new_color|
6823
+ @cell_grid[row][column].fill = new_color
6824
+ end.observe(@grid.cells[row][column], :color)
6825
+ end
6826
+ end
6827
+
6828
+ Glimmer::DataBinding::Observer.proc do |game_over|
6829
+ Glimmer::LibUI.queue_main do
6830
+ if game_over
6831
+ msg_box('Game Over!', "Score: #{@game.score}")
6832
+ @game.start
6833
+ end
6834
+ end
6835
+ end.observe(@game, :over)
6836
+
6837
+ Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
6838
+ unless @game.over?
6839
+ @game.snake.move
6840
+ @main_window.title = "Glimmer Snake (Score: #{@game.score})"
6841
+ end
6842
+ end
6843
+ end
6844
+
6845
+ def create_gui
6846
+ @cell_grid = []
6847
+ @main_window = window('Glimmer Snake', @game.width * CELL_SIZE, @game.height * CELL_SIZE) {
6848
+ resizable false
6849
+
6850
+ vertical_box {
6851
+ padded false
6852
+
6853
+ @game.height.times do |row|
6854
+ @cell_grid << []
6855
+ horizontal_box {
6856
+ padded false
6857
+
6858
+ @game.width.times do |column|
6859
+ area {
6860
+ @cell_grid.last << path {
6861
+ square(0, 0, CELL_SIZE)
6862
+
6863
+ fill Presenter::Cell::COLOR_CLEAR
6864
+ }
6865
+
6866
+ on_key_up do |area_key_event|
6867
+ orientation_and_key = [@game.snake.head.orientation, area_key_event[:ext_key]]
6868
+ case orientation_and_key
6869
+ in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
6870
+ @game.snake.turn_right
6871
+ in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
6872
+ @game.snake.turn_left
6873
+ else
6874
+ # No Op
6875
+ end
6876
+ end
6877
+ }
6878
+ end
6879
+ }
6880
+ end
6881
+ }
6882
+ }
6883
+ end
6884
+ end
6885
+
6886
+ Snake.new.launch
6887
+ ```
6888
+
6768
6889
  ## Applications
6769
6890
 
6770
6891
  Here are some applications built with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.21
1
+ 0.2.22
@@ -43,7 +43,7 @@ class MetaExample
43
43
 
44
44
  def run_example(example)
45
45
  Thread.new do
46
- command = "ruby -r #{glimmer_dsl_libui_file} #{example} 2>&1"
46
+ command = "#{RbConfig.ruby} -r #{glimmer_dsl_libui_file} #{example} 2>&1"
47
47
  result = ''
48
48
  IO.popen(command) do |f|
49
49
  sleep(0.0001) # yield to main thread
@@ -0,0 +1,33 @@
1
+ class Snake
2
+ module Model
3
+ class Apple
4
+ attr_reader :game
5
+ attr_accessor :row, :column
6
+
7
+ def initialize(game)
8
+ @game = game
9
+ end
10
+
11
+ # generates a new location from scratch or via dependency injection of what cell is (for testing purposes)
12
+ def generate(initial_row: nil, initial_column: nil)
13
+ if initial_row && initial_column
14
+ self.row, self.column = initial_row, initial_column
15
+ else
16
+ self.row, self.column = @game.height.times.zip(@game.width.times).reject do |row, column|
17
+ @game.snake.vertebrae.map {|v| [v.row, v.column]}.include?([row, column])
18
+ end.sample
19
+ end
20
+ end
21
+
22
+ def remove
23
+ self.row = nil
24
+ self.column = nil
25
+ end
26
+
27
+ # inspect is overridden to prevent printing very long stack traces
28
+ def inspect
29
+ "#{super[0, 120]}... >"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ require 'fileutils'
2
+
3
+ require_relative 'snake'
4
+ require_relative 'apple'
5
+
6
+ class Snake
7
+ module Model
8
+ class Game
9
+ WIDTH_DEFAULT = 40
10
+ HEIGHT_DEFAULT = 40
11
+ FILE_HIGH_SCORE = File.expand_path(File.join(Dir.home, '.glimmer-snake'))
12
+
13
+ attr_reader :width, :height
14
+ attr_accessor :snake, :apple, :over, :score, :high_score
15
+ alias over? over
16
+ # TODO implement scoring on snake eating apples
17
+
18
+ def initialize(width = WIDTH_DEFAULT, height = HEIGHT_DEFAULT)
19
+ @width = width
20
+ @height = height
21
+ @snake = Snake.new(self)
22
+ @apple = Apple.new(self)
23
+ FileUtils.touch(FILE_HIGH_SCORE)
24
+ @high_score = File.read(FILE_HIGH_SCORE).to_i rescue 0
25
+ end
26
+
27
+ def score=(new_score)
28
+ @score = new_score
29
+ self.high_score = @score if @score > @high_score
30
+ end
31
+
32
+ def high_score=(new_high_score)
33
+ @high_score = new_high_score
34
+ File.write(FILE_HIGH_SCORE, @high_score.to_s)
35
+ rescue => e
36
+ puts e.full_message
37
+ end
38
+
39
+ def start
40
+ self.over = false
41
+ self.score = 0
42
+ self.snake.generate
43
+ self.apple.generate
44
+ end
45
+
46
+ # inspect is overridden to prevent printing very long stack traces
47
+ def inspect
48
+ "#{super[0, 75]}... >"
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,95 @@
1
+ require_relative 'vertebra'
2
+
3
+ class Snake
4
+ module Model
5
+ class Snake
6
+ SCORE_EAT_APPLE = 50
7
+ RIGHT_TURN_MAP = {
8
+ north: :east,
9
+ east: :south,
10
+ south: :west,
11
+ west: :north
12
+ }
13
+ LEFT_TURN_MAP = RIGHT_TURN_MAP.invert
14
+
15
+ attr_accessor :collided
16
+ alias collided? collided
17
+
18
+ attr_reader :game
19
+ # vertebrae and joins are ordered from tail to head
20
+ attr_accessor :vertebrae
21
+
22
+ def initialize(game)
23
+ @game = game
24
+ end
25
+
26
+ # generates a new snake location and orientation from scratch or via dependency injection of what head_cell and orientation are (for testing purposes)
27
+ def generate(initial_row: nil, initial_column: nil, initial_orientation: nil)
28
+ self.collided = false
29
+ initial_vertebra = Vertebra.new(snake: self, row: initial_row, column: initial_column, orientation: initial_orientation)
30
+ self.vertebrae = [initial_vertebra]
31
+ end
32
+
33
+ def length
34
+ @vertebrae.length
35
+ end
36
+
37
+ def head
38
+ @vertebrae.last
39
+ end
40
+
41
+ def tail
42
+ @vertebrae.first
43
+ end
44
+
45
+ def remove
46
+ self.vertebrae.clear
47
+ self.joins.clear
48
+ end
49
+
50
+ def move
51
+ @old_tail = tail.dup
52
+ @new_head = head.dup
53
+ case @new_head.orientation
54
+ when :east
55
+ @new_head.column = (@new_head.column + 1) % @game.width
56
+ when :west
57
+ @new_head.column = (@new_head.column - 1) % @game.width
58
+ when :south
59
+ @new_head.row = (@new_head.row + 1) % @game.height
60
+ when :north
61
+ @new_head.row = (@new_head.row - 1) % @game.height
62
+ end
63
+ if @vertebrae.map {|v| [v.row, v.column]}.include?([@new_head.row, @new_head.column])
64
+ self.collided = true
65
+ @game.over = true
66
+ else
67
+ @vertebrae.append(@new_head)
68
+ @vertebrae.delete(tail)
69
+ if head.row == @game.apple.row && head.column == @game.apple.column
70
+ grow
71
+ @game.apple.generate
72
+ end
73
+ end
74
+ end
75
+
76
+ def turn_right
77
+ head.orientation = RIGHT_TURN_MAP[head.orientation]
78
+ end
79
+
80
+ def turn_left
81
+ head.orientation = LEFT_TURN_MAP[head.orientation]
82
+ end
83
+
84
+ def grow
85
+ @game.score += SCORE_EAT_APPLE
86
+ @vertebrae.prepend(@old_tail)
87
+ end
88
+
89
+ # inspect is overridden to prevent printing very long stack traces
90
+ def inspect
91
+ "#{super[0, 150]}... >"
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,22 @@
1
+ class Snake
2
+ module Model
3
+ class Vertebra
4
+ ORIENTATIONS = %i[north east south west]
5
+ # orientation is needed for snake occuppied cells (but not apple cells)
6
+ attr_reader :snake
7
+ attr_accessor :row, :column, :orientation
8
+
9
+ def initialize(snake: , row: , column: , orientation: )
10
+ @row = row || rand(snake.game.height)
11
+ @column = column || rand(snake.game.width)
12
+ @orientation = orientation || ORIENTATIONS.sample
13
+ @snake = snake
14
+ end
15
+
16
+ # inspect is overridden to prevent printing very long stack traces
17
+ def inspect
18
+ "#{super[0, 150]}... >"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ class Snake
2
+ module Presenter
3
+ class Cell
4
+ COLOR_CLEAR = :white
5
+ COLOR_SNAKE = :green
6
+ COLOR_APPLE = :red
7
+
8
+ attr_reader :row, :column, :grid
9
+ attr_accessor :color
10
+
11
+ def initialize(grid: ,row: ,column: )
12
+ @row = row
13
+ @column = column
14
+ @grid = grid
15
+ end
16
+
17
+ def clear
18
+ self.color = COLOR_CLEAR unless color == COLOR_CLEAR
19
+ end
20
+
21
+ # inspect is overridden to prevent printing very long stack traces
22
+ def inspect
23
+ "#{super[0, 150]}... >"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ require 'glimmer/data_binding/observer'
2
+ require_relative '../model/game'
3
+ require_relative 'cell'
4
+
5
+ class Snake
6
+ module Presenter
7
+ class Grid
8
+ attr_reader :game, :cells
9
+
10
+ def initialize(game = Model::Game.new)
11
+ @game = game
12
+ @cells = @game.height.times.map do |row|
13
+ @game.width.times.map do |column|
14
+ Cell.new(grid: self, row: row, column: column)
15
+ end
16
+ end
17
+ Glimmer::DataBinding::Observer.proc do |new_vertebrae|
18
+ occupied_snake_positions = @game.snake.vertebrae.map {|v| [v.row, v.column]}
19
+ @cells.each_with_index do |row_cells, row|
20
+ row_cells.each_with_index do |cell, column|
21
+ if [@game.apple.row, @game.apple.column] == [row, column]
22
+ cell.color = Cell::COLOR_APPLE
23
+ elsif occupied_snake_positions.include?([row, column])
24
+ cell.color = Cell::COLOR_SNAKE
25
+ else
26
+ cell.clear
27
+ end
28
+ end
29
+ end
30
+ end.observe(@game.snake, :vertebrae)
31
+ end
32
+
33
+ def clear
34
+ @cells.each do |row_cells|
35
+ row_cells.each do |cell|
36
+ cell.clear
37
+ end
38
+ end
39
+ end
40
+
41
+ # inspect is overridden to prevent printing very long stack traces
42
+ def inspect
43
+ "#{super[0, 75]}... >"
44
+ end
45
+ end
46
+ end
47
+ end
data/examples/snake.rb ADDED
@@ -0,0 +1,90 @@
1
+ require 'glimmer-dsl-libui'
2
+ require 'glimmer/data_binding/observer'
3
+
4
+ require_relative 'snake/presenter/grid'
5
+
6
+ class Snake
7
+ CELL_SIZE = 15
8
+ SNAKE_MOVE_DELAY = 0.1
9
+ include Glimmer
10
+
11
+ def initialize
12
+ @game = Model::Game.new
13
+ @grid = Presenter::Grid.new(@game)
14
+ @game.start
15
+ create_gui
16
+ register_observers
17
+ end
18
+
19
+ def launch
20
+ @main_window.show
21
+ end
22
+
23
+ def register_observers
24
+ @game.height.times do |row|
25
+ @game.width.times do |column|
26
+ Glimmer::DataBinding::Observer.proc do |new_color|
27
+ @cell_grid[row][column].fill = new_color
28
+ end.observe(@grid.cells[row][column], :color)
29
+ end
30
+ end
31
+
32
+ Glimmer::DataBinding::Observer.proc do |game_over|
33
+ Glimmer::LibUI.queue_main do
34
+ if game_over
35
+ msg_box('Game Over!', "Score: #{@game.score} | High Score: #{@game.high_score}")
36
+ @game.start
37
+ end
38
+ end
39
+ end.observe(@game, :over)
40
+
41
+ Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
42
+ unless @game.over?
43
+ @game.snake.move
44
+ @main_window.title = "Glimmer Snake (Score: #{@game.score} | High Score: #{@game.high_score})"
45
+ end
46
+ end
47
+ end
48
+
49
+ def create_gui
50
+ @cell_grid = []
51
+ @main_window = window('Glimmer Snake', @game.width * CELL_SIZE, @game.height * CELL_SIZE) {
52
+ resizable false
53
+
54
+ vertical_box {
55
+ padded false
56
+
57
+ @game.height.times do |row|
58
+ @cell_grid << []
59
+ horizontal_box {
60
+ padded false
61
+
62
+ @game.width.times do |column|
63
+ area {
64
+ @cell_grid.last << path {
65
+ square(0, 0, CELL_SIZE)
66
+
67
+ fill Presenter::Cell::COLOR_CLEAR
68
+ }
69
+
70
+ on_key_up do |area_key_event|
71
+ orientation_and_key = [@game.snake.head.orientation, area_key_event[:ext_key]]
72
+ case orientation_and_key
73
+ in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
74
+ @game.snake.turn_right
75
+ in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
76
+ @game.snake.turn_left
77
+ else
78
+ # No Op
79
+ end
80
+ end
81
+ }
82
+ end
83
+ }
84
+ end
85
+ }
86
+ }
87
+ end
88
+ end
89
+
90
+ Snake.new.launch
@@ -113,7 +113,7 @@ class Tetris
113
113
  end
114
114
 
115
115
  def tetris_dir
116
- @tetris_dir ||= File.join(File.expand_path('~'), '.glimmer-tetris')
116
+ @tetris_dir ||= File.join(Dir.home, '.glimmer-tetris')
117
117
  end
118
118
 
119
119
  def tetris_high_score_file
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-libui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.21
4
+ version: 0.2.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-05 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -252,6 +252,13 @@ files:
252
252
  - examples/method_based_custom_keyword.rb
253
253
  - examples/midi_player.rb
254
254
  - examples/simple_notepad.rb
255
+ - examples/snake.rb
256
+ - examples/snake/model/apple.rb
257
+ - examples/snake/model/game.rb
258
+ - examples/snake/model/snake.rb
259
+ - examples/snake/model/vertebra.rb
260
+ - examples/snake/presenter/cell.rb
261
+ - examples/snake/presenter/grid.rb
255
262
  - examples/tetris.rb
256
263
  - examples/tetris/model/block.rb
257
264
  - examples/tetris/model/game.rb