ruby_snake 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/ruby_snake CHANGED
@@ -4,7 +4,7 @@ $:.unshift File.expand_path('../../lib/', __FILE__)
4
4
 
5
5
  require 'ruby_snake'
6
6
 
7
- RubySnake.play
7
+ RubySnake.start
8
8
 
9
9
 
10
10
 
@@ -0,0 +1,64 @@
1
+ require 'socket'
2
+
3
+ module RubySnake
4
+ class Client
5
+
6
+ # The following code is a shit
7
+ def self.connect(host='127.0.0.1')
8
+ system 'clear'
9
+
10
+ @message = "0"
11
+ loop do
12
+
13
+ break if @stop
14
+
15
+ sleep Game.speed
16
+ next if @message == '3'
17
+ server = TCPSocket.new host, 2000
18
+
19
+ server.send @message, 0
20
+ server_message = server.recv(1)
21
+ @message = '3' if @message == '2'
22
+
23
+ if server_message == '0'
24
+ @message = '1'
25
+
26
+ puts '=' * 40
27
+ puts 'Connecting to host...'
28
+ puts '=' * 40
29
+
30
+ countdown
31
+
32
+ @thread = Thread.new do
33
+ Game.start 'client'
34
+ @message = '2'
35
+ Game.lose
36
+ @stop = true
37
+ end
38
+
39
+ elsif server_message == '1'
40
+ next
41
+ else
42
+ @thread.kill
43
+ Game.win
44
+ break
45
+ end
46
+ server.close
47
+ end
48
+
49
+ system 'clear'
50
+ end
51
+
52
+ def self.countdown
53
+ 3.times do |i|
54
+ puts 3 - i
55
+ sleep 1
56
+ end
57
+ end
58
+
59
+ def self.server
60
+ @server
61
+ end
62
+
63
+ end
64
+ end
@@ -8,18 +8,12 @@ module RubySnake
8
8
  QUIT = 113 # q
9
9
  YES = 121 # y
10
10
  NO = 110 # n
11
+ SINGLE_PLAYER = 115 # s
12
+ TWO_PLAYERS = 116 # t
13
+ CREATE_HOST = 115 # s
14
+ CONNECT_TO_HOST = 99 # c
11
15
 
12
- KEYBOARD_MAPPING = {
13
- UP => 'up',
14
- DOWN => 'down',
15
- LEFT => 'left',
16
- RIGHT => 'right',
17
- PAUSE => 'pause',
18
- QUIT => 'exit',
19
- YES => 'yes',
20
- NO => 'no'
21
- }
16
+ OPERATIONS = [UP, DOWN, LEFT, RIGHT, PAUSE, QUIT]
22
17
 
23
- OPERATIONS = [UP, DOWN, LEFT, RIGHT, PAUSE, QUIT, YES, NO]
24
18
  end
25
19
  end
@@ -1,7 +1,199 @@
1
1
  module RubySnake
2
2
  class Game
3
3
  class << self
