glimmer-dsl-swt 4.22.2.1 → 4.22.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 38c5a6fcb0bc02d02b4b2b4566e86bcdcfc037730b344bc0868afca2bbaf045d
4
- data.tar.gz: b0c616c16900822130ee36452d88e36070bf293668f54ded34b9a1798842cb97
3
+ metadata.gz: 3de6dce288c5d0febfd7cdaa37195daf13284c7ff6f175442a4642f71b499fe7
4
+ data.tar.gz: 33e0fc58526098b0fa74c4bbc6779845b34b5052c3ddcb33d40e6f9d6548f2aa
5
5
  SHA512:
6
- metadata.gz: dc5a5d28f744a77d10e29e96fe28e641a02463c610431ae2fbdfe0c662a9399cd08ac942669d6c85e55069e67a6c45d98fc94c84d9a7e7b58bf4ab107d14d82b
7
- data.tar.gz: 2b91cdab4cd1ee9919ad1b635314a625e9335153a34e7d792a645e91df2fe66e1348ed7d39659ebf5c02859621a768fd31cce1674ae24a2911c60c47c6fc9dab
6
+ metadata.gz: 65b37079de93d70fcdde14ea4fada7cd2feeb1aa1fb22ee7dd0dedf08d873966183de876d510492a07707812b2414193c1003a83804636aeb021cd7b229195d0
7
+ data.tar.gz: b7c347ae41ee4b0fc170fc910e20bcbf4e58aed1e9d8a31416a66f1253e3a7d40b3d3fe79354549b301023401bf952af15873caf89525c29103da3b447010902
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 4.22.2.2
4
+
5
+ - Snake elaborate sample
6
+ - Fixed `timer_exec(time_in_millis) {}` expresion
7
+
3
8
  ## 4.22.2.1
4
9
 
