rb-snake 0.0.1 → 1.0.1

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: d226ce857ed8de1e615d68cbc27d4e4ef6cd136ff154d6a44917dfb4ffd7735f
4
- data.tar.gz: 23d3352ff62318377681d43caee10a018fb77ccefcabdac03c416986a5a76041
3
+ metadata.gz: 529079a6646e1e0bfc700fa65d4a8fe80d01f85c5e3871790797fe628d5b5a07
4
+ data.tar.gz: 5eb2921b933580848c2c5a7d7a51127ea1b02d64e36b998704477975978261ff
5
5
  SHA512:
6
- metadata.gz: a32fc0bdf90147f87ca693194ab85537be1b2ded3988ae86cdf609a0ed93211718a2b68cecd2618e85e25928af606f1dcf919e59f4d753204c4c04460f972256
7
- data.tar.gz: 601e241bcc4e4bfc51aa8db50b5360047dc50a5969a47b92352e95fc48c1c8dcbeb010b2d54f87da00d4b92f2deced545e1908b9f679b3ea2dd51f6ca0bb23b9
6
+ metadata.gz: 57b85516859d4bf5ba21ad80ced31eb8d7acaef84fb09b3e15a15629b1e7f4dfc155c6c783462608e5cdf8eb2cba944da9d75c4aab35c7242c80e132e5c78f88
7
+ data.tar.gz: 4a1262d36a8146d3fdf3937ffd0ae8bca0356eefe2e59bbd98d11ba8f5ba251d5e1774a80f2965c3e5ccee0a997514cfd6f534aa33c59fde8035c7d714bbbf75
data/.rubocop.yml CHANGED
@@ -2,7 +2,7 @@ require:
2
2
  - rubocop-rspec
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 3.1.2
5
+ TargetRubyVersion: 2.6.0
6
6
 
7
7
  Style/StringLiterals:
8
8
  Enabled: true
@@ -14,3 +14,15 @@ Style/StringLiteralsInInterpolation:
14
14
 
15
15
  Layout/LineLength:
16
16
  Max: 120
