snake_game 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,28 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Documentation cache and generated files:
13
+ /.yardoc/
14
+ /_yardoc/
15
+ /doc/
16
+ /rdoc/
17
+
18
+ ## Environment normalisation:
19
+ /.bundle/
20
+ /lib/bundler/man/
21
+
22
+
23
+ Gemfile.lock
24
+ .ruby-version
25
+ .ruby-gemset
26
+
27
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
28
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'bump'
5
+ gem 'rake'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 José M. Gilgado
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ snake_game
2
+ ==========
3
+
4
+ Snake game implemented in Ruby using Curses
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require "bump/tasks"
4
+
5
+ task :default => :run
6
+
7
+ task :run do
8
+ exec "./bin/snake_game"
9
+ end
data/bin/snake_game ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
+
4
+ require 'snake_game'
5
+
6
+ Game.new.create
data/lib/snake_game.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "snake_game/version"
2
+
3
+ module SnakeGame
4
+ require 'snake_game/food'
5
+ require 'snake_game/snake'
6
+ require 'snake_game/term_window'
7
+ require 'snake_game/game'
8
+ end
9
+
@@ -0,0 +1,32 @@
1
+ class Food
2
+ attr_accessor :window, :points, :symbol, :x, :y
3
+
4
+ DEFAULT_SYMBOL = "*"
5
+
6
+ def initialize(window, x = nil, y = nil)
7
+ @window = window
8
+ @x = x || generate_random_x
9
+ @y = y || generate_random_y
10
+ @symbol = DEFAULT_SYMBOL
11
+ @points = 1
12
+ end
13
+
14
+ def has_been_eaten_by?(snake)
15
+ snake[0][0] == @x && snake[0][1] == @y
16
+ end
17
+
18
+ def relocate_without_conflict!(snake)
19
+ if snake.include? [@x, @y]
20
+ @x = generate_random_x
21
+ @y = generate_random_y
22
+ end
23
+ end
24
+
25
+ def generate_random_x
26
+ Random.rand(1..@window.width - 2)
27
+ end
28
+
29
+ def generate_random_y
30
+ Random.rand(1..@window.height - 2)
31
+ end
32
+ end
@@ -0,0 +1,83 @@
1
+ require 'curses'
2
+
3
+ class Game
4
+ INVISIBLE_CURSOR = 0
5
+
6
+ attr_reader :window, :snake
7
+
8
+ def initialize
9
+ @window = TermWindow.new
10
+ @snake = Snake.new([[4,10], [4,9], [4,8]])
11
+ end
12
+
13
+ def create
14
+ Curses.init_screen()
15
+ Curses.cbreak()
16
+ Curses.noecho
17
+ Curses.curs_set(INVISIBLE_CURSOR)
18
+
19
+ run
20
+ end
21
+
22
+ private
23
+ def run
24
+ key = Curses::KEY_RIGHT
25
+ score = 0
26
+
27
+ food = Food.new(window)
28
+ food.relocate_without_conflict!(@snake)
29
+
30
+ window.paint_food(food)
31
+
32
+ while (key != 27)
33
+ window.setpos(0, (window.width / 2) - 10)
34
+ window.addstr(" Score: #{score.to_s} ")
35
+ window.timeout = 150
36
+
37
+ prev_key = key
38
+ event = window.getch()
39
+ key = event == -1 ? key : event
40
+
41
+ key = prev_key unless [Curses::KEY_DOWN, Curses::KEY_UP, Curses::KEY_RIGHT, Curses::KEY_LEFT, 27].include?(key)
42
+
43
+ case key
44
+ when Curses::KEY_DOWN
45
+ @snake.insert(0, [@snake[0][0], @snake[0][1] + 1])
46
+ when Curses::KEY_UP
47
+ @snake.insert(0, [@snake[0][0], @snake[0][1] - 1])
48
+ when Curses::KEY_LEFT
49
+ @snake.insert(0, [@snake[0][0] - 1, @snake[0][1]])
50
+ when Curses::KEY_RIGHT
51
+ @snake.insert(0, [@snake[0][0] + 1, @snake[0][1]])
52
+ end
53
+
54
+ @snake[0][0] = (window.width.to_i - 2) if @snake[0][0] == 0
55
+ @snake[0][1] = (window.height.to_i - 2) if @snake[0][1] == 0
56
+ @snake[0][0] = 1 if @snake[0][0] == window.width - 1
57
+ @snake[0][1] = 1 if @snake[0][1] == window.height - 1
58
+
59
+ if snake.crashed?
60
+ break
61
+ end
62
+
63
+ if food.has_been_eaten_by?(@snake)
64
+ score += food.points
65
+ food = Food.new(window)
66
+ food.relocate_without_conflict!(@snake)
67
+ window.paint_food(food)
68
+ else
69
+ last_part = @snake.pop
70
+ window.setpos(last_part[1], last_part[0])
71
+ window.addstr(' ')
72
+ end
73
+
74
+ window.paint_snake(@snake)
75
+ end
76
+
77
+ window.close
78
+ Curses.close_screen
79
+
80
+ puts("----- GAME OVER -----")
81
+ puts("----- Score: #{score} -----")
82
+ end
83
+ end
@@ -0,0 +1,19 @@
1
+ require 'set'
2
+
3
+ class Snake < Array
4
+ SYMBOL = 'O'
5
+
6
+ def crashed?
7
+ visited = Set.new
8
+
9
+ self.each_with_index do |position, i|
10
+ if visited.include?(position)
11
+ return true
12
+ else
13
+ visited << position
14
+ end
15
+ end
16
+
17
+ return false
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ require 'curses'
2
+
3
+ class TermWindow < Curses::Window
4
+ DEFAULT_WIDTH = 100
5
+ DEFAULT_HEIGHT = 20
6
+
7
+ attr_accessor :width, :height
8
+
9
+ def initialize(height = DEFAULT_HEIGHT, width = DEFAULT_WIDTH)
10
+ super(height, width, 0, 0)
11
+ @width, @height = width, height
12
+ self.box(?|, ?-)
13
+ self.keypad(true)
14
+ end
15
+
16
+ def paint_food(food)
17
+ self.setpos(food.y, food.x)
18
+ self.addstr(food.symbol)
19
+ self.refresh
20
+ end
21
+
22
+ def paint_snake(snake)
23
+ self.setpos(snake[0][1], snake[0][0])
24
+ self.addstr(Snake::SYMBOL)
25
+ self.refresh
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module SnakeGame
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,18 @@
1
+ #encoding: utf-8
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
4
+
5
+ name = "snake_game"
6
+ require "#{name}/version"
7
+
8
+ Gem::Specification.new name, SnakeGame::VERSION do |s|
9
+ s.summary = "Play classic Snake game using Curses"
10
+ s.email = "jm.gilgado@gmail.com"
11
+ s.homepage = "http://github.com/josem/#{name}"
12
+ s.authors = ["José M. Gilgado"]
13
+ s.files = `git ls-files`.split("\n")
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ s.license = "MIT"
16
+ s.add_runtime_dependency "curses"
17
+ end
18
+
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snake_game
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - José M. Gilgado
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-07-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: curses
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description:
31
+ email: jm.gilgado@gmail.com
32
+ executables:
33
+ - snake_game
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - bin/snake_game
43
+ - lib/snake_game.rb
44
+ - lib/snake_game/food.rb
45
+ - lib/snake_game/game.rb
46
+ - lib/snake_game/snake.rb
47
+ - lib/snake_game/term_window.rb
48
+ - lib/snake_game/version.rb
49
+ - snake_game.gemspec
50
+ homepage: http://github.com/josem/snake_game
51
+ licenses:
52
+ - MIT
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ segments:
64
+ - 0
65
+ hash: -4062283852686282717
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ segments:
73
+ - 0
74
+ hash: -4062283852686282717
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 1.8.23
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: Play classic Snake game using Curses
81
+ test_files: []