4
- def start
4
+ include Config
5
+
6
+ def pause_or_continue
7
+ if pause?
8
+ continue
9
+ else
10
+ pause
11
+ end
12
+ end
13
+
14
+ def operation
15
+ @operation
16
+ end
17
+
18
+ def direction_opposite?(o)
19
+ return true if @operation == UP && o == DOWN
20
+ return true if @operation == DOWN && o == UP
21
+ return true if @operation == LEFT && o == RIGHT
22
+ return true if @operation == RIGHT && o == LEFT
23
+ end
24
+
25
+ def pause?
26
+ @pause_flag
27
+ end
28
+
29
+ def pause
30
+ @used_time = time
31
+ @pause_flag = true
32
+ end
33
+
34
+ def continue
35
+ @time_flag = Time.now.to_f
36
+ @pause_flag = false
37
+ end
38
+
39
+ def restart
40
+ UI.window.clear
41
+ @operation = RIGHT
42
+ @used_time = 0.0
43
+ @time_flag = Time.now.to_f
44
+ snake.init
45
+ Ncurses.nodelay window, true
46
+ end
47
+
48
+ def window
49
+ UI.window
50
+ end
51
+
52
+ def snake
53
+ UI.snake
54
+ end
55
+
56
+ def time
57
+ if pause?
58
+ @used_time
59
+ else
60
+ ((Time.now.to_f - @time_flag + @used_time.to_f) * 10).round / 10.0
61
+ end
62
+ end
63
+
64
+ def over?
65
+ UI.draw_over
66
+ loop do
67
+ case window.getch
68
+ when YES
69
+ return false
70
+ when NO
71
+ return true
72
+ end
73
+ end
74
+ end
75
+
76
+ def score
77
+ snake.body.length - 2
78
+ end
79
+
80
+ def level
81
+ score / 10 + 1
82
+ end
83
+
84
+ def speed
85
+ if score < 10
86
+ 0.2
87
+ elsif score >= 10 && score < 20
88
+ 0.1
89
+ elsif score >= 20 && score < 30
90
+ 0.05
91
+ elsif score >= 30
92
+ 0.03
93
+ end
94
+ end
95
+
96
+ def listen_operation
97
+ operation = window.getch
98
+
99
+ if OPERATIONS.include?(operation) && !direction_opposite?(operation)
100
+ case operation
101
+ when PAUSE
102
+ pause_or_continue unless Game.vs?
103
+ when QUIT
104
+ stop
105
+ else
106
+ @operation = operation unless Game.pause?
107
+ end
108
+ end
109
+
110
+ @operation
111
+ end
112
+
113
+ def choise_role
114
+ UI.draw_role_menu
115
+ loop do
116
+ case window.getch
117
+ when CREATE_HOST
118
+ Ncurses.endwin
119
+ create_server
120
+ break
121
+ when CONNECT_TO_HOST
122
+ Ncurses.endwin
123
+ connect
124
+ break
125
+ when QUIT
126
+ Ncurses.endwin
127
+ break
128
+ end
129
+ end
130
+ end
131
+
132
+ def choise_mode
133
+ loop do
134
+ case window.getch
135
+ when SINGLE_PLAYER
136
+ start
137
+ break
138
+ when TWO_PLAYERS
139
+ choise_role
140
+ break
141
+ when QUIT
142
+ Ncurses.endwin
143
+ break
144
+ end
145
+ end
146
+ end
147
+
148
+ def welcome
149
+ UI.draw_welcome
150
+ choise_mode
151
+ end
152
+
153
+ def create_server
154
+ Server.start
155
+ end
156
+
157
+ def win
158
+ UI.draw_win
159
+ sleep 1
160
+ window.getch
161
+ Ncurses.endwin
162
+ end
163
+
164
+ def lose
165
+ UI.draw_lose
166
+ sleep 1
167
+ window.getch
168
+ Ncurses.endwin
169
+ end
170
+
171
+ def connect
172
+ system 'clear'
173
+ print "Input host to connect: "
174
+ host = gets.chomp
175
+ Client.connect host
176
+ end
177
+
178
+ def stop
179
+ @operation = QUIT
180
+ end
181
+
182
+ def role
183
+ @role
184
+ end
185
+
186
+ def role= role
187
+ @role = role
188
+ end
189
+
190
+ def vs?
191
+ self.role
192
+ end
193
+
194
+ def start(role=nil)
195
+ self.role = role unless role.nil?
196
+ @time_flag = Time.now.to_f
5
197
  UI.draw
6
198
  end
7
199
  end
@@ -0,0 +1,67 @@
1
+ require 'socket'
2
+
3
+ module RubySnake
4
+ class Server
5
+
6
+ # The following code is a shit
7
+ def self.start
8
+ system 'clear'
9
+
10
+ server = TCPServer.new 2000
11
+ @message = '0'
12
+ loop do
13
+ if @message == '0'
14
+ puts '=' * 40
15
+ puts 'Waiting connection...'
16
+ puts '=' * 40
17
+ end
18
+
19
+ break if @stop
20
+ sleep Game.speed and next if @message == '3'
21
+
22
+ client = server.accept
23
+
24
+ if client
25
+ client_message = client.recv(1)
26
+ client.send @message, 0
27
+ @message = '3' if @message == '2'
28
+
29
+ if client_message == '0'
30
+ @message = '1'
31
+
32
+ countdown
33
+
34
+ @thread = Thread.new do
35
+ Game.start 'server'
36
+ @message = '2'
37
+ Game.lose
38
+ @stop = true
39
+ end
40
+
41
+ elsif client_message == '1'
42
+ next
43
+ else
44
+ @thread.kill
45
+ Game.win
46
+ break
47
+ end
48
+ end
49
+ client.close
50
+ end
51
+
52
+ system 'clear'
53
+ end
54
+
55
+ def self.countdown
56
+ 3.times do |i|
57
+ puts 3-i
58
+ sleep 1
59
+ end
60
+ end
61
+
62
+ def self.client
63
+ @client
64
+ end
65
+
66
+ end
67
+ end
@@ -1,11 +1,18 @@
1
1
  module RubySnake
