snakes 0.0.1 → 0.1.0

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: bc78d31fc1e7b1a82a7d8fa4169835dc53cde3be9c2826afcb6ffb29b4960c99
4
- data.tar.gz: 3abd2b3f6153cc48198a8559360778a9990580b13ff4dbdbbe931a726659130e
3
+ metadata.gz: ba7d24f2b0258fb0f6eb0eb19aa8de9527dbb2d3a9b52fe3d86bc1e5aa226faa
4
+ data.tar.gz: 6a9dd99f563da54e60c88c49645d848367ac5b716585ea36a6e0843908cee46c
5
5
  SHA512:
6
- metadata.gz: b8cc205575d0d2bda27d4c99c105eeca39fe349ed3aaf44cde9b77d97783dbedbc45bf6a3de6f99dfc21d6f7b879484359dacdff1eebfe58326cd779817f36f5
7
- data.tar.gz: 2b3870c18c1677053850b48f2bb485edb843a83e2df081ca0b1913097369be78e68f9f9093b1afd130f2ed2361ea855f1b3b5c32b35d3942f89c5d02a73001cf
6
+ metadata.gz: cd28636c959481e634b4a7eb6d4d5cb84ee9eeef87383edce063f7aece6472b76d103cded0e4ae6fb4515f265399bcdadb3fd5f8dfdf27f824a25c70929d3fe1
7
+ data.tar.gz: 45294ee4a69b57c14dcf4b74531f46a1a1e511f4a5220920f1c216f4b1b0aedcc785f25c781d0381e8a6545c48b63d585d4a93568dbd7b9054580bdd0e9ba075
data/.idea/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Datasource local storage ignored files
7
+ /dataSources/
8
+ /dataSources.local.xml
data/.idea/misc.xml ADDED
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager" version="2" project-jdk-name="asdf: 2.7.4" project-jdk-type="RUBY_SDK" />
4
+ </project>
data/.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/snakes.iml" filepath="$PROJECT_DIR$/.idea/snakes.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
data/.idea/snakes.iml ADDED
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="ModuleRunConfigurationManager">
4
+ <shared />
5
+ </component>
6
+ <component name="NewModuleRootManager">
7
+ <content url="file://$MODULE_DIR$" />
8
+ <orderEntry type="jdk" jdkName="asdf: 3.1.0" jdkType="RUBY_SDK" />
9
+ <orderEntry type="sourceFolder" forTests="false" />
10
+ <orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, asdf: 3.1.0) [gem]" level="application" />
11
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v2.3.3, asdf: 3.1.0) [gem]" level="application" />
12
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.15.0, asdf: 3.1.0) [gem]" level="application" />
13
+ <orderEntry type="library" scope="PROVIDED" name="parallel (v1.21.0, asdf: 3.1.0) [gem]" level="application" />
14
+ <orderEntry type="library" scope="PROVIDED" name="parser (v3.0.3.2, asdf: 3.1.0) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="rainbow (v3.0.0, asdf: 3.1.0) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.6, asdf: 3.1.0) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="regexp_parser (v2.2.0, asdf: 3.1.0) [gem]" level="application" />
18
+ <orderEntry type="library" scope="PROVIDED" name="rexml (v3.2.5, asdf: 3.1.0) [gem]" level="application" />
19
+ <orderEntry type="library" scope="PROVIDED" name="rubocop (v1.24.1, asdf: 3.1.0) [gem]" level="application" />
20
+ <orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v1.15.1, asdf: 3.1.0) [gem]" level="application" />
21
+ <orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.11.0, asdf: 3.1.0) [gem]" level="application" />
22
+ <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v2.1.0, asdf: 3.1.0) [gem]" level="application" />
23
+ </component>
24
+ </module>
data/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
data/Gemfile CHANGED
@@ -5,8 +5,7 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in snakes.gemspec
6
6
  gemspec
7
7
 
8
+ gem "curses", "~> 1.4.4"
8
9
  gem "rake", "~> 13.0"
9
-
10
10
  gem "minitest", "~> 5.0"
11
-
12
11
  gem "rubocop", "~> 1.21"
data/Gemfile.lock CHANGED
@@ -7,25 +7,26 @@ GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.2)
10
+ curses (1.4.4)
10
11
  minitest (5.15.0)
11
12
  parallel (1.21.0)
12
- parser (3.0.3.2)
13
+ parser (3.1.1.0)
13
14
  ast (~> 2.4.1)
14
- rainbow (3.0.0)
15
+ rainbow (3.1.1)
15
16
  rake (13.0.6)
