pentix 1.0.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.
- data/README.md +29 -0
- data/bin/pentix +3 -0
- data/lib/block.rb +20 -0
- data/lib/controls.rb +24 -0
- data/lib/figure.rb +155 -0
- data/lib/finish.rb +85 -0
- data/lib/game.rb +104 -0
- data/lib/glass.rb +158 -0
- data/lib/records.rb +40 -0
- data/lib/status.rb +110 -0
- data/media/block.png +0 -0
- data/pentix.rb +22 -0
- data/spec/lib/block_spec.rb +32 -0
- data/spec/lib/controls_spec.rb +13 -0
- data/spec/lib/figure_spec.rb +318 -0
- data/spec/lib/game_spec.rb +4 -0
- data/spec/lib/glass_spec.rb +377 -0
- data/spec/lib/status_spec.rb +194 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +103 -0
- metadata +78 -0
@@ -0,0 +1,377 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe Glass do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@window = DummyWindow.new
|
7
|
+
@window.glass = @glass = Glass.new(@window, 1, 2)
|
8
|
+
@window.status = @status = Status.new(@window, 20, 2)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "initialization" do
|
12
|
+
it "should use correct blocks color" do
|
13
|
+
@glass.instance_variable_get('@block').color.should == Glass::COLOR
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should assign the initial position" do
|
17
|
+
@glass.pos_x.should == 1
|
18
|
+
@glass.pos_y.should == 2
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should render the glass walls correctly" do
|
22
|
+
@glass.should render_blocks(%Q{
|
23
|
+
|x. . . . . . . . . . . . .x|
|
24
|
+
|x. . . . . . . . . . . . .x|
|
25
|
+
|x. . . . . . . . . . . . .x|
|
26
|
+
|x. . . . . . . . . . . . .x|
|
27
|
+
|x. . . . . . . . . . . . .x|
|
28
|
+
|x. . . . . . . . . . . . .x|
|
29
|
+
|x. . . . . . . . . . . . .x|
|
30
|
+
|x. . . . . . . . . . . . .x|
|
31
|
+
|x. . . . . . . . . . . . .x|
|
32
|
+
|x. . . . . . . . . . . . .x|
|
33
|
+
|x. . . . . . . . . . . . .x|
|
34
|
+
|x. . . . . . . . . . . . .x|
|
35
|
+
|x. . . . . . . . . . . . .x|
|
36
|
+
|x. . . . . . . . . . . . .x|
|
37
|
+
|x. . . . . . . . . . . . .x|
|
38
|
+
|x. . . . . . . . . . . . .x|
|
39
|
+
|x. . . . . . . . . . . . .x|
|
40
|
+
|x. . . . . . . . . . . . .x|
|
41
|
+
|x. . . . . . . . . . . . .x|
|
42
|
+
|x. . . . . . . . . . . . .x|
|
43
|
+
|x. . . . . . . . . . . . .x|
|
44
|
+
|x. . . . . . . . . . . . .x|
|
45
|
+
|x. . . . . . . . . . . . .x|
|
46
|
+
|x. . . . . . . . . . . . .x|
|
47
|
+
|x.x.x.x.x.x.x.x.x.x.x.x.x.x|
|
48
|
+
})
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have an empty matrix" do
|
52
|
+
@glass.should have_matrix(%Q{
|
53
|
+
| . . . . . . . . . . . |
|
54
|
+
| . . . . . . . . . . . |
|
55
|
+
| . . . . . . . . . . . |
|
56
|
+
| . . . . . . . . . . . |
|
57
|
+
| . . . . . . . . . . . |
|
58
|
+
| . . . . . . . . . . . |
|
59
|
+
| . . . . . . . . . . . |
|
60
|
+
| . . . . . . . . . . . |
|
61
|
+
| . . . . . . . . . . . |
|
62
|
+
| . . . . . . . . . . . |
|
63
|
+
| . . . . . . . . . . . |
|
64
|
+
| . . . . . . . . . . . |
|
65
|
+
| . . . . . . . . . . . |
|
66
|
+
| . . . . . . . . . . . |
|
67
|
+
| . . . . . . . . . . . |
|
68
|
+
| . . . . . . . . . . . |
|
69
|
+
| . . . . . . . . . . . |
|
70
|
+
| . . . . . . . . . . . |
|
71
|
+
| . . . . . . . . . . . |
|
72
|
+
| . . . . . . . . . . . |
|
73
|
+
| . . . . . . . . . . . |
|
74
|
+
| . . . . . . . . . . . |
|
75
|
+
| . . . . . . . . . . . |
|
76
|
+
| . . . . . . . . . . . |
|
77
|
+
})
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#spaces_below" do
|
82
|
+
before do
|
83
|
+
@glass = Glass.new(@window, 1, 2)
|
84
|
+
@figure = Figure.new(@window, :l_crutch)
|
85
|
+
@figure.pos_x = 8
|
86
|
+
@figure.pos_y = 2
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should calculate the distance correctly when the figure is vertical" do
|
90
|
+
@figure.rotate_left if @figure.size_x > @figure.size_y
|
91
|
+
@glass.spaces_below(@figure).should == Glass::HEIGHT - @figure.size_y
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should calculate the distance correctly when the figure is vertical" do
|
95
|
+
@figure.rotate_left if @figure.size_y > @figure.size_y
|
96
|
+
@glass.spaces_below(@figure).should == Glass::HEIGHT - @figure.size_y
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should calculate the distance correctly when a figure is hanging in the middle" do
|
100
|
+
@offset = Glass::HEIGHT / 2
|
101
|
+
@figure.pos_y = @glass.pos_y + @offset
|
102
|
+
|
103
|
+
@glass.spaces_below(@figure).should == Glass::HEIGHT - @figure.size_y - @offset
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "with some blocks in the glass" do
|
107
|
+
before do
|
108
|
+
@stack_height = 3
|
109
|
+
|
110
|
+
@stack_height.times do |y|
|
111
|
+
3.times do |x|
|
112
|
+
@glass.matrix[Glass::HEIGHT - 1 - y][x] = Color::WHITE
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should subtract the blocks height when the figure is above them" do
|
118
|
+
@figure.pos_x = @glass.pos_x + 1
|
119
|
+
@glass.spaces_below(@figure).should == Glass::HEIGHT - @figure.size_y - @stack_height
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should not calculate the blocks height when the figure is not above them" do
|
123
|
+
@figure.pos_x = @glass.pos_x + 6
|
124
|
+
@glass.spaces_below(@figure).should == Glass::HEIGHT - @figure.size_y
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should calculate the distance correctly when the figure is in the middle" do
|
128
|
+
@figure.pos_x = @glass.pos_x + 1
|
129
|
+
@figure.pos_y = 10
|
130
|
+
|
131
|
+
@glass.spaces_below(@figure).should == Glass::HEIGHT -
|
132
|
+
@figure.size_y - @stack_height - @figure.pos_y + @glass.pos_y
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#glue_in" do
|
138
|
+
before do
|
139
|
+
@figure = Figure.new(@window, :stairs)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should glue the figure in when it's on top" do
|
143
|
+
@figure.move_to(@glass.pos_x + 3, @glass.pos_y)
|
144
|
+
@glass.glue_in(@figure)
|
145
|
+
@glass.should have_matrix(%Q{
|
146
|
+
| . . . . . . . . . . . |
|
147
|
+
| . . . . . . . . . . . |
|
148
|
+
| . . . . . . . . . . . |
|
149
|
+
| . . . . . . . . . . . |
|
150
|
+
| . . . . . . . . . . . |
|
151
|
+
| . . . . . . . . . . . |
|
152
|
+
| . . . . . . . . . . . |
|
153
|
+
| . . . . . . . . . . . |
|
154
|
+
| . . . . . . . . . . . |
|
155
|
+
| . . . . . . . . . . . |
|
156
|
+
| . . . . . . . . . . . |
|
157
|
+
| . . . . . . . . . . . |
|
158
|
+
| . . . . . . . . . . . |
|
159
|
+
| . . . . . . . . . . . |
|
160
|
+
| . . . . . . . . . . . |
|
161
|
+
| . . . . . . . . . . . |
|
162
|
+
| . . . . . . . . . . . |
|
163
|
+
| . . . . . . . . . . . |
|
164
|
+
| . . . . . . . . . . . |
|
165
|
+
| . . . . . . . . . . . |
|
166
|
+
| . . . . . . . . . . . |
|
167
|
+
| . .x. . . . . . . . . |
|
168
|
+
| . .x.x. . . . . . . . |
|
169
|
+
| . . .x.x. . . . . . . |
|
170
|
+
})
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should call the status for scores" do
|
174
|
+
@figure.move_to(@glass.pos_x + 3, @glass.pos_y)
|
175
|
+
|
176
|
+
@status.should_receive(:count_drop).with(@figure)
|
177
|
+
@status.should_receive(:count_kill).with([])
|
178
|
+
|
179
|
+
@glass.glue_in(@figure)
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "with some blocks already in the glass" do
|
183
|
+
before do
|
184
|
+
figure = Figure.new(@window, :l_crutch)
|
185
|
+
figure.move_to(@glass.pos_x + 2, @glass.pos_y)
|
186
|
+
@glass.glue_in(figure)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should glue figures next to each other" do
|
190
|
+
@figure.move_to(@glass.pos_x + 7, @glass.pos_y + 6)
|
191
|
+
@glass.glue_in(@figure)
|
192
|
+
|
193
|
+
@glass.should have_matrix(%Q{
|
194
|
+
| . . . . . . . . . . . |
|
195
|
+
| . . . . . . . . . . . |
|
196
|
+
| . . . . . . . . . . . |
|
197
|
+
| . . . . . . . . . . . |
|
198
|
+
| . . . . . . . . . . . |
|
199
|
+
| . . . . . . . . . . . |
|
200
|
+
| . . . . . . . . . . . |
|
201
|
+
| . . . . . . . . . . . |
|
202
|
+
| . . . . . . . . . . . |
|
203
|
+
| . . . . . . . . . . . |
|
204
|
+
| . . . . . . . . . . . |
|
205
|
+
| . . . . . . . . . . . |
|
206
|
+
| . . . . . . . . . . . |
|
207
|
+
| . . . . . . . . . . . |
|
208
|
+
| . . . . . . . . . . . |
|
209
|
+
| . . . . . . . . . . . |
|
210
|
+
| . . . . . . . . . . . |
|
211
|
+
| . . . . . . . . . . . |
|
212
|
+
| . . . . . . . . . . . |
|
213
|
+
| . . . . . . . . . . . |
|
214
|
+
| .x. . . . . . . . . . |
|
215
|
+
| .x.x. . . .x. . . . . |
|
216
|
+
| .x. . . . .x.x. . . . |
|
217
|
+
| .x. . . . . .x.x. . . |
|
218
|
+
})
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should glue figures on top of each other" do
|
222
|
+
@figure.move_to(@glass.pos_x + 3, @glass.pos_y)
|
223
|
+
@glass.glue_in(@figure)
|
224
|
+
|
225
|
+
@figure.move_to(@glass.pos_x + 2, @glass.pos_y)
|
226
|
+
@glass.glue_in(@figure)
|
227
|
+
|
228
|
+
@glass.should have_matrix(%Q{
|
229
|
+
| . . . . . . . . . . . |
|
230
|
+
| . . . . . . . . . . . |
|
231
|
+
| . . . . . . . . . . . |
|
232
|
+
| . . . . . . . . . . . |
|
233
|
+
| . . . . . . . . . . . |
|
234
|
+
| . . . . . . . . . . . |
|
235
|
+
| . . . . . . . . . . . |
|
236
|
+
| . . . . . . . . . . . |
|
237
|
+
| . . . . . . . . . . . |
|
238
|
+
| . . . . . . . . . . . |
|
239
|
+
| . . . . . . . . . . . |
|
240
|
+
| . . . . . . . . . . . |
|
241
|
+
| . . . . . . . . . . . |
|
242
|
+
| . . . . . . . . . . . |
|
243
|
+
| . . . . . . . . . . . |
|
244
|
+
| . . . . . . . . . . . |
|
245
|
+
| .x. . . . . . . . . . |
|
246
|
+
| .x.x. . . . . . . . . |
|
247
|
+
| . .x.x. . . . . . . . |
|
248
|
+
| . .x. . . . . . . . . |
|
249
|
+
| .x.x.x. . . . . . . . |
|
250
|
+
| .x.x.x.x. . . . . . . |
|
251
|
+
| .x. . . . . . . . . . |
|
252
|
+
| .x. . . . . . . . . . |
|
253
|
+
})
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "#has_space_for?" do
|
259
|
+
before do
|
260
|
+
@figure = Figure.new(@window, :cross)
|
261
|
+
end
|
262
|
+
|
263
|
+
describe "in an empty glass" do
|
264
|
+
it "should say 'yes' when the figure is in the middle" do
|
265
|
+
@glass.should have_space_for(
|
266
|
+
@figure.matrix, @glass.pos_x + 4, @glass.pos_y + 4
|
267
|
+
)
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should say 'nope' when the figure is out of the left border" do
|
271
|
+
@glass.should_not have_space_for(
|
272
|
+
@figure.matrix, @glass.pos_x, @glass.pos_y
|
273
|
+
)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "should say 'nope' if a figure is out of the right border" do
|
277
|
+
@glass.should_not have_space_for(
|
278
|
+
@figure.matrix, @glass.pos_x + Glass::WIDTH + 2 - @figure.size_x, @glass.pos_y
|
279
|
+
)
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should say 'nope' if a figure is below the bottom line" do
|
283
|
+
@glass.should_not have_space_for(
|
284
|
+
@figure.matrix, @glass.pos_x + 4, @glass.pos_y + Glass::HEIGHT - @figure.size_y + 1
|
285
|
+
)
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should say 'yup' for a figure next to the left border" do
|
289
|
+
@glass.should have_space_for(
|
290
|
+
@figure.matrix, @glass.pos_x + 1, @glass.pos_y
|
291
|
+
)
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should say 'yup' for a figure next to the right border" do
|
295
|
+
@glass.should have_space_for(
|
296
|
+
@figure.matrix, @glass.pos_x + Glass::WIDTH + 1 - @figure.size_x, @glass.pos_y
|
297
|
+
)
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should say 'yup' for a figure next to the bottom border" do
|
301
|
+
@glass.should have_space_for(
|
302
|
+
@figure.matrix, @glass.pos_x + 4, @glass.pos_y + Glass::HEIGHT - @figure.size_y
|
303
|
+
)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
describe "with some blocks in the glass" do
|
308
|
+
before do
|
309
|
+
10.times do |i|
|
310
|
+
@glass.matrix[i][i] = Color::GRAY
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should say 'yup' for figures that are away from the blocks" do
|
315
|
+
@glass.should have_space_for(
|
316
|
+
@figure.matrix, @glass.pos_x + 8, @glass.pos_y
|
317
|
+
)
|
318
|
+
end
|
319
|
+
|
320
|
+
it "should say 'yup' for figures that fit the landscape" do
|
321
|
+
@glass.should have_space_for(
|
322
|
+
@figure.matrix, @glass.pos_x + 3, @glass.pos_y
|
323
|
+
)
|
324
|
+
end
|
325
|
+
|
326
|
+
it "should say 'nope' for figures that intersect with the landscape" do
|
327
|
+
@glass.should_not have_space_for(
|
328
|
+
@figure.matrix, @glass.pos_x + 1, @glass.pos_y
|
329
|
+
)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
describe "#remove_full_lines" do
|
335
|
+
|
336
|
+
before do
|
337
|
+
10.times do |y|
|
338
|
+
@glass.matrix[y].each_with_index do |cell, x|
|
339
|
+
@glass.matrix[Glass::HEIGHT - y - 1][x] =
|
340
|
+
y % 2 == 0 || x % 2 == 0 ? 0xFFFFFFFF : nil
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
@glass.remove_full_lines
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should have matrix like that" do
|
348
|
+
@glass.should have_matrix(%Q{
|
349
|
+
| . . . . . . . . . . . |
|
350
|
+
| . . . . . . . . . . . |
|
351
|
+
| . . . . . . . . . . . |
|
352
|
+
| . . . . . . . . . . . |
|
353
|
+
| . . . . . . . . . . . |
|
354
|
+
| . . . . . . . . . . . |
|
355
|
+
| . . . . . . . . . . . |
|
356
|
+
| . . . . . . . . . . . |
|
357
|
+
| . . . . . . . . . . . |
|
358
|
+
| . . . . . . . . . . . |
|
359
|
+
| . . . . . . . . . . . |
|
360
|
+
| . . . . . . . . . . . |
|
361
|
+
| . . . . . . . . . . . |
|
362
|
+
| . . . . . . . . . . . |
|
363
|
+
| . . . . . . . . . . . |
|
364
|
+
| . . . . . . . . . . . |
|
365
|
+
| . . . . . . . . . . . |
|
366
|
+
| . . . . . . . . . . . |
|
367
|
+
| . . . . . . . . . . . |
|
368
|
+
|x. .x. .x. .x. .x. .x. |
|
369
|
+
|x. .x. .x. .x. .x. .x. |
|
370
|
+
|x. .x. .x. .x. .x. .x. |
|
371
|
+
|x. .x. .x. .x. .x. .x. |
|
372
|
+
|x. .x. .x. .x. .x. .x. |
|
373
|
+
})
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe Status do
|
4
|
+
before :all do
|
5
|
+
@window = DummyWindow.new
|
6
|
+
@window.glass = Glass.new(@window, 1, 1)
|
7
|
+
|
8
|
+
@head_font_args = [@window, Status::HEAD_FONT[0], Status::HEAD_FONT[1]]
|
9
|
+
@text_font_args = [@window, Status::TEXT_FONT[0], Status::TEXT_FONT[1]]
|
10
|
+
|
11
|
+
@head_font = Font.new(*@head_font_args)
|
12
|
+
@text_font = Font.new(*@text_font_args)
|
13
|
+
|
14
|
+
@status = Status.new(@window, 10, 20)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "initialization" do
|
18
|
+
it "should instantiate correct fonts" do
|
19
|
+
Font.should_receive(:new).with(*@head_font_args).and_return(@head_font)
|
20
|
+
Font.should_receive(:new).with(*@text_font_args).and_return(@text_font)
|
21
|
+
|
22
|
+
@status = Status.new(@window, 10, 20)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set correct positions" do
|
26
|
+
@status.pos_x.should == 10
|
27
|
+
@status.pos_y.should == 20
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should set first level" do
|
31
|
+
@status.level.should == 1
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should set zero lines" do
|
35
|
+
@status.lines.should == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should set zero figures" do
|
39
|
+
@status.figures.should == 0
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should set zero score" do
|
43
|
+
@status.score.should == 0
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#reset!' do
|
48
|
+
before :all do
|
49
|
+
@status.level = 8
|
50
|
+
@status.score = 9999
|
51
|
+
@status.lines = 234
|
52
|
+
@status.figures = 1234
|
53
|
+
|
54
|
+
@status.reset!
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should set the first level" do
|
58
|
+
@status.level.should == 1
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should set zero lines" do
|
62
|
+
@status.lines.should == 0
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should set zero figures" do
|
66
|
+
@status.figures.should == 0
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should set zero score" do
|
70
|
+
@status.score.should == 0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#draw" do
|
75
|
+
it "should draw the things" do
|
76
|
+
Font.should_receive(:new).with(*@head_font_args).and_return(@head_font)
|
77
|
+
Font.should_receive(:new).with(*@text_font_args).and_return(@text_font)
|
78
|
+
|
79
|
+
@figure = Figure.new(@window)
|
80
|
+
@status = Status.new(@window, 10, 20)
|
81
|
+
@status.figure = @figure
|
82
|
+
|
83
|
+
@figure.should_receive(:pos_x=).with(10)
|
84
|
+
@figure.should_receive(:pos_y=).with(22)
|
85
|
+
@figure.should_receive(:draw)
|
86
|
+
|
87
|
+
@head_font.should_receive(:draw).with("Next:", 200, 395, 0, 1.0, 1.0, Status::HEAD_FONT[2])
|
88
|
+
@head_font.should_receive(:draw).with("Score:", 200, 575, 0, 1.0, 1.0, Status::HEAD_FONT[2])
|
89
|
+
@head_font.should_receive(:draw).with("Winnars:", 200, 755, 0, 1.0, 1.0, Status::HEAD_FONT[2])
|
90
|
+
|
91
|
+
@status.draw
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "scoring" do
|
96
|
+
before do
|
97
|
+
@figure = Figure.new(@window)
|
98
|
+
|
99
|
+
@status.score = 0
|
100
|
+
@status.level = 1
|
101
|
+
@status.lines = 0
|
102
|
+
@status.figures = 0
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should calculate correctly a figure drop score" do
|
106
|
+
@figure.distance = 8
|
107
|
+
|
108
|
+
@status.count_drop @figure
|
109
|
+
|
110
|
+
@status.score.should == 8
|
111
|
+
@status.figures.should == 1
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should multiply the drop score by the current level" do
|
115
|
+
@figure.distance = 9
|
116
|
+
@status.level = 3
|
117
|
+
|
118
|
+
@status.count_drop @figure
|
119
|
+
|
120
|
+
@status.score.should == 27
|
121
|
+
@status.figures.should == 1
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should score lines kill according to the scoring system" do
|
125
|
+
Status::SCORING_SYSTEM.each do |lines_num, score|
|
126
|
+
@status.score = 0
|
127
|
+
@status.lines = 0
|
128
|
+
|
129
|
+
@status.count_kill Array.new(lines_num)
|
130
|
+
|
131
|
+
@status.score.should == score
|
132
|
+
@status.lines.should == lines_num
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should multiply the lines kill score by the current level" do
|
137
|
+
Status::SCORING_SYSTEM.each do |lines_num, score|
|
138
|
+
@status.score = 0
|
139
|
+
@status.lines = 0
|
140
|
+
@status.level = 4
|
141
|
+
|
142
|
+
@status.count_kill Array.new(lines_num)
|
143
|
+
|
144
|
+
@status.score.should == score * 4
|
145
|
+
@status.lines.should == lines_num
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "levelups" do
|
151
|
+
before do
|
152
|
+
@status.reset!
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should not levelup until the user scores a minimum amount of lines" do
|
156
|
+
(Status::LEVELUP - 1).times do
|
157
|
+
@status.count_kill [1]
|
158
|
+
end
|
159
|
+
|
160
|
+
@status.level.should == 1
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should levelup right after the user scores the needed amount of lines" do
|
164
|
+
Status::LEVELUP.times do
|
165
|
+
@status.count_kill [1]
|
166
|
+
end
|
167
|
+
|
168
|
+
@status.level.should == 2
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should keep excessive lines count after each levelup" do
|
172
|
+
(Status::LEVELUP - 1).times do
|
173
|
+
@status.count_kill [1]
|
174
|
+
end
|
175
|
+
|
176
|
+
@status.level.should == 1
|
177
|
+
|
178
|
+
@status.count_kill [1,2,3]
|
179
|
+
|
180
|
+
@status.level.should == 2
|
181
|
+
|
182
|
+
(Status::LEVELUP - 3).times do
|
183
|
+
@status.count_kill [1]
|
184
|
+
end
|
185
|
+
|
186
|
+
@status.level.should == 2
|
187
|
+
|
188
|
+
@status.count_kill [1]
|
189
|
+
|
190
|
+
@status.level.should == 3
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'pentix.rb')
|
3
|
+
|
4
|
+
# a dummy window class to test the modules separately from the main game
|
5
|
+
class DummyWindow < Gosu::Window
|
6
|
+
attr_accessor :glass, :status
|
7
|
+
|
8
|
+
# converting `.new` into a singleton to avoid memory leaks in Gosu
|
9
|
+
def self.new
|
10
|
+
@@win ||= super
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super(100, 100, false)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Some pretty formatted matrixes handling helpers
|
21
|
+
#
|
22
|
+
module MatrixHelper
|
23
|
+
def str_to_matrix(str)
|
24
|
+
str.scan(/\s*\|(.+?)\|/).map do |line|
|
25
|
+
line[0].split('.').map{ |c| c != ' ' }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def matrix_to_str(matrix)
|
30
|
+
matrix.map do |row|
|
31
|
+
"|#{row.map{ |c| c ? 'x' : ' '}.join('.')}|"
|
32
|
+
end.join("\n ")
|
33
|
+
end
|
34
|
+
|
35
|
+
def draw_matrix(figure)
|
36
|
+
block = actual.instance_variable_get('@block')
|
37
|
+
matrix = figure.instance_variable_get('@matrix')
|
38
|
+
result = []
|
39
|
+
max_x = 0
|
40
|
+
|
41
|
+
block.class.instance_eval do
|
42
|
+
define_method :draw do |x, y|
|
43
|
+
x = x - figure.pos_x
|
44
|
+
y = y - figure.pos_y
|
45
|
+
|
46
|
+
result[y] ||= []
|
47
|
+
result[y][x] = true
|
48
|
+
max_x = x if max_x < x
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
figure.draw
|
53
|
+
|
54
|
+
# making the size of the rows even
|
55
|
+
result.map do |row|
|
56
|
+
(row || []).tap do |row|
|
57
|
+
(0..max_x).each do |x|
|
58
|
+
row[x] = false unless row[x]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# making a set of boolean values out of the matrix
|
65
|
+
def boolify(matrix)
|
66
|
+
matrix.map do |row|
|
67
|
+
row.map{ |cell| !!cell}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Figures rendering matcher
|
74
|
+
#
|
75
|
+
RSpec::Matchers.define :render_blocks do |expected|
|
76
|
+
extend MatrixHelper
|
77
|
+
|
78
|
+
match do |actual|
|
79
|
+
boolify(draw_matrix(actual)) == boolify(str_to_matrix(expected))
|
80
|
+
end
|
81
|
+
|
82
|
+
failure_message_for_should do |actual|
|
83
|
+
"expected: #{matrix_to_str(str_to_matrix(expected))}\n\n" \
|
84
|
+
" got: #{matrix_to_str(draw_matrix(actual))}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
#
|
90
|
+
# a readable matrix matcher
|
91
|
+
#
|
92
|
+
RSpec::Matchers.define :have_matrix do |expected|
|
93
|
+
extend MatrixHelper
|
94
|
+
|
95
|
+
match do |actual|
|
96
|
+
boolify(actual.matrix) == boolify(str_to_matrix(expected))
|
97
|
+
end
|
98
|
+
|
99
|
+
failure_message_for_should do |actual|
|
100
|
+
"expected: #{matrix_to_str(str_to_matrix(expected))}\n\n" \
|
101
|
+
" got: #{matrix_to_str(actual.matrix)}"
|
102
|
+
end
|
103
|
+
end
|