2
2
  class Snake
3
+ include Config
4
+
3
5
  attr_accessor :direction, :head, :tail, :food, :width, :height
4
6
 
5
7
  def initialize(width, height)
6
8
  @width, @height = width - 3, height - 3
7
9
  end
8
10
 
11
+ def init
12
+ body.clear
13
+ body << [1, 0] << [0, 0]
14
+ end
15
+
9
16
  def body
10
17
  @body ||= Proc.new do
11
18
  body = []
@@ -38,7 +45,7 @@ module RubySnake
38
45
  end
39
46
 
40
47
  def direction
41
- @direction ||= 'right'
48
+ @direction ||= RIGHT
42
49
  end
43
50
 
44
51
  def head
@@ -47,8 +54,8 @@ module RubySnake
47
54
 
48
55
  def near_border?
49
56
  return true if head.first == 1 or head.last == 0
50
- return true if head.first == @width or head.first == @width - 1
51
- return true if head.last == @height
57
+ return true if head.first == width or head.first == width - 1
58
+ return true if head.last == height
52
59
  end
53
60
 
54
61
  def tail
@@ -59,17 +66,17 @@ module RubySnake
59
66
  x = head.first
60
67
  y = head.last
61
68
  case direction
62
- when 'down'
63
- return false if y + 1 > @height
69
+ when DOWN
70
+ return false if y + 1 > height
64
71
  body.unshift [x, y + 1]
65
- when 'up'
72
+ when UP
66
73
  return false if y - 1 < 0
67
74
  body.unshift [x, y - 1]
68
- when 'left'
75
+ when LEFT
69
76
  return false if x - 2 < 0
70
77
  body.unshift [x - 2, y]
71
- when 'right'
72
- return false if x + 2 > @width
78
+ when RIGHT
79
+ return false if x + 2 > width
73
80
  body.unshift [x + 2, y]
74
81
  end
75
82
  body.uniq == body
data/lib/ruby_snake/ui.rb CHANGED
@@ -1,10 +1,10 @@
1
- #encoding: utf-8
2
1
  require 'ncurses'
3
2
 
4
3
  module RubySnake
5
4
  class UI
6
5
  class << self
7
6
  include Config
7
+
8
8
  def init
9
9
  Ncurses.initscr
10
10
  Ncurses.cbreak
@@ -20,84 +20,59 @@ module RubySnake
20
20
  Ncurses.init_pair(3, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK);
21
21
  Ncurses.init_pair(4, Ncurses::COLOR_GREEN, Ncurses::COLOR_BLACK);
22
22
 
23
- @window = Ncurses::WINDOW.new(30, 101, (Ncurses.stdscr.getmaxy - 30) / 2, (Ncurses.stdscr.getmaxx - 101) / 2)
23
+ init_window
24
+
25
+ @snake = Snake.new window.getmaxx, window.getmaxy
26
+ end
27
+
28
+ def init_window
29
+ x = (Ncurses.stdscr.getmaxy - 30) / 2
30
+ y = (Ncurses.stdscr.getmaxx - 101) / 2
31
+
32
+ @window = Ncurses::WINDOW.new 30, 101, x, y
24
33
  unless @window
25
34
  @window = Ncurses.stdscr
26
35
  end
27
36
  Ncurses.nodelay @window, true
28
37
  @window.clear
29
- @operation = KEYBOARD_MAPPING[RIGHT]
30
- @snake = Snake.new(@window.getmaxx, @window.getmaxy)
31
- @time_flag = Time.now.to_f
32
38
  end
33
39
 
34
- def direction_opposite?(o)
35
- return true if @operation == 'up' && o == DOWN
36
- return true if @operation == 'down' && o == UP
37
- return true if @operation == 'left' && o == RIGHT
38
- return true if @operation == 'right' && o == LEFT
40
+ def window
41
+ @window
42
+ end
43
+
44
+ def snake
45
+ @snake
39
46
  end
40
47
 
41
48
  def display stuff, symbol
42
49
  x = stuff.last + 1
43
50
  y = stuff.first + 1
44
- @window.mvprintw(x, y, symbol)
51
+ window.mvprintw x, y, symbol
45
52
  end
46
53
 
47
- def score
48
- @snake.body.length - 2
54
+ def clear_tail
55
+ display snake.tail, ' '
49
56
  end
50
57
 
