ruby_snake 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -1
- data/lib/ruby_snake/client.rb +29 -53
- data/lib/ruby_snake/game.rb +159 -97
- data/lib/ruby_snake/server.rb +24 -56
- data/lib/ruby_snake/ui/base.rb +40 -0
- data/lib/ruby_snake/ui/one.rb +96 -0
- data/lib/ruby_snake/ui/two.rb +158 -0
- data/lib/ruby_snake/ui.rb +34 -172
- data/lib/ruby_snake/version.rb +1 -1
- data/lib/ruby_snake.rb +3 -1
- metadata +5 -2
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Ruby Snake
|
2
2
|
|
3
|
-
Ruby Snake is a simple greedy-snake like game, it is plable at command-line
|
3
|
+
Ruby Snake is a simple greedy-snake like game, it is plable at command-line.
|
4
4
|
The rules are the same of any snake game:
|
5
5
|
|
6
6
|
> You control a stupid snake and the objective is to eat as many money you can. Each money eaten increases it's size by one unit and movement speed will be more and more fast.
|
@@ -9,8 +9,11 @@ The rules are the same of any snake game:
|
|
9
9
|
|
10
10
|
> To each money is given a bonus value, so the challenge is to earn the biggest score possible by eating as much money as you can.
|
11
11
|
|
12
|
+
In addition, two players can fight online.
|
13
|
+
|
12
14
|
Good Luck!
|
13
15
|
|
16
|
+
|
14
17
|
![image](http://zgm.dn.qbox.me/ruby_snake.png)
|
15
18
|
|
16
19
|
## Installation
|
data/lib/ruby_snake/client.rb
CHANGED
@@ -1,64 +1,40 @@
|
|
1
|
-
require 'socket'
|
2
|
-
|
3
1
|
module RubySnake
|
4
2
|
class Client
|
5
3
|
|
6
4
|
# The following code is a shit
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
5
|
+
class << self
|
6
|
+
attr_accessor :message, :snake
|
7
|
+
|
8
|
+
def connect(host='127.0.0.1')
|
9
|
+
@message = '0'
|
10
|
+
|
11
|
+
loop do
|
12
|
+
sleep Game.speed
|
13
|
+
|
14
|
+
begin
|
15
|
+
server = TCPSocket.new host, 2000
|
16
|
+
rescue => err
|
17
|
+
@message = '10'
|
18
|
+
break
|
37
19
|
end
|
38
20
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
21
|
+
server.send @message, 0
|
22
|
+
server_message = server.recv(4096)
|
23
|
+
|
24
|
+
case server_message
|
25
|
+
when '0'
|
26
|
+
@message = '1'
|
27
|
+
when '1'
|
28
|
+
@message = Game.snake.body.join(',').to_s if Game.snake
|
29
|
+
when '2'
|
30
|
+
Game.win
|
31
|
+
break
|
32
|
+
else
|
33
|
+
@message = Game.snake.body.join(',').to_s if Game.snake
|
34
|
+
@snake = server_message.split(',').map(&:to_i).each_slice(2).to_a if server_message
|
35
|
+
end
|
45
36
|
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
37
|
end
|
57
38
|
end
|
58
|
-
|
59
|
-
def self.server
|
60
|
-
@server
|
61
|
-
end
|
62
|
-
|
63
39
|
end
|
64
40
|
end
|
data/lib/ruby_snake/game.rb
CHANGED
@@ -3,56 +3,99 @@ module RubySnake
|
|
3
3
|
class << self
|
4
4
|
include Config
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
# common
|
7
|
+
|
8
|
+
def start(role=nil)
|
9
|
+
self.role = role unless role.nil?
|
10
|
+
@time_flag = Time.now.to_f
|
11
|
+
if role == 'server'
|
12
|
+
start_server_thread
|
13
|
+
elsif role == 'client'
|
14
|
+
start_client_thread
|
11
15
|
end
|
12
|
-
end
|
13
16
|
|
14
|
-
|
15
|
-
@operation
|
17
|
+
UI.draw
|
16
18
|
end
|
17
|
-
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
|
20
|
+
def choise_role
|
21
|
+
UI.draw_role_menu
|
22
|
+
loop do
|
23
|
+
case window.getch
|
24
|
+
when CREATE_HOST
|
25
|
+
Ncurses.endwin
|
26
|
+
start 'server'
|
27
|
+
break
|
28
|
+
when CONNECT_TO_HOST
|
29
|
+
Ncurses.endwin
|
30
|
+
start 'client'
|
31
|
+
break
|
32
|
+
when QUIT
|
33
|
+
break
|
34
|
+
end
|
35
|
+
end
|
23
36
|
end
|
24
37
|
|
25
|
-
def
|
26
|
-
|
38
|
+
def choise_mode
|
39
|
+
loop do
|
40
|
+
case window.getch
|
41
|
+
when SINGLE_PLAYER
|
42
|
+
start
|
43
|
+
break
|
44
|
+
when TWO_PLAYERS
|
45
|
+
choise_role
|
46
|
+
break
|
47
|
+
when QUIT
|
48
|
+
break
|
49
|
+
end
|
50
|
+
end
|
27
51
|
end
|
28
52
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
53
|
+
def welcome
|
54
|
+
begin
|
55
|
+
UI.init
|
56
|
+
UI.draw_welcome
|
57
|
+
choise_mode
|
58
|
+
ensure
|
59
|
+
Ncurses.endwin
|
60
|
+
end
|
32
61
|
end
|
33
62
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
63
|
+
def window
|
64
|
+
if vs?
|
65
|
+
UI::Two.window
|
66
|
+
else
|
67
|
+
UI::One.window
|
68
|
+
end
|
37
69
|
end
|
38
70
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
Ncurses.nodelay window, true
|
71
|
+
def snake
|
72
|
+
if vs?
|
73
|
+
UI::Two.snake
|
74
|
+
else
|
75
|
+
UI::One.snake
|
76
|
+
end
|
46
77
|
end
|
47
78
|
|
48
|
-
def
|
49
|
-
|
50
|
-
end
|
79
|
+
def listen_operation
|
80
|
+
operation = window.getch
|
51
81
|
|
52
|
-
|
53
|
-
|
82
|
+
if OPERATIONS.include?(operation) && !direction_opposite?(operation)
|
83
|
+
case operation
|
84
|
+
when PAUSE
|
85
|
+
pause_or_continue unless Game.vs?
|
86
|
+
when QUIT
|
87
|
+
stop unless Game.vs?
|
88
|
+
else
|
89
|
+
@operation = operation unless Game.pause?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
@operation
|
54
94
|
end
|
55
95
|
|
96
|
+
|
97
|
+
#one player
|
98
|
+
|
56
99
|
def time
|
57
100
|
if pause?
|
58
101
|
@used_time
|
@@ -62,7 +105,7 @@ module RubySnake
|
|
62
105
|
end
|
63
106
|
|
64
107
|
def over?
|
65
|
-
UI.draw_over
|
108
|
+
UI::One.draw_over
|
66
109
|
loop do
|
67
110
|
case window.getch
|
68
111
|
when YES
|
@@ -93,86 +136,70 @@ module RubySnake
|
|
93
136
|
end
|
94
137
|
end
|
95
138
|
|
96
|
-
def
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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
|
139
|
+
def pause_or_continue
|
140
|
+
if pause?
|
141
|
+
continue
|
142
|
+
else
|
143
|
+
pause
|
108
144
|
end
|
145
|
+
end
|
109
146
|
|
147
|
+
def operation
|
110
148
|
@operation
|
111
149
|
end
|
112
150
|
|
113
|
-
def
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
151
|
+
def direction_opposite? o
|
152
|
+
return true if @operation == UP && o == DOWN
|
153
|
+
return true if @operation == DOWN && o == UP
|
154
|
+
return true if @operation == LEFT && o == RIGHT
|
155
|
+
return true if @operation == RIGHT && o == LEFT
|
130
156
|
end
|
131
157
|
|
132
|
-
def
|
133
|
-
|
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
|
158
|
+
def pause?
|
159
|
+
@pause_flag
|
146
160
|
end
|
147
161
|
|
148
|
-
def
|
149
|
-
|
150
|
-
|
162
|
+
def pause
|
163
|
+
@used_time = time
|
164
|
+
@pause_flag = true
|
151
165
|
end
|
152
166
|
|
153
|
-
def
|
154
|
-
|
167
|
+
def continue
|
168
|
+
@time_flag = Time.now.to_f
|
169
|
+
@pause_flag = false
|
170
|
+
end
|
171
|
+
|
172
|
+
def restart
|
173
|
+
Ncurses.nodelay window, true
|
174
|
+
UI::One.window.clear
|
175
|
+
@operation = RIGHT
|
176
|
+
@used_time = 0.0
|
177
|
+
@time_flag = Time.now.to_f
|
178
|
+
snake.init
|
155
179
|
end
|
156
180
|
|
181
|
+
# two players
|
182
|
+
|
157
183
|
def win
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
184
|
+
@win = true
|
185
|
+
end
|
186
|
+
|
187
|
+
def win?
|
188
|
+
@win
|
162
189
|
end
|
163
190
|
|
164
191
|
def lose
|
165
|
-
|
192
|
+
Ncurses.nodelay window, false
|
193
|
+
role_class.message = '2'
|
194
|
+
UI::Two.draw_lose
|
166
195
|
sleep 1
|
167
196
|
window.getch
|
168
|
-
Ncurses.endwin
|
169
197
|
end
|
170
198
|
|
171
|
-
def
|
199
|
+
def connected_host
|
172
200
|
system 'clear'
|
173
201
|
print "Input host to connect: "
|
174
|
-
|
175
|
-
Client.connect host
|
202
|
+
gets.chomp
|
176
203
|
end
|
177
204
|
|
178
205
|
def stop
|
@@ -187,14 +214,49 @@ module RubySnake
|
|
187
214
|
@role = role
|
188
215
|
end
|
189
216
|
|
217
|
+
def role_class
|
218
|
+
if role == 'server'
|
219
|
+
Server
|
220
|
+
else
|
221
|
+
Client
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
190
225
|
def vs?
|
191
|
-
self.role
|
226
|
+
!!self.role
|
192
227
|
end
|
193
228
|
|
194
|
-
def
|
195
|
-
|
196
|
-
|
197
|
-
|
229
|
+
def countdown
|
230
|
+
3.times do |i|
|
231
|
+
puts 3 - i
|
232
|
+
sleep 1
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def start_server_thread
|
237
|
+
system 'clear'
|
238
|
+
puts '=' * 40
|
239
|
+
puts 'Waiting for a connection...'
|
240
|
+
puts '=' * 40
|
241
|
+
Thread.new { Server.start }
|
242
|
+
loop do
|
243
|
+
sleep 0.2
|
244
|
+
if Server.message != '0'
|
245
|
+
countdown
|
246
|
+
break
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def start_client_thread
|
252
|
+
host = connected_host
|
253
|
+
Thread.new { Client.connect host }
|
254
|
+
sleep 0.35
|
255
|
+
raise 'Connect failed' if Client.message == '10'
|
256
|
+
puts '=' * 40
|
257
|
+
puts "Connect to #{host}..."
|
258
|
+
puts '=' * 40
|
259
|
+
countdown
|
198
260
|
end
|
199
261
|
end
|
200
262
|
end
|
data/lib/ruby_snake/server.rb
CHANGED
@@ -1,67 +1,35 @@
|
|
1
|
-
require 'socket'
|
2
|
-
|
3
1
|
module RubySnake
|
4
2
|
class Server
|
5
3
|
|
6
4
|
# The following code is a shit
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
countdown
|
33
|
-
|
34
|
-
@thread = Thread.new do
|
35
|
-
Game.start 'server'
|
36
|
-
@message = '2'
|
37
|
-
Game.lose
|
38
|
-
@stop = true
|
5
|
+
class << self
|
6
|
+
attr_accessor :message, :snake
|
7
|
+
|
8
|
+
def start
|
9
|
+
@message = '0'
|
10
|
+
|
11
|
+
server = TCPServer.new 2000
|
12
|
+
loop do
|
13
|
+
client = server.accept
|
14
|
+
if client
|
15
|
+
client_message = client.recv(4096)
|
16
|
+
client.send @message, 0
|
17
|
+
|
18
|
+
case client_message
|
19
|
+
when '0'
|
20
|
+
@message = '1'
|
21
|
+
when '1'
|
22
|
+
@message = Game.snake.body.join(',').to_s if Game.snake
|
23
|
+
when '2'
|
24
|
+
Game.win
|
25
|
+
break
|
26
|
+
else
|
27
|
+
@message = Game.snake.body.join(',').to_s if Game.snake
|
28
|
+
@snake = client_message.split(',').map(&:to_i).each_slice(2).to_a if client_message
|
39
29
|
end
|
40
|
-
|
41
|
-
elsif client_message == '1'
|
42
|
-
next
|
43
|
-
else
|
44
|
-
@thread.kill
|
45
|
-
Game.win
|
46
|
-
break
|
47
30
|
end
|
48
31
|
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
32
|
end
|
60
33
|
end
|
61
|
-
|
62
|
-
def self.client
|
63
|
-
@client
|
64
|
-
end
|
65
|
-
|
66
34
|
end
|
67
35
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RubySnake
|
2
|
+
class UI
|
3
|
+
class Base
|
4
|
+
class << self
|
5
|
+
def draw_dialog x, y, text
|
6
|
+
UI.draw_dialog x, y, text
|
7
|
+
end
|
8
|
+
|
9
|
+
def display stuff, symbol
|
10
|
+
x = stuff.last + 1
|
11
|
+
y = stuff.first + 1
|
12
|
+
window.mvprintw x, y, symbol
|
13
|
+
end
|
14
|
+
|
15
|
+
def clear_tail
|
16
|
+
display snake.tail, ' '
|
17
|
+
end
|
18
|
+
|
19
|
+
def draw_food
|
20
|
+
if Game.pause?
|
21
|
+
window.color_set 3, nil
|
22
|
+
else
|
23
|
+
window.color_set 1, nil
|
24
|
+
end
|
25
|
+
display snake.food, '$'
|
26
|
+
end
|
27
|
+
|
28
|
+
def draw_snake
|
29
|
+
snake.body.each do |body|
|
30
|
+
if body == snake.head
|
31
|
+
display body, '@'
|
32
|
+
else
|
33
|
+
display body, 'o'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module RubySnake
|
2
|
+
class UI
|
3
|
+
class One < Base
|
4
|
+
class << self
|
5
|
+
def window
|
6
|
+
UI.window
|
7
|
+
end
|
8
|
+
|
9
|
+
def snake
|
10
|
+
@snake ||= Snake.new window.getmaxx, window.getmaxy
|
11
|
+
end
|
12
|
+
|
13
|
+
def draw_snake
|
14
|
+
if Game.pause?
|
15
|
+
window.color_set 3, nil
|
16
|
+
else
|
17
|
+
window.color_set 2, nil
|
18
|
+
end
|
19
|
+
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def draw_title
|
24
|
+
if Game.pause?
|
25
|
+
window.color_set 3, nil
|
26
|
+
elsif snake.near_border?
|
27
|
+
window.color_set 1, nil
|
28
|
+
else
|
29
|
+
window.color_set 4, nil
|
30
|
+
end
|
31
|
+
y = snake.width / 2 - 15
|
32
|
+
|
33
|
+
window.mvprintw 0, y,
|
34
|
+
" Score: #{Game.score} Level: #{Game.level} Time: #{Game.time}s "
|
35
|
+
end
|
36
|
+
|
37
|
+
def draw_boder
|
38
|
+
if Game.pause?
|
39
|
+
window.color_set 3, nil
|
40
|
+
elsif snake.near_border?
|
41
|
+
window.color_set 1, nil
|
42
|
+
else
|
43
|
+
window.color_set 4, nil
|
44
|
+
end
|
45
|
+
window.border *([0] * 8)
|
46
|
+
end
|
47
|
+
|
48
|
+
def draw_quit
|
49
|
+
x = window.getmaxx / 2
|
50
|
+
y = window.getmaxy / 2 - 10
|
51
|
+
draw_dialog y, x, "Oops, I am died, restart? (y/n)"
|
52
|
+
end
|
53
|
+
|
54
|
+
def draw_over
|
55
|
+
window.clear
|
56
|
+
Ncurses.nodelay window, false
|
57
|
+
x = window.getmaxx / 2
|
58
|
+
y = window.getmaxy / 2 - 10
|
59
|
+
draw_dialog y, x, "Oops, I am died, restart? (y/n)"
|
60
|
+
end
|
61
|
+
|
62
|
+
def draw_map
|
63
|
+
draw_boder
|
64
|
+
draw_title
|
65
|
+
draw_snake
|
66
|
+
window.refresh
|
67
|
+
draw_food
|
68
|
+
clear_tail
|
69
|
+
sleep Game.speed
|
70
|
+
window.refresh
|
71
|
+
end
|
72
|
+
|
73
|
+
def draw
|
74
|
+
window.clear
|
75
|
+
Ncurses.nodelay window, true
|
76
|
+
begin
|
77
|
+
loop do
|
78
|
+
draw_map
|
79
|
+
operation = Game.listen_operation
|
80
|
+
break if operation == Config::QUIT
|
81
|
+
if !Game.pause? && !snake.move(operation)
|
82
|
+
if Game.over?
|
83
|
+
break
|
84
|
+
else
|
85
|
+
Game.restart
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
ensure
|
90
|
+
Ncurses.endwin
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module RubySnake
|
2
|
+
class UI
|
3
|
+
class Two < Base
|
4
|
+
class << self
|
5
|
+
def init_windows
|
6
|
+
local_window.border *([0]*8)
|
7
|
+
remote_window.border *([0]*8)
|
8
|
+
local_window.noutrefresh
|
9
|
+
remote_window.noutrefresh
|
10
|
+
end
|
11
|
+
|
12
|
+
def local_window
|
13
|
+
x = (Ncurses.stdscr.getmaxy - 30) / 2
|
14
|
+
y = (Ncurses.stdscr.getmaxx - 100) / 2
|
15
|
+
|
16
|
+
@local_window ||= Ncurses::WINDOW.new 30, 50, x, y
|
17
|
+
end
|
18
|
+
|
19
|
+
def remote_window
|
20
|
+
x = (Ncurses.stdscr.getmaxy - 30) / 2
|
21
|
+
y = Ncurses.stdscr.getmaxx / 2
|
22
|
+
@remote_window ||= Ncurses::WINDOW.new 30,
|
23
|
+
50,
|
24
|
+
x,
|
25
|
+
y
|
26
|
+
end
|
27
|
+
|
28
|
+
def snake
|
29
|
+
@snake ||= Snake.new local_window.getmaxx, local_window.getmaxy
|
30
|
+
end
|
31
|
+
|
32
|
+
def window
|
33
|
+
@local_window
|
34
|
+
end
|
35
|
+
|
36
|
+
def clear_windows
|
37
|
+
local_window.clear
|
38
|
+
local_window.noutrefresh
|
39
|
+
remote_window.clear
|
40
|
+
remote_window.noutrefresh
|
41
|
+
end
|
42
|
+
|
43
|
+
def draw_lose
|
44
|
+
clear_windows
|
45
|
+
@local_window = UI.window
|
46
|
+
window.color_set 1, nil
|
47
|
+
Ncurses.nodelay window, false
|
48
|
+
x = window.getmaxx / 2
|
49
|
+
y = window.getmaxy / 2 - 10
|
50
|
+
draw_dialog y, x, "Sorry, you lose the game."
|
51
|
+
window.refresh
|
52
|
+
end
|
53
|
+
|
54
|
+
def draw_win
|
55
|
+
clear_windows
|
56
|
+
@local_window = UI.window
|
57
|
+
window.color_set 4, nil
|
58
|
+
x = window.getmaxx / 2
|
59
|
+
y = window.getmaxy / 2 - 10
|
60
|
+
draw_dialog y, x, "Congratulations, you win the game."
|
61
|
+
window.refresh
|
62
|
+
end
|
63
|
+
|
64
|
+
def draw_snake
|
65
|
+
window.color_set 2, nil
|
66
|
+
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
70
|
+
def draw_local
|
71
|
+
draw_snake
|
72
|
+
draw_food
|
73
|
+
window.noutrefresh
|
74
|
+
Ncurses.doupdate
|
75
|
+
clear_tail
|
76
|
+
end
|
77
|
+
|
78
|
+
def remote_display stuff, symbol
|
79
|
+
x = stuff.last + 1
|
80
|
+
y = stuff.first + 1
|
81
|
+
remote_window.mvprintw x, y, symbol
|
82
|
+
end
|
83
|
+
|
84
|
+
def draw_remote_snake
|
85
|
+
remote_window.color_set 2, nil
|
86
|
+
remote_snake_body.each do |body|
|
87
|
+
if body == remote_snake_head
|
88
|
+
remote_display body, '@'
|
89
|
+
else
|
90
|
+
remote_display body, 'o'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def remote_snake_body
|
96
|
+
Game.role_class.snake
|
97
|
+
end
|
98
|
+
|
99
|
+
def remote_snake_head
|
100
|
+
Game.role_class.snake.first
|
101
|
+
end
|
102
|
+
|
103
|
+
def remote_snake_tail
|
104
|
+
Game.role_class.snake.last
|
105
|
+
end
|
106
|
+
|
107
|
+
def clear_remote_tail
|
108
|
+
remote_display remote_snake_tail, ' '
|
109
|
+
end
|
110
|
+
|
111
|
+
def draw_remote_food
|
112
|
+
remote_window.color_set 1, nil
|
113
|
+
remote_display snake.food, '$'
|
114
|
+
end
|
115
|
+
|
116
|
+
def draw_remote
|
117
|
+
draw_remote_snake
|
118
|
+
draw_remote_food
|
119
|
+
remote_window.noutrefresh
|
120
|
+
Ncurses.doupdate
|
121
|
+
clear_remote_tail
|
122
|
+
end
|
123
|
+
|
124
|
+
def draw_map
|
125
|
+
draw_local
|
126
|
+
draw_remote
|
127
|
+
sleep Game.speed
|
128
|
+
window.noutrefresh
|
129
|
+
remote_window.noutrefresh
|
130
|
+
Ncurses.doupdate
|
131
|
+
end
|
132
|
+
|
133
|
+
def draw
|
134
|
+
init_windows
|
135
|
+
Ncurses.nodelay window, true
|
136
|
+
begin
|
137
|
+
loop do
|
138
|
+
draw_map
|
139
|
+
operation = Game.listen_operation
|
140
|
+
if Game.win?
|
141
|
+
draw_win
|
142
|
+
sleep 1
|
143
|
+
window.getch
|
144
|
+
break
|
145
|
+
end
|
146
|
+
if !snake.move(operation)
|
147
|
+
Game.lose
|
148
|
+
break
|
149
|
+
end
|
150
|
+
end
|
151
|
+
ensure
|
152
|
+
Ncurses.endwin
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/lib/ruby_snake/ui.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require 'ncurses'
|
2
|
-
|
3
1
|
module RubySnake
|
4
2
|
class UI
|
5
|
-
|
6
|
-
|
3
|
+
autoload :Base, 'ruby_snake/ui/base'
|
4
|
+
autoload :One, 'ruby_snake/ui/one'
|
5
|
+
autoload :Two, 'ruby_snake/ui/two'
|
7
6
|
|
7
|
+
class << self
|
8
8
|
def init
|
9
9
|
Ncurses.initscr
|
10
10
|
Ncurses.cbreak
|
@@ -21,8 +21,6 @@ module RubySnake
|
|
21
21
|
Ncurses.init_pair(4, Ncurses::COLOR_GREEN, Ncurses::COLOR_BLACK);
|
22
22
|
|
23
23
|
init_window
|
24
|
-
|
25
|
-
@snake = Snake.new window.getmaxx, window.getmaxy
|
26
24
|
end
|
27
25
|
|
28
26
|
def init_window
|
@@ -31,199 +29,63 @@ module RubySnake
|
|
31
29
|
|
32
30
|
@window = Ncurses::WINDOW.new 30, 101, x, y
|
33
31
|
unless @window
|
34
|
-
|
35
|
-
|
36
|
-
Ncurses.nodelay @window, true
|
37
|
-
@window.clear
|
38
|
-
end
|
39
|
-
|
40
|
-
def window
|
41
|
-
@window
|
42
|
-
end
|
43
|
-
|
44
|
-
def snake
|
45
|
-
@snake
|
46
|
-
end
|
47
|
-
|
48
|
-
def display stuff, symbol
|
49
|
-
x = stuff.last + 1
|
50
|
-
y = stuff.first + 1
|
51
|
-
window.mvprintw x, y, symbol
|
52
|
-
end
|
53
|
-
|
54
|
-
def clear_tail
|
55
|
-
display snake.tail, ' '
|
56
|
-
end
|
57
|
-
|
58
|
-
def draw_food
|
59
|
-
if Game.pause?
|
60
|
-
window.color_set 3, nil
|
61
|
-
else
|
62
|
-
window.color_set 1, nil
|
32
|
+
Ncurses.endwin
|
33
|
+
raise 'Terminal screen size is not big enough'
|
63
34
|
end
|
64
|
-
display snake.food, '$'
|
65
|
-
window.refresh
|
66
35
|
end
|
67
36
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
snake.body.each do |body|
|
75
|
-
if body == snake.head
|
76
|
-
display body, '@'
|
77
|
-
else
|
78
|
-
display body, 'o'
|
79
|
-
end
|
80
|
-
end
|
37
|
+
def draw_welcome
|
38
|
+
Ncurses.nodelay window, false
|
39
|
+
x = window.getmaxx / 2
|
40
|
+
y = window.getmaxy / 2 - 10
|
41
|
+
draw_dialog y, x, 'Single Player? (s) or Two Players? (t)'
|
81
42
|
end
|
82
43
|
|
83
|
-
def
|
84
|
-
|
85
|
-
window.color_set 3, nil
|
86
|
-
elsif snake.near_border?
|
87
|
-
window.color_set 1, nil
|
88
|
-
else
|
89
|
-
window.color_set 4, nil
|
90
|
-
end
|
91
|
-
y = snake.width / 2 - 15
|
92
|
-
|
93
|
-
window.mvprintw 0, y,
|
94
|
-
" Score: #{Game.score} Level: #{Game.level} Time: #{Game.time}s "
|
44
|
+
def window
|
45
|
+
@window
|
95
46
|
end
|
96
47
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
window.color_set 1, nil
|
103
|
-
else
|
104
|
-
window.color_set 4, nil
|
105
|
-
end
|
106
|
-
window.border *([0] * 8)
|
48
|
+
def draw_role_menu
|
49
|
+
Ncurses.nodelay window, false
|
50
|
+
x = window.getmaxx / 2
|
51
|
+
y = window.getmaxy / 2 - 10
|
52
|
+
draw_dialog y, x, 'Create Host? (s) or Connect to a Host? (c)'
|
107
53
|
end
|
108
54
|
|
109
55
|
def draw_dialog y, x, text
|
110
|
-
|
111
56
|
text =
|
112
57
|
|
113
|
-
|
114
|
-
|
58
|
+
"
|
59
|
+
< #{text} >
|
115
60
|
" <<
|
116
61
|
|
117
62
|
'
|
118
63
|
|
119
64
|
|
120
65
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
66
|
+
.-.
|
67
|
+
/ aa
|
68
|
+
\ -,_)
|
69
|
+
_..._| \ `-<
|
70
|
+
{} .\" .__.\' |
|
71
|
+
{} ( /`\
|
72
|
+
{}(`\'------\' /
|
73
|
+
|\/;._______.\'\
|
74
|
+
; \ /
|
75
|
+
\'-\'-.......-\'
|
131
76
|
'
|
132
77
|
|
133
78
|
window.mvaddstr y, x, text
|
134
79
|
window.refresh
|
135
80
|
end
|
136
81
|
|
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)"
|
142
|
-
end
|
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
|
-
|
171
|
-
def draw_map
|
172
|
-
draw_boder
|
173
|
-
draw_title
|
174
|
-
draw_snake
|
175
|
-
draw_food
|
176
|
-
clear_tail
|
177
|
-
sleep Game.speed
|
178
|
-
window.refresh
|
179
|
-
end
|
180
|
-
|
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
|
204
|
-
end
|
205
|
-
|
206
82
|
def draw
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
draw_map
|
212
|
-
operation = Game.listen_operation
|
213
|
-
break if operation == QUIT
|
214
|
-
if !Game.pause? && !snake.move(operation)
|
215
|
-
if Game.vs? || Game.over?
|
216
|
-
break
|
217
|
-
else
|
218
|
-
Game.restart
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
ensure
|
223
|
-
Ncurses.endwin
|
83
|
+
if Game.vs?
|
84
|
+
Two.draw
|
85
|
+
else
|
86
|
+
One.draw
|
224
87
|
end
|
225
88
|
end
|
226
89
|
end
|
227
|
-
|
228
90
|
end
|
229
91
|
end
|
data/lib/ruby_snake/version.rb
CHANGED
data/lib/ruby_snake.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
$:.unshift File.expand_path('../', __FILE__)
|
2
2
|
|
3
3
|
require "ruby_snake/version"
|
4
|
+
require 'ncurses'
|
5
|
+
require 'socket'
|
4
6
|
|
5
7
|
module RubySnake
|
6
8
|
autoload :UI, 'ruby_snake/ui'
|
@@ -10,7 +12,7 @@ module RubySnake
|
|
10
12
|
autoload :Server, 'ruby_snake/server'
|
11
13
|
autoload :Client, 'ruby_snake/client'
|
12
14
|
|
13
|
-
def self.start
|
15
|
+
def self.start
|
14
16
|
Game.welcome
|
15
17
|
end
|
16
18
|
|
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.
|
4
|
+
version: 0.0.3
|
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-
|
12
|
+
date: 2012-12-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ncurses-ruby
|
@@ -48,6 +48,9 @@ files:
|
|
48
48
|
- lib/ruby_snake/server.rb
|
49
49
|
- lib/ruby_snake/snake.rb
|
50
50
|
- lib/ruby_snake/ui.rb
|
51
|
+
- lib/ruby_snake/ui/base.rb
|
52
|
+
- lib/ruby_snake/ui/one.rb
|
53
|
+
- lib/ruby_snake/ui/two.rb
|
51
54
|
- lib/ruby_snake/version.rb
|
52
55
|
- ruby_snake.gemspec
|
53
56
|
homepage: https://github.com/zhouguangming/ruby_snake
|