5
10
  - Upgrade to glimmer 2.6.0
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 SWT 4.22.2.1
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 SWT 4.22.2.2
2
2
  ## JRuby Desktop Development GUI Framework
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
4
4
  [![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
@@ -17,17 +17,20 @@ Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) an
17
17
 
18
18
  ![Eclipse SWT RCP NASA Mars Rover](/images/glimmer-eclipse-swt-rcp-nasa-mars-rover.png)
19
19
 
20
- [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.22.2.1 includes [SWT 4.22](https://download.eclipse.org/eclipse/downloads/drops4/R-4.22-202111241800/), which was released on November 24, 2021. Gem version numbers are in sync with the SWT library versions. The first two digits represent the SWT version number. The last two digits represent the minor and patch versions of Glimmer DSL for SWT.
20
+ [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.22.2.2 includes [SWT 4.22](https://download.eclipse.org/eclipse/downloads/drops4/R-4.22-202111241800/), which was released on November 24, 2021. Gem version numbers are in sync with the SWT library versions. The first two digits represent the SWT version number. The last two digits represent the minor and patch versions of Glimmer DSL for SWT.
21
21
 
22
22
  **Starting in version 4.20.0.0, [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) comes with the new [***Shine***](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#shine) syntax** for highly intuitive and visually expressive View/Model Attribute Mapping, relying on `<=>` for bidirectional (two-way) data-binding and `<=` for unidirectional (one-way) data-binding, providing an alternative to the `bind` keyword.
23
23
 
24
24
  Please help make [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) better by providing feedback and [contributing](#contributing) whenever possible. Any feature suggestions that are accepted could be implemented within weeks if not days.
25
25
 
26
- Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interested in:
26
+ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems you might be interested in:
27
27
  - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
28
28
  - [glimmer-dsl-libui](https://github.com/AndyObtiva/glimmer-dsl-libui): Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)
29
29
  - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
30
30
  - [glimmer-dsl-gtk](https://github.com/AndyObtiva/glimmer-dsl-gtk): Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library)
31
+ - [glimmer-dsl-fx](https://github.com/AndyObtiva/glimmer-dsl-fx): Glimmer DSL for FX (FOX Toolkit Ruby Desktop Development GUI Library)
32
+ - [glimmer-dsl-jfx](https://github.com/AndyObtiva/glimmer-dsl-jfx): Glimmer DSL for JFX (JRuby JavaFX Desktop Development GUI Library)
33
+ - [glimmer-dsl-swing](https://github.com/AndyObtiva/glimmer-dsl-swing): Glimmer DSL for Swing (JRuby Swing Desktop Development GUI Library)
31
34
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
32
35
  - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
33
36
 
@@ -325,7 +328,7 @@ jgem install glimmer-dsl-swt
325
328
 
326
329
  Or this command if you want a specific version:
327
330
  ```
328
- jgem install glimmer-dsl-swt -v 4.22.2.1
331
+ jgem install glimmer-dsl-swt -v 4.22.2.2
329
332
  ```
330
333
 
331
334
  `jgem` is JRuby's version of `gem` command.
@@ -353,7 +356,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
353
356
 
354
357
  Add the following to `Gemfile`:
355
358
  ```
356
- gem 'glimmer-dsl-swt', '~> 4.22.2.1'
359
+ gem 'glimmer-dsl-swt', '~> 4.22.2.2'
357
360
  ```
358
361
 
359
362
  And, then run:
@@ -376,7 +379,7 @@ glimmer
376
379
  ```
377
380
 
378
381
  ```
379
- Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.22.2.1
382
+ Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.22.2.2
380
383
 
381
384
  Usage: glimmer [--bundler] [--pd] [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args]) [[application2.rb]...]
382
385
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.22.2.1
1
+ 4.22.2.2
@@ -79,6 +79,7 @@
79
79
  - [Metronome](#metronome)
80
80
  - [Weather](#weather)
81
81
  - [Quarto](#quarto)
82
+ - [Snake](#snake)
82
83
  - [External Samples](#external-samples)
83
84
  - [Glimmer Calculator](#glimmer-calculator)
84
85
  - [Gladiator](#gladiator)
@@ -1375,6 +1376,20 @@ Quarto
1375
1376
 
1376
1377
  ![Quarto](/images/glimmer-quarto.png)
1377
1378
 
1379
+ #### Snake
1380
+
1381
+ This is the classic Snake game, which demonstrates MVP (Model-View-Presenter) and data-binding written [test-first](/spec/samples/elaborate/snake/model/game_spec.rb).
1382
+
1383
+ Code:
1384
+
1385
+ [samples/elaborate/snake.rb](/samples/elaborate/snake.rb)
1386
+
1387
+ Snake
1388
+
1389
+ ![Snake](/images/glimmer-snake.png)
1390
+
1391
+ ![Snake Video](/images/glimmer-snake.gif)
1392
+
1378
1393
  ### External Samples
1379
1394
 
1380
1395
  #### Glimmer Calculator
Binary file
@@ -36,8 +36,7 @@ module Glimmer
36
36
 
37
37
  def can_interpret?(parent, keyword, *args, &block)
38
38
  keyword == exec_operation and
39
- block_given? and
40
- args.empty?
39
+ block_given?
41
40
  end
42
41
 
43
42
  def interpret(parent, keyword, *args, &block)
@@ -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,68 @@
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 = 20
10
+ HEIGHT_DEFAULT = 20
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, :paused
15
+ alias over? over
16
+ alias paused? paused
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
+ def pause
47
+ self.paused = true
48
+ end
49
+
50
+ def resume
51
+ self.paused = false
52
+ end
53
+
54
+ def toggle_pause
55
+ unless paused?
56
+ pause
57
+ else
58
+ resume
59
+ end
60
+ end
61
+
62
+ # inspect is overridden to prevent printing very long stack traces
63
+ def inspect
64
+ "#{super[0, 75]}... >"
65
+ end
66
+ end
67
+ end
68
+ 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,49 @@
1
+ require 'glimmer'
2
+ require_relative '../model/game'
3
+ require_relative 'cell'
4
+
5
+ class Snake
6
+ module Presenter
7
+ class Grid
8
+ include Glimmer
9
+
10
+ attr_reader :game, :cells
11
+
12
+ def initialize(game = Model::Game.new)
13
+ @game = game
14
+ @cells = @game.height.times.map do |row|
15
+ @game.width.times.map do |column|
16
+ Cell.new(grid: self, row: row, column: column)
17
+ end
18
+ end
19
+ observe(@game.snake, :vertebrae) do |new_vertebrae|
20
+ occupied_snake_positions = @game.snake.vertebrae.map {|v| [v.row, v.column]}
21
+ @cells.each_with_index do |row_cells, row|
22
+ row_cells.each_with_index do |cell, column|
23
+ if [@game.apple.row, @game.apple.column] == [row, column]
24
+ cell.color = Cell::COLOR_APPLE
25
+ elsif occupied_snake_positions.include?([row, column])
26
+ cell.color = Cell::COLOR_SNAKE
27
+ else
28
+ cell.clear
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def clear
36
+ @cells.each do |row_cells|
37
+ row_cells.each do |cell|
38
+ cell.clear
39
+ end
40
+ end
41
+ end
42
+
43
+ # inspect is overridden to prevent printing very long stack traces
44
+ def inspect
45
+ "#{super[0, 75]}... >"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,103 @@
1
+ require 'glimmer-dsl-swt'
2
+
3
+ require_relative 'snake/presenter/grid'
4
+
5
+ class Snake
6
+ include Glimmer::UI::CustomShell
7
+
8
+ CELL_SIZE = 15
9
+ SNAKE_MOVE_DELAY = 100 # millis
10
+
11
+ before_body do
12
+ @game = Model::Game.new
13
+ @grid = Presenter::Grid.new(@game)
14
+ @game.start
15
+ @keypress_queue = []
16
+
17
+ display {
18
+ on_swt_keydown do |key_event|
19
+ if key_event.keyCode == 32
20
+ @game.toggle_pause
21
+ else
22
+ @keypress_queue << key_event.keyCode
23
+ end
24
+ end
25
+ }
26
+ end
27
+
28
+ after_body do
29
+ register_observers
30
+ end
31
+
32
+ body {
33
+ shell(:no_resize) {
34
+ grid_layout(@game.width, true) {
35
+ margin_width 0
36
+ margin_height 0
37
+ horizontal_spacing 0
38
+ vertical_spacing 0
39
+ }
40
+
41
+ # data-bind window title to game score, converting it to a title string on read from the model
42
+ text <= [@game, :score, on_read: -> (score) {"Snake (Score: #{@game.score})"}]
43
+ minimum_size @game.width * CELL_SIZE, @game.height * CELL_SIZE
44
+
45
+ @game.height.times do |row|
46
+ @game.width.times do |column|
47
+ canvas {
48
+ layout_data {
49
+ width_hint CELL_SIZE
50
+ height_hint CELL_SIZE
51
+ }
52
+
53
+ rectangle(0, 0, CELL_SIZE, CELL_SIZE) {
54
+ background <= [@grid.cells[row][column], :color] # data-bind square fill to grid cell color
55
+ }
56
+ }
57
+ end
58
+ end
59
+ }
60
+ }
61
+
62
+ def register_observers
63
+ observe(@game, :over) do |game_over|
64
+ async_exec do
65
+ if game_over
66
+ message_box {
67
+ text 'Game Over!'
68
+ message "Score: #{@game.score} | High Score: #{@game.high_score}"
69
+ }.open
70
+ @game.start
71
+ end
72
+ end
73
+ end
74
+
75
+ timer_exec(SNAKE_MOVE_DELAY, &method(:move_snake))
76
+ end
77
+
78
+ def move_snake
79
+ unless @game.paused? || @game.over?
80
+ process_queued_keypress
81
+ @game.snake.move
82
+ end
83
+ timer_exec(SNAKE_MOVE_DELAY, &method(:move_snake))
84
+ end
85
+
86
+ def process_queued_keypress
87
+ # key press queue ensures one turn per snake move to avoid a double-turn resulting in instant death (due to snake illogically going back against itself)
88
+ key = @keypress_queue.shift
89
+ if [@game.snake.head.orientation, key] == [:north, swt(:arrow_right)] ||
90
+ [@game.snake.head.orientation, key] == [:east, swt(:arrow_down)] ||
91
+ [@game.snake.head.orientation, key] == [:south, swt(:arrow_left)] ||
92
+ [@game.snake.head.orientation, key] == [:west, swt(:arrow_up)]
93
+ @game.snake.turn_right
94
+ elsif [@game.snake.head.orientation, key] == [:north, swt(:arrow_left)] ||
95
+ [@game.snake.head.orientation, key] == [:west, swt(:arrow_down)] ||
96
+ [@game.snake.head.orientation, key] == [:south, swt(:arrow_right)] ||
97
+ [@game.snake.head.orientation, key] == [:east, swt(:arrow_up)]
98
+ @game.snake.turn_left
99
+ end
100
+ end
101
+ end
102
+
103
+ Snake.launch
@@ -54,7 +54,7 @@ class Tetris
54
54
  Display.app_name = 'Glimmer Tetris'
55
55
 
56
56
  display {
57
- on_swt_keydown { |key_event|
57
+ on_swt_keydown do |key_event|
58
58
  case key_event.keyCode
59
59
  when swt(:arrow_down), 's'.bytes.first
60
60
  if OS.mac?
@@ -88,16 +88,16 @@ class Tetris
88
88
  game.rotate!(:left)
89
89
  end
90
90
  end
91
- }
91
+ end
92
92
 
93
93
  # if running in app mode, set the Mac app about dialog (ignored in platforms)
94
- on_about {
94
+ on_about do
95
95
  show_about_dialog
96
- }
96
+ end
97
97
 
98
- on_quit {
98
+ on_quit do
99
99
  exit(0)
100
- }
100
+ end
101
101
  }
102
102
  end
103
103
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-swt
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.22.2.1
4
+ version: 4.22.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-25 00:00:00.000000000 Z
11
+ date: 2022-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -582,6 +582,13 @@ files:
582
582
  - samples/elaborate/quarto/view/message_box_panel.rb
583
583
  - samples/elaborate/quarto/view/piece.rb
584
584
  - samples/elaborate/quarto/view/selected_piece_area.rb
585
+ - samples/elaborate/snake.rb
586
+ - samples/elaborate/snake/model/apple.rb
587
+ - samples/elaborate/snake/model/game.rb
588
+ - samples/elaborate/snake/model/snake.rb
589
+ - samples/elaborate/snake/model/vertebra.rb
590
+ - samples/elaborate/snake/presenter/cell.rb
591
+ - samples/elaborate/snake/presenter/grid.rb
585
592
  - samples/elaborate/stock_ticker.rb
586
593
  - samples/elaborate/tetris.rb
587
594
  - samples/elaborate/tetris/model/block.rb