51
- def level
52
- score/10 + 1
53
- end
54
-
55
- def speed
56
- return 1 if @pause_flag
57
-
58
- if score < 10
59
- 0.2
60
- elsif score >= 10 && score < 20
61
- 0.1
62
- elsif score >= 20 && score < 30
63
- 0.05
64
- elsif score >= 30
65
- 0.03
66
- end
67
- end
68
-
69
- def time
70
- if @pause_flag
71
- @used_time
58
+ def draw_food
59
+ if Game.pause?
60
+ window.color_set 3, nil
72
61
  else
73
- ((Time.now.to_f - @time_flag + @used_time.to_f) * 10).round / 10.0
62
+ window.color_set 1, nil
74
63
  end
75
- end
76
-
77
- def pause
78
- @used_time = time
79
- @pause_flag ||= true
80
- end
81
-
82
- def continue
83
- @time_flag = Time.now.to_f
84
- @pause_flag = false
85
- end
86
-
87
- def clear
88
- display @snake.tail, ' '
89
- end
90
-
91
- def draw_food
92
- @window.color_set(1, nil)
93
- display @snake.food, '$'
94
- @window.refresh
64
+ display snake.food, '$'
65
+ window.refresh
95
66
  end
96
67
 
97
68
  def draw_snake
98
- @window.color_set(2, nil)
99
- @snake.body.each do |body|
100
- if body == @snake.head
69
+ if Game.pause?
70
+ window.color_set 3, nil
71
+ else
72
+ window.color_set 2, nil
73
+ end
74
+ snake.body.each do |body|
75
+ if body == snake.head
101
76
  display body, '@'
102
77
  else
103
78
  display body, 'o'
@@ -105,115 +80,147 @@ module RubySnake
105
80
  end
106
81
  end
107
82
 
108
- def pause_or_continue
109
- if @pause_flag
110
- continue
83
+ def draw_title
84
+ if Game.pause?
85
+ window.color_set 3, nil
86
+ elsif snake.near_border?
87
+ window.color_set 1, nil
111
88
  else
112
- pause
89
+ window.color_set 4, nil
113
90
  end
114
- end
91
+ y = snake.width / 2 - 15
115
92
 
116
- def draw_title
117
- @window.color_set(4, nil)
118
- y = @snake.width / 2 - 15
119
- @window.mvprintw(0, y, "Score: #{score} Level: #{level} Time: #{time}s")
93
+ window.mvprintw 0, y,
94
+ " Score: #{Game.score} Level: #{Game.level} Time: #{Game.time}s "
120
95
  end
121
96
 
122
97
  def draw_boder
123
- if @snake.near_border?
124
- @window.color_set(1, nil)
98
+
99
+ if Game.pause?
100
+ window.color_set 3, nil
101
+ elsif snake.near_border?
102
+ window.color_set 1, nil
125
103
  else
126
- @window.color_set(4, nil)
104
+ window.color_set 4, nil
127
105
  end
128
- @window.border(*([0] * 8))
106
+ window.border *([0] * 8)
129
107
  end
130
108
 
131
- def listen_operation
132
- operation = @window.getch
133
- if OPERATIONS.include?(operation) && !direction_opposite?(operation)
134
- case operation
135
- when PAUSE
136
- pause_or_continue
137
- when QUIT
138
- Thread.current.kill
139
- else
140
- @operation = operation
141
- @operation = KEYBOARD_MAPPING[@operation]
142
- end
143
- end
144
- end
109
+ def draw_dialog y, x, text
110
+
111
+ text =
112
+
113
+ "
114
+ < #{text} >
115
+ " <<
116
+
117
+ '
145
118
 
146
- def game_over
147
- x = @window.getmaxx / 2
148
- y = @window.getmaxy / 2 - 10
149
- Ncurses.nodelay @window, false
150
- @window.clear
151
119
 
152
- text = '
153
120
 
154
- _________________________________
155
- < Opps, I am died, restart? (y/n) >
156
- ---------------------------------
157
121
  .-.
158
122
  / aa
159
123
  \ -,_)
160
124
  _..._| \ `-<
161
- {} ." .__.\' |
125
+ {} .\" .__.\' |
162
126
  {} ( /`\