17
+
18
+ Style/Documentation:
19
+ Enabled: false
20
+
21
+ Metrics/MethodLength:
22
+ Max: 17
23
+
24
+ Metrics/ParameterLists:
25
+ Enabled: false
26
+
27
+ RSpec/MultipleMemoizedHelpers:
28
+ Enabled: false
data/README.md CHANGED
@@ -1,22 +1,18 @@
1
- # Rb::Snake
1
+ # rb-snake
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rb/snake`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ This is a Ruby adapted version of the Snake classic game, using [Ruby2d](https://www.ruby2d.com) gem
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ![](https://i.imgur.com/wC6W4VH.png)
6
6
 
7
7
  ## Installation
8
8
 
9
- Install the gem and add to the application's Gemfile by executing:
10
-
11
- $ bundle add rb-snake
12
-
13
- If bundler is not being used to manage dependencies, install the gem by executing:
9
+ Install the gem
14
10
 
15
11
  $ gem install rb-snake
16
12
 
17
13
  ## Usage
18
14
 
19
- TODO: Write usage instructions here
15
+ Run `rb-snake` on your terminal to start the game. Use the arrow keys on the keyboard to move the snake. Try to feed your snake as much as possible without hitting your own body!
20
16
 
21
17
  ## Development
22
18
 
data/bin/rb-snake ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "rb_snake/app"
6
+
7
+ app = RbSnake::App.new
8
+ app.start
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rb_snake/models/direction"
4
+
5
+ module RbSnake
6
+ module Actions
7
+ class ChangeDirection
8
+ class << self
9
+ def call(state, new_direction:)
10
+ return unless valid_direction?(state.current_direction, new_direction)
11
+
12
+ state.update_direction(new_direction)
13
+ end
14
+
15
+ private
16
+
17
+ def valid_direction?(current_direction, new_direction)
18
+ case current_direction
19
+ when RbSnake::Models::Direction::UP
20
+ !new_direction.eql?(RbSnake::Models::Direction::DOWN)
21
+ when RbSnake::Models::Direction::DOWN
22
+ !new_direction.eql?(RbSnake::Models::Direction::UP)
23
+ when RbSnake::Models::Direction::LEFT
24
+ !new_direction.eql?(RbSnake::Models::Direction::RIGHT)
25
+ when RbSnake::Models::Direction::RIGHT
26
+ !new_direction.eql?(RbSnake::Models::Direction::LEFT)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RbSnake
4
+ module Actions
5
+ class MoveSnake
6
+ class << self
7
+ def call(state, window)
8
+ snake = state.snake
9
+ current_direction = state.current_direction
10
+ food = state.food
11
+ grid = state.grid
12
+
13
+ make_next_move(snake, current_direction, food, grid, state)
14
+
15
+ window.render(state)
16
+ end
17
+
18
+ private
19
+
20
+ def make_next_move(snake, current_direction, food, grid, state)
21
+ next_position = snake.next_position(current_direction, grid)
22
+ if next_position.eql?(food.location)
23
+ snake.eat(food)
24
+ food.regenerate(snake, grid)
25
+ state.increase_speed if (snake.body.length % 10).zero?
26
+ elsif snake.body.any? { |body_pos| body_pos.eql?(next_position) }
27
+ state.finish_game!
28
+ else
29
+ snake.move_to(next_position)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/rb_snake/app.rb CHANGED
@@ -1,42 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'view/ruby2d'
4
- require_relative 'model/state'
5
- require_relative 'actions/actions'
3
+ require "rb_snake/models/state"
4
+ require "rb_snake/views/window"
6
5
 
7
- class App
8
- def initialize
9
- @state = Model.initial_state
10
- end
11
-
12
- def start
13
- @view = View::Ruby2dView.new(self)
14
- timer_thread = Thread.new { init_timer(@view) }
15
- @view.start(@state)
16
- timer_thread.join
17
- end
6
+ module RbSnake
7
+ class App
8
+ attr_reader :state, :window
18
9
 
19
- def init_timer(view)
20
- loop do
21
- if @state.game_finished
22
- puts 'Juego Finalizado'
23
- puts "Puntaje: #{@state.snake.positions.length}"
24
- break
25
- end
26
- @state = Actions::move_snake(@state)
27
- view.render(@state)
28
- sleep 0.1
10
+ def initialize
11
+ @state = Models::State.initial_state
29
12
  end
30
- end
31
13
 
32
- def send_action(action, params)
33
- new_state = Actions.send(action, @state, params)
34
- if new_state.hash != @state
35
- @state = new_state
36
- @view.render(@state)
14
+ def start
15
+ @window = Views::Window.new
16
+ window.start(state)
37
17
  end
38
18
  end
39
19
  end
40
-
41
- app = App.new
42
- app.start
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RbSnake
4
+ module Models
5
+ class Coordinate
6
+ attr_accessor :row, :col
7
+
8
+ def initialize(row:, col:)
9
+ @row = row
10
+ @col = col
11
+ end
12
+
13
+ def eql?(other)
14
+ row == other.row && col == other.col
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RbSnake
4
+ module Models
5
+ module Direction
6
+ UP = :up
7
+ RIGHT = :right
8
+ DOWN = :down
9
+ LEFT = :left
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rb_snake/models/coordinate"
4
+
5
+ module RbSnake
6
+ module Models
7
+ class Food
8
+ attr_reader :location
9
+
10
+ RenderedElement = Struct.new(:elem, :location)
11
+
12
+ def initialize(row:, col:)
13
+ @location = Coordinate.new(row: row, col: col)
14
+ end
15
+
16
+ def render(window)
17
+ return if rendered_element&.location == location
18
+
19
+ window.remove(rendered_element.elem) if rendered_element
20
+
21
+ elem = yield(location.row, location.col)
22
+ @rendered_element = RenderedElement.new(elem, location)
23
+ end
24
+
25
+ def regenerate(snake, grid)
26
+ loop do
27
+ new_row = rand(0...grid.rows)
28
+ new_col = rand(0...grid.cols)
29
+
30
+ if snake.body.none? { |position| position.row == new_row && position.col == new_col }
31
+ @location = Coordinate.new(row: new_row, col: new_col)
32
+ break
33
+ end
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :rendered_element
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RbSnake
4
+ module Models
5
+ class Grid
6
+ attr_reader :rows, :cols
7
+
8
+ def initialize(rows:, cols:)
9
+ @rows = rows
10
+ @cols = cols
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rb_snake/models/direction"
4
+ require "rb_snake/models/coordinate"
5
+
6
+ module RbSnake
7
+ module Models
8
+ class Snake
9
+ RenderedBodyElem = Struct.new(:elem, :position)
10
+
11
+ attr_reader :body
12
+
13
+ def initialize(body:)
14
+ @body = body
15
+ end
16
+
17
+ def render(window, &block)
18
+ return build_rendered_body(&block) if rendered_body.nil?
19
+
20
+ update_last_rendered_position(window)
21
+ update_first_rendered_position(&block)
22
+ end
23
+
24
+ def next_position(direction, grid)
25
+ new_row = head.row
26
+ new_col = head.col
27
+
28
+ case direction
29
+ when Direction::UP
30
+ new_row -= 1
31
+ when Direction::RIGHT
32
+ new_col += 1
33
+ when Direction::DOWN
34
+ new_row += 1
35
+ when Direction::LEFT
36
+ new_col -= 1
37
+ else
38
+ raise StandardError, "direction #{direction} not recognized"
39
+ end
40
+
41
+ new_row = truncate_row(new_row, grid)
42
+ new_col = truncate_col(new_col, grid)
43
+
44
+ Coordinate.new(row: new_row, col: new_col)
45
+ end
46
+
47
+ def eat(food)
48
+ body.unshift(food.location)
49
+ end
50
+
51
+ def move_to(position)
52
+ body.unshift(position)
53
+ body.pop
54
+ end
55
+
56
+ private
57
+
58
+ def head
59
+ body.first
60
+ end
61
+
62
+ def build_rendered_body(&block)
63
+ @rendered_body = body.map do |position|
64
+ elem = block.call(position.row, position.col)
65
+ RenderedBodyElem.new(elem, position)
66
+ end
67
+ end
68
+
69
+ def update_last_rendered_position(window)
70
+ return if rendered_body.last.position == body.last
71
+
72
+ window.remove(rendered_body.last.elem)
73
+ rendered_body.pop
74
+ end
75
+
76
+ def update_first_rendered_position(&block)
77
+ return if rendered_body.first.position == body.first
78
+
79
+ new_position = body.first
80
+ elem = block.call(new_position.row, new_position.col)
81
+ rendered_body.unshift(RenderedBodyElem.new(elem, new_position))
82
+ end
83
+
84
+ def truncate_row(new_row, grid)
85
+ return 0 if new_row >= grid.rows
86
+ return grid.rows - 1 if new_row.negative?
87
+
88
+ new_row
89
+ end
90
+
91
+ def truncate_col(new_col, grid)
92
+ return 0 if new_col >= grid.cols
93
+ return grid.cols - 1 if new_col.negative?
94
+
95
+ new_col
96
+ end
97
+
98
+ attr_reader :rendered_body
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rb_snake/models/coordinate"
4
+ require "rb_snake/models/snake"
5
+ require "rb_snake/models/food"
6
+ require "rb_snake/models/grid"
7
+ require "rb_snake/models/direction"
8
+
9
+ module RbSnake
10
+ module Models
11
+ class State
12
+ attr_reader :snake, :food, :grid, :current_direction, :game_finished, :speed_factor
13
+
14
+ def initialize(snake:, food:, grid:, current_direction:, game_finished:, speed_factor:)
15
+ @snake = snake
16
+ @food = food
17
+ @grid = grid
18
+ @current_direction = current_direction
19
+ @game_finished = game_finished
20
+ @speed_factor = speed_factor
21
+ end
22
+
23
+ def self.initial_state
24
+ new(
25
+ snake: Snake.new(
26
+ body: [Coordinate.new(row: 1, col: 1), Coordinate.new(row: 0, col: 1)]
27
+ ),
28
+ food: Food.new(row: 10, col: 1),
29
+ grid: Grid.new(rows: 12, cols: 24),
30
+ current_direction: Direction::DOWN,
31
+ game_finished: false,
32
+ speed_factor: 6
33
+ )
34
+ end
35
+
36
+ def finish_game!
37
+ @game_finished = true
38
+ end
39
+
40
+ def game_score
41
+ snake.body.length
42
+ end
43
+
44
+ def update_direction(new_direction)
45
+ @current_direction = new_direction
46
+ end
47
+
48
+ def increase_speed
49
+ @speed_factor = [speed_factor - 1, 1].max # the lower, the faster
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RbSnake
4
- VERSION = "0.0.1"
4
+ VERSION = '1.0.1'
5
5
  end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby2d"
4
+ require "rb_snake/models/direction"
5
+ require "rb_snake/actions/move_snake"
6
+ require "rb_snake/actions/change_direction"
7
+
8
+ module RbSnake
9
+ module Views
10
+ class Window
11
+ PIXEL_SIZE = 50
12
+
13
+ def initialize
14
+ @ruby2d_window = Ruby2D::Window.new
15
+ end
16
+
17
+ def start(state)
18
+ setup_window(state.grid)
19
+ add_key_listener(state)
20
+ render_on_each_frame(state)
21
+
22
+ ruby2d_window.show
23
+ end
24
+
25
+ def render(state)
26
+ state.food.render(ruby2d_window) do |row, col|
27
+ render_square(row: row, col: col, color: "yellow")
28
+ end
29
+
30
+ state.snake.render(ruby2d_window) do |row, col|
31
+ render_square(row: row, col: col, color: "green")
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :ruby2d_window
38
+
39
+ def setup_window(grid)
40
+ ruby2d_window.set(
41
+ title: "Snake",
42
+ width: PIXEL_SIZE * grid.cols,
43
+ height: PIXEL_SIZE * grid.rows
44
+ )
45
+ end
46
+
47
+ def add_key_listener(state)
48
+ ruby2d_window.on :key_down do |event|
49
+ handle_key_event(event, state)
50
+ end
51
+ end
52
+
53
+ def render_on_each_frame(state)
54
+ tick = 0
55
+
56
+ ruby2d_window.update do
57
+ Actions::MoveSnake.call(state, self) if (tick % state.speed_factor).zero?
58
+
59
+ if state.game_finished
60
+ ruby2d_window.close
61
+
62
+ puts "Game Over"
63
+ puts "Score: #{state.game_score}"
64
+ end
65
+
66
+ tick += 1
67
+ end
68
+ end
69
+
70
+ def render_square(row:, col:, color:)
71
+ square = Ruby2D::Square.new(
72
+ x: col * PIXEL_SIZE,
73
+ y: row * PIXEL_SIZE,
74
+ size: PIXEL_SIZE,
75
+ color: color
76
+ )
77
+
78
+ ruby2d_window.add(square)
79
+ square
80
+ end
81
+
82
+ def handle_key_event(event, state)
83
+ case event.key
84
+ when "up"
85
+ Actions::ChangeDirection.call(state, new_direction: Models::Direction::UP)
86
+ when "down"
87
+ Actions::ChangeDirection.call(state, new_direction: Models::Direction::DOWN)
88
+ when "left"
89
+ Actions::ChangeDirection.call(state, new_direction: Models::Direction::LEFT)
90
+ when "right"
91
+ Actions::ChangeDirection.call(state, new_direction: Models::Direction::RIGHT)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
data/lib/rb_snake.rb CHANGED
@@ -4,5 +4,4 @@ require_relative "rb_snake/version"
4
4
 
5
5
  module RbSnake
6
6
  class Error < StandardError; end
7
- # Your code goes here...
8
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rb-snake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Prada
8
- autorequire:
9
- bindir: exe
8
+ autorequire:
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-17 00:00:00.000000000 Z
11
+ date: 2023-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby2d
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.12.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -83,11 +97,11 @@ dependencies:
83
97
  description: The classic snake game recreated using ruby
84
98
  email:
85
99
  - mapra99@gmail.com
86
- executables: []
100
+ executables:
101
+ - rb-snake
87
102
  extensions: []
88
103
  extra_rdoc_files: []
89
104
  files:
90
- - ".byebug_history"
91
105
  - ".rspec"
92
106
  - ".rubocop.yml"
93
107
  - ".stickler.yml"
@@ -97,13 +111,19 @@ files:
97
111
  - LICENSE.txt
98
112
  - README.md
99
113
  - Rakefile
114
+ - bin/rb-snake
100
115
  - lib/rb_snake.rb
101
- - lib/rb_snake/actions/actions.rb
116
+ - lib/rb_snake/actions/change_direction.rb
117
+ - lib/rb_snake/actions/move_snake.rb
102
118
  - lib/rb_snake/app.rb
103
- - lib/rb_snake/model/state.rb
119
+ - lib/rb_snake/models/coordinate.rb
120
+ - lib/rb_snake/models/direction.rb
121
+ - lib/rb_snake/models/food.rb
122
+ - lib/rb_snake/models/grid.rb
123
+ - lib/rb_snake/models/snake.rb
124
+ - lib/rb_snake/models/state.rb
104
125
  - lib/rb_snake/version.rb
105
- - lib/rb_snake/view/ruby2d.rb
106
- - rb-snake.gemspec
126
+ - lib/rb_snake/views/window.rb
107
127
  - sig/rb/snake.rbs
108
128
  homepage: https://github.com/mapra99/rb-snake
109
129
  licenses:
@@ -111,7 +131,7 @@ licenses:
111
131
  metadata:
112
132
  homepage_uri: https://github.com/mapra99/rb-snake
113
133
  source_code_uri: https://github.com/mapra99/rb-snake
114
- post_install_message:
134
+ post_install_message:
115
135
  rdoc_options: []
116
136
  require_paths:
117
137
  - lib
@@ -126,8 +146,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
146
  - !ruby/object:Gem::Version
127
147
  version: '0'
128
148
  requirements: []
129
- rubygems_version: 3.3.7
130
- signing_key:
149
+ rubygems_version: 3.3.26
150
+ signing_key:
131
151
  specification_version: 4
132
152
  summary: The classic snake game recreated using ruby
133
153
  test_files: []
data/.byebug_history DELETED
@@ -1,4 +0,0 @@
1
- exit
2
- actual_state
3
- n
4
- expected_state.snake
@@ -1,100 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Actions
4
- def self.move_snake(state)
5
- next_direction = state.curr_direction
6
- next_position = calc_next_position(state)
7
-
8
- if position_is_food? state, next_position
9
- state = grow_snake_to state, next_position
10
- generate_food state
11
- elsif position_is_valid? state, next_position
12
- move_snake_to state, next_position
13
- else
14
- end_game state
15
- end
16
- end
17
-
18
- def self.change_direction(state, direction)
19
- if next_direction_is_valid? state, direction
20
- state.curr_direction = direction
21
- else
22
- puts "Invalid direction"
23
- end
24
-
25
- state
26
- end
27
-
28
- private
29
-
30
- def self.generate_food(state)
31
- new_food = Model::Food.new(rand(state.grid.rows), rand(state.grid.cols))
32
- state.food = new_food
33
- state
34
- end
35
-
36
- def self.calc_next_position(state)
37
- curr_position = state.snake.positions.first
38
- case state.curr_direction
39
- when Model::Direction::UP
40
- Model::Coord.new(curr_position.row - 1,
41
- curr_position.col)
42
- when Model::Direction::RIGHT
43
- Model::Coord.new(curr_position.row,
44
- curr_position.col + 1)
45
- when Model::Direction::DOWN
46
- Model::Coord.new(curr_position.row + 1,
47
- curr_position.col)
48
- when Model::Direction::LEFT
49
- Model::Coord.new(curr_position.row,
50
- curr_position.col - 1)
51
- end
52
- end
53
-
54
- def self.position_is_food?(state, next_position)
55
- (state.food.row == next_position.row) && (state.food.col == next_position.col)
56
- end
57
-
58
- def self.position_is_valid?(state, position)
59
- # verificar que este en la grilla
60
- is_invalid = ((position.row >= state.grid.rows) || (position.row < 0)) ||
61
- ((position.col >= state.grid.cols) || (position.col < 0))
62
-
63
- return false if is_invalid
64
-
65
- # verificar que no este superponiendo a la serpiente
66
- !(state.snake.positions.include? position)
67
- end
68
-
69
- def self.grow_snake_to(state, next_position)
70
- state.snake.positions = [next_position] + state.snake.positions
71
- state
72
- end
73
-
74
- def self.move_snake_to(state, next_position)
75
- new_positions = [next_position] + state.snake.positions[0...-1]
76
- state.snake.positions = new_positions
77
-
78
- state
79
- end
80
-
81
- def self.end_game(state)
82
- state.game_finished = true
83
- state
84
- end
85
-
86
- def self.next_direction_is_valid?(state, direction)
87
- case state.curr_direction
88
- when Model::Direction::UP
89
- direction != Model::Direction::DOWN
90
- when Model::Direction::RIGHT
91
- direction != Model::Direction::LEFT
92
- when Model::Direction::DOWN
93
- direction != Model::Direction::UP
94
- when Model::Direction::LEFT
95
- direction != Model::Direction::RIGHT
96
- else
97
- false
98
- end
99
- end
100
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Representation of Game State
4
- module Model
5
- module Direction
6
- UP = :up
7
- RIGHT = :right
8
- DOWN = :down
9
- LEFT = :left
10
- end
11
-
12
- class Coord < Struct.new(:row, :col)
13
- end
14
-
15
- class Food < Coord
16
- end
17
-
18
- class Snake < Struct.new(:positions)
19
- end
20
-
21
- class Grid < Struct.new(:rows, :cols)
22
- end
23
-
24
- class State < Struct.new(:snake, :food, :grid, :curr_direction, :game_finished)
25
- end
26
-
27
- def self.initial_state
28
- Model::State.new(
29
- Model::Snake.new([Model::Coord.new(1, 1),
30
- Model::Coord.new(0, 1)]),
31
- Model::Food.new(4, 4),
32
- Model::Grid.new(8, 12),
33
- Direction::DOWN,
34
- false
35
- )
36
- end
37
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ruby2d'
4
- module View
5
- class Ruby2dView
6
- def initialize(app)
7
- @pixel_size = 50
8
- @app = app
9
- end
10
-
11
- def start(state)
12
- extend Ruby2D::DSL
13
- set(title: 'Snake',
14
- width: @pixel_size * state.grid.cols,
15
- height: @pixel_size * state.grid.rows)
16
- on :key_down do |event|
17
- handle_key_event event
18
- end
19
- show
20
- end
21
-
22
- def render(state)
23
- close if state.game_finished
24
- render_food(state)
25
- render_snake(state)
26
- end
27
-
28
- private
29
-
30
- def render_food(state)
31
- @food.remove if @food
32
- extend Ruby2D::DSL
33
- food = state.food
34
- @food = Square.new(
35
- x: food.col * @pixel_size,
36
- y: food.row * @pixel_size,
37
- size: @pixel_size,
38
- color: 'yellow'
39
- )
40
- end
41
-
42
- def render_snake(state)
43
- @snake.each(&:remove) if @snake
44
- extend Ruby2D::DSL
45
- snake = state.snake
46
- @snake = snake.positions.map do |pos|
47
- Square.new(
48
- x: pos.col * @pixel_size,
49
- y: pos.row * @pixel_size,
50
- size: @pixel_size,
51
- color: 'green'
52
- )
53
- end
54
- end
55
-
56
- def handle_key_event(event)
57
- case event.key
58
- when "up"
59
- @app.send_action(:change_direction, Model::Direction::UP)
60
- when "down"
61
- @app.send_action(:change_direction, Model::Direction::DOWN)
62
- when "left"
63
- @app.send_action(:change_direction, Model::Direction::LEFT)
64
- when "right"
65
- @app.send_action(:change_direction, Model::Direction::RIGHT)
66
- end
67
- end
68
- end
69
- end
data/rb-snake.gemspec DELETED
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/rb_snake/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "rb-snake"
7
- spec.version = RbSnake::VERSION
8
- spec.authors = ["Miguel Prada"]
9
- spec.email = ["mapra99@gmail.com"]
10
-
11
- spec.summary = "The classic snake game recreated using ruby"
12
- spec.description = "The classic snake game recreated using ruby"
13
- spec.homepage = "https://github.com/mapra99/rb-snake"
14
- spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.6.0"
16
-
17
- spec.metadata["homepage_uri"] = spec.homepage
18
- spec.metadata["source_code_uri"] = spec.homepage
19
-
20
- # Specify which files should be added to the gem when it is released.
21
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(__dir__) do
23
- `git ls-files -z`.split("\x0").reject do |f|
24
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
25
- end
26
- end
27
- spec.bindir = "exe"
28
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
- spec.require_paths = ["lib"]
30
-
31
- # Uncomment to register a new dependency of your gem
32
- spec.add_dependency 'ruby2d', '~> 0.12.0'
33
-
34
- spec.add_development_dependency 'rake', '~> 13.0'
35
- spec.add_development_dependency 'rspec', '~> 3.0'
36
- spec.add_development_dependency 'rubocop', '~> 1.21'
37
- spec.add_development_dependency 'rubocop-rspec', '~> 2.16.0'
38
-
39
- # For more information and examples about making a new gem, check out our
40
- # guide at: https://bundler.io/guides/creating_gem.html
41
- end