16
- regexp_parser (2.2.0)
17
+ regexp_parser (2.2.1)
17
18
  rexml (3.2.5)
18
- rubocop (1.24.1)
19
+ rubocop (1.25.1)
19
20
  parallel (~> 1.10)
20
- parser (>= 3.0.0.0)
21
+ parser (>= 3.1.0.0)
21
22
  rainbow (>= 2.2.2, < 4.0)
22
23
  regexp_parser (>= 1.8, < 3.0)
23
24
  rexml
24
25
  rubocop-ast (>= 1.15.1, < 2.0)
25
26
  ruby-progressbar (~> 1.7)
26
27
  unicode-display_width (>= 1.4.0, < 3.0)
27
- rubocop-ast (1.15.1)
28
- parser (>= 3.0.1.1)
28
+ rubocop-ast (1.16.0)
29
+ parser (>= 3.1.1.0)
29
30
  ruby-progressbar (1.11.0)
30
31
  unicode-display_width (2.1.0)
31
32
 
@@ -33,10 +34,11 @@ PLATFORMS
33
34
  x86_64-linux
34
35
 
35
36
  DEPENDENCIES
37
+ curses (~> 1.4.4)
36
38
  minitest (~> 5.0)
37
39
  rake (~> 13.0)
38
40
  rubocop (~> 1.21)
39
41
  snakes!
40
42
 
41
43
  BUNDLED WITH
42
- 2.3.3
44
+ 2.3.4
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Snakes
1
+ b# Snakes
2
2
 