163
127
  {}(`\'------\' /
164
128
  |\/;._______.\'\
165
129
  ; \ /
166
130
  \'-\'-.......-\'
167
-
168
-
169
131
  '
170
132
 
171
- @window.mvaddstr(y, x, text)
172
- @window.refresh
173
- while true
174
- case @window.getch
175
- when YES
176
- return false
177
- when NO
178
- return true
179
- end
180
- end
133
+ window.mvaddstr y, x, text
134
+ window.refresh
135
+ end
136
+
137
+ def draw_quit
138
+ x = window.getmaxx / 2
139
+ y = window.getmaxy / 2 - 10
140
+ window.clear
141
+ draw_dialog y, x, "Oops, I am died, restart? (y/n)"
181
142
  end
182
143
 
144
+ def draw_over
145
+ Ncurses.nodelay window, false
146
+ x = window.getmaxx / 2
147
+ y = window.getmaxy / 2 - 10
148
+ window.clear
149
+ draw_dialog y, x, "Oops, I am died, restart? (y/n)"
150
+ end
151
+
152
+ def draw_lose
153
+ window.color_set 1, nil
154
+ Ncurses.nodelay window, false
155
+ x = window.getmaxx / 2
156
+ y = window.getmaxy / 2 - 10
157
+ window.clear
158
+ draw_dialog y, x, "Sorry, you lose the game."
159
+ end
160
+
161
+ def draw_win
162
+ window.color_set 4, nil
163
+ Ncurses.nodelay window, false
164
+ x = window.getmaxx / 2
165
+ y = window.getmaxy / 2 - 10
166
+ window.clear
167
+ draw_dialog y, x, "Congratulations, you win the game."
168
+ end
169
+
170
+
183
171
  def draw_map
184
172
  draw_boder
185
173
  draw_title
186
174
  draw_snake
187
175
  draw_food
188
- clear
189
- sleep speed
190
- @window.refresh
176
+ clear_tail
177
+ sleep Game.speed
178
+ window.refresh
191
179
  end
192
180
 
193
- def restart
194
- @window.clear
195
- @operation = nil
196
- Ncurses.nodelay @window, true
197
- @snake = Snake.new(@window.getmaxx, @window.getmaxy)
181
+ def draw_welcome
182
+ init
183
+ begin
184
+ Ncurses.nodelay window, false
185
+ x = window.getmaxx / 2
186
+ y = window.getmaxy / 2 - 10
187
+ window.clear
188
+ draw_dialog y, x, 'Single Player? (s) or Two Players? (t)'
189
+ ensure
190
+ Ncurses.endwin
191
+ end
192
+ end
193
+
194
+ def draw_role_menu
195
+ begin
196
+ Ncurses.nodelay window, false
197
+ x = window.getmaxx / 2
198
+ y = window.getmaxy / 2 - 10
199
+ window.clear
200
+ draw_dialog y, x, 'Create Host? (s) or Connect to a Host? (c)'
201
+ ensure
202
+ Ncurses.endwin
203
+ end
198
204
  end
199
205
 
200
206
  def draw
207
+ Ncurses.nodelay window, true
208
+ window.clear
201
209
  begin
202
- init
203
- while true
204
- listen_operation
210
+ loop do
205
211
  draw_map
206
- if !@pause_flag && !@snake.move(@operation)
207
- sleep 1
208
- if game_over
212
+ operation = Game.listen_operation
213
+ break if operation == QUIT
214
+ if !Game.pause? && !snake.move(operation)
215
+ if Game.vs? || Game.over?
209
216
  break
210
217
  else
211
- restart
218
+ Game.restart
212
219
  end
213
220
  end
214
221
  end
215
222
  ensure
216
- Ncurses.endwin()
223
+ Ncurses.endwin
217
224
  end
218
225
  end
219
226
  end
@@ -1,3 +1,3 @@
1
1
  module RubySnake
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/ruby_snake.rb CHANGED
@@ -7,8 +7,11 @@ module RubySnake
7
7
  autoload :Game, 'ruby_snake/game'
8
8
  autoload :Snake, 'ruby_snake/snake'
9
9
  autoload :Config, 'ruby_snake/config'
10
+ autoload :Server, 'ruby_snake/server'
11
+ autoload :Client, 'ruby_snake/client'
10
12
 
11
- def self.play
12
- Game.start
13
+ def self.start(player=1)
14
+ Game.welcome
13
15
  end
16
+
14
17
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_snake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-20 00:00:00.000000000 Z
12
+ date: 2012-12-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ncurses-ruby
@@ -42,8 +42,10 @@ files:
42
42
  - Rakefile
43
43
  - bin/ruby_snake
44
44
  - lib/ruby_snake.rb
45
+ - lib/ruby_snake/client.rb
45
46
  - lib/ruby_snake/config.rb
46
47
  - lib/ruby_snake/game.rb
48
+ - lib/ruby_snake/server.rb
47
49
  - lib/ruby_snake/snake.rb
48
50
  - lib/ruby_snake/ui.rb
49
51
  - lib/ruby_snake/version.rb