3
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/snakes`. To experiment with that code, run `bin/console` for an interactive prompt.
4
4
 
data/exe/snakes ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/snakes"
4
+
5
+ Snakes::Game.new.run
@@ -0,0 +1,349 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ module Snakes
4
+ require "curses"
5
+
6
+ Curses.init_screen
7
+ Curses.cbreak
8
+ Curses.noecho
9
+ Curses.curs_set(0) # Invisible cursor
10
+ Curses.stdscr.keypad = true
11
+
12
+ exit_game = lambda do
13
+ Game.stop
14
+ puts "Good Bye! :D"
15
+ exit 130
16
+ end
17
+
18
+ trap("INT") { exit_game.call }
19
+ at_exit { exit_game.call }
20
+
21
+ class Game
22
+ def initialize
23
+ @snake_head_icon = "o" #"*"
24
+ @snake_node_icon = "·" # "#"
25
+ @food_icon = "+" # "#"
26
+
27
+ @game_speed = 5
28
+ @game_update_time = 1.0 / @game_speed
29
+
30
+ @non_block_timeout = 0.001
31
+
32
+ @frame = nil
33
+ @board = nil
34
+
35
+ @window_width = nil
36
+ @window_height = nil
37
+
38
+ @board_width = nil
39
+ @board_height = nil
40
+
41
+ @pause = false
42
+ @game_status = :RUN # :RUN ,:PAUSE, :GAME_OVER
43
+
44
+ @direction = [:UP, :DOWN, :LEFT, :RIGHT]
45
+ @current_direction = @direction.sample
46
+
47
+ self.init_game_board
48
+
49
+ @snake = (1..2).map { |i| [(@board_height / 2).to_i + i, (@board_width / 2).to_i] }
50
+
51
+ @food = [@board_height / 2 + 2, @board_width / 2 + 2]
52
+
53
+ @press = nil
54
+ @score = 0
55
+ @speed = 1
56
+ end
57
+
58
+ def init_game_board
59
+
60
+ # Window Frame
61
+ @window_height = Curses.lines
62
+ @window_width = Curses.cols
63
+
64
+ @board_height = (@window_height * 0.8).to_i
65
+ @board_width = (@window_width * 0.6).to_i
66
+
67
+ @info_board_height = (@window_height * 0.5).to_i
68
+ @info_board_width = (@window_width * 0.3).to_i
69
+
70
+ @frame = Curses::Window.new(@window_height, @window_width, 0, 0)
71
+
72
+ title = "Snakes"
73
+ @frame.setpos(0, @board_width / 2 - title.length / 2)
74
+ @frame.addstr(title)
75
+ @frame.refresh
76
+
77
+ @board = @frame.subwin(@board_height, @board_width, 1, 1)
78
+ @board.keypad = true
79
+ @board.timeout = @non_block_timeout
80
+
81
+ @board.box(0, 0)
82
+ @board.refresh
83
+
84
+ @info_board = @frame.subwin(
85
+ @info_board_height,
86
+ @info_board_width,
87
+ 1,
88
+ @board_width + 1
89
+ )
90
+ @info_board.box(0, 0)
91
+ @info_board.refresh
92
+ end
93
+
94
+ def create_food
95
+ @food = [rand(2..@board_height - 2), rand(2..@board_width - 2)]
96
+
97
+ unless is_safe_food?
98
+ @food = [rand(2..@board_height - 2), rand(2..@board_width - 2)]
99
+ end
100
+ end
101
+
102
+ def is_safe_food?
103
+ return !@snake.include?(@food)
104
+ end
105
+
106
+ def inc_speed
107
+ speed = @game_speed + 1
108
+ if speed >= 30
109
+ @game_speed = 30
110
+ else
111
+ @game_speed = speed
112
+ end
113
+
114
+ self.update_tick
115
+ end
116
+
117
+ def dec_speed
118
+ speed = @game_speed - 1
119
+ if speed <= 5
120
+ @game_speed = 5
121
+ else
122
+ @game_speed = speed
123
+ end
124
+
125
+ self.update_tick
126
+ end
127
+
128
+ def render_game_info
129
+ # Press Key
130
+ @info_board.setpos(1, 1)
131
+ @info_board.addstr("[Press]: #{@current_direction.to_s}")
132
+
133
+ # score
134
+ @info_board.setpos(3, 1)
135
+ @info_board.addstr("[Score]: #{@score}")
136
+
137
+ # speed
138
+ @info_board.setpos(5, 1)
139
+ @info_board.addstr("[Speed]: #{@game_speed}")
140
+
141
+ # tick time
142
+ @info_board.setpos(7, 1)
143
+ @info_board.addstr("[Tick]: #{@game_update_time}")
144
+
145
+ # status
146
+ @info_board.setpos(9, 1)
147
+ @info_board.addstr("[Status]: #{@game_status}")
148
+ end
149
+
150
+ def render_food
151
+ food_y, food_x = @food
152
+ @board.setpos(food_y, food_x)
153
+ @board.addch(@food_icon)
154
+ end
155
+
156
+ def render_snake
157
+ snake_path = @snake.dup
158
+
159
+ head_y, head_x = snake_path.shift
160
+
161
+ @board.setpos(head_y, head_x)
162
+ @board.addch(@snake_head_icon)
163
+
164
+ snake_path.each do |node_pos|
165
+ node_y, node_x = node_pos
166
+ @board.setpos(node_y, node_x)
167
+ @board.addstr(@snake_node_icon)
168
+ end
169
+ end
170
+
171
+ def check_game(next_point)
172
+ if @snake.include?(next_point)
173
+ @game_status = :GAME_OVER
174
+ return false
175
+ end
176
+
177
+ next_y, next_x = next_point
178
+
179
+ if !(next_x > 0 && next_x < @board_width && next_y > 0 && next_y < @board_height)
180
+ @game_status = :GAME_OVER
181
+ return false
182
+ end
183
+
184
+ food_y, food_x = @food
185
+ if food_y == next_y && food_x == next_x
186
+ @score += 1
187
+ @snake.unshift(@food)
188
+ self.create_food
189
+ end
190
+ return true
191
+ end
192
+
193
+ def add_step
194
+ head_y, head_x = @snake.first.dup
195
+
196
+ if @current_direction == :UP
197
+ head_y -= 1
198
+ if head_y <= 0
199
+ head_y = 1
200
+ end
201
+ elsif @current_direction == :DOWN
202
+ head_y += 1
203
+ if head_y >= @board_height
204
+ head_y = @board_height - 1
205
+ end
206
+ elsif @current_direction == :LEFT
207
+ head_x -= 1
208
+ if head_x <= 0
209
+ head_x = 1
210
+ end
211
+ elsif @current_direction == :RIGHT
212
+ head_x += 1
213
+ if head_x >= @board_width
214
+ head_x = @board_width - 1
215
+ end
216
+ else
217
+ return
218
+ end
219
+
220
+ next_point = [head_y, head_x]
221
+
222
+ result = self.check_game(next_point)
223
+ if result
224
+ @snake.unshift(next_point)
225
+ @snake.pop
226
+ end
227
+ end
228
+
229
+ def _event_listener
230
+ while true
231
+ c = @board.getch
232
+ if c
233
+ @press = c
234
+ end
235
+
236
+ head_y, head_x = @snake.first.dup
237
+
238
+ if c == Curses::KEY_UP || c == "w"
239
+ @current_direction = :UP
240
+ elsif c == Curses::KEY_DOWN || c == "s"
241
+ @current_direction = :DOWN
242
+ elsif c == Curses::KEY_LEFT || c == "a"
243
+ @current_direction = :LEFT
244
+ elsif c == Curses::KEY_RIGHT || c == "d"
245
+ @current_direction = :RIGHT
246
+ elsif c == Curses::KEY_BACKSPACE || c == "p"
247
+ @game_status = @game_status == :PAUSE ? :RUN : :PAUSE
248
+ elsif c == "m"
249
+ self.inc_speed
250
+ elsif c == "n"
251
+ self.dec_speed
252
+ else
253
+ return # 这里其实断掉了。其实接住了外循环,每次读取数据
254
+ end
255
+ end
256
+ end
257
+
258
+ def reset_game
259
+ self.initialize
260
+ end
261
+
262
+ def update_tick
263
+ @game_update_time = (1.0 / @game_speed).round(2)
264
+ end
265
+
266
+ def check_speed
267
+ @game_speed = @score % 5 + 5
268
+ self.update_tick
269
+ end
270
+
271
+ def main_loop
272
+ loop do
273
+ self.init_game_board
274
+ self.reset_game
275
+ game_result = catch(:end_game) do
276
+ while @game_status != :GAME_OVER
277
+ self._event_listener
278
+
279
+ @board.clear
280
+ @info_board.clear
281
+ @board.box(0, 0)
282
+ @info_board.box(0, 0)
283
+
284
+ if @game_status == :RUN
285
+ self.add_step
286
+ end
287
+ self.check_speed
288
+ self.render_food
289
+ self.render_snake
290
+ self.render_game_info
291
+
292
+ @board.refresh
293
+ @info_board.refresh
294
+ sleep @game_update_time
295
+ end
296
+
297
+ throw :end_game, :GAME_OVER
298
+ end
299
+
300
+ next_status = catch(:next_action) do
301
+ if game_result == :GAME_OVER
302
+ @board.timeout = -1
303
+ @board.clear
304
+ @board.box(0, 0)
305
+ @board.setpos(@board_height / 2, @board_width / 2 - 10)
306
+ @board.addstr("GAME OVER")
307
+ @board.setpos(@board_height / 2 + 2, @board_width / 2 - 10)
308
+ @board.addstr("Play Again?")
309
+ @board.setpos(@board_height / 2 + 3, @board_width / 2 - 10)
310
+ @board.addstr("Y:Yes/ N: Exit")
311
+ @board.refresh
312
+ @board.timeout = -1
313
+
314
+ next_goto = nil
315
+ while next_goto != "y"
316
+ next_goto = @board.getch
317
+ if next_goto == "n"
318
+ exit 0
319
+ elsif next_goto == "y"
320
+ @board.setpos(@board_height / 2 + 4, @board_width / 2 - 10)
321
+ @board.addstr(next_goto)
322
+ @board.refresh
323
+
324
+ throw :next_action, :RUN
325
+ end
326
+ end
327
+ end
328
+ end
329
+
330
+ @game_status = next_status
331
+ end
332
+ end
333
+
334
+ def run
335
+ self.main_loop
336
+ end
337
+
338
+ class << self
339
+ def run
340
+ @app = self.new
341
+ @app.run
342
+ end
343
+
344
+ def stop
345
+ Curses.close_screen
346
+ end
347
+ end
348
+ end
349
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Snakes
4
- VERSION = "0.0.1"
4
+ VERSION = "0.1.0"
5
5
  end
data/lib/snakes.rb CHANGED
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  require_relative "snakes/version"
3
+ require_relative "./snakes/game"
4
4
 
5
5
  module Snakes
6
6
  class Error < StandardError; end
7
- puts "hello world this is snakes game"
8
- # Your code goes here...
9
7
  end
metadata CHANGED
@@ -1,22 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snakes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark24
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-06 00:00:00.000000000 Z
11
+ date: 2022-02-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Snakes game power by Ruby.
14
14
  email:
15
15
  - mark.zhangyoung@qq.com
16
- executables: []
16
+ executables:
17
+ - snakes
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
21
+ - ".idea/.gitignore"
22
+ - ".idea/misc.xml"
23
+ - ".idea/modules.xml"
24
+ - ".idea/snakes.iml"
25
+ - ".idea/vcs.xml"
20
26
  - ".rubocop.yml"
21
27
  - CHANGELOG.md
22
28
  - Gemfile
@@ -26,7 +32,9 @@ files:
26
32
  - Rakefile
27
33
  - bin/console
28
34
  - bin/setup
35
+ - exe/snakes
29
36
  - lib/snakes.rb
37
+ - lib/snakes/game.rb
30
38
  - lib/snakes/version.rb
31
39
  - sig/snakes.rbs
32
40
  - snakes.gemspec