Skip to content

Commit 811c926

Browse files
committed
Merge branch 'bodacious/generic_falling_blocks_game_solver'
2 parents 67cca5f + b43a6b2 commit 811c926

File tree

6 files changed

+626
-36
lines changed

6 files changed

+626
-36
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
source "https://rubygems.org"
4+
ruby '3.2.2'
5+
6+
gem 'minitest'
7+
gem 'matrix'
8+
gem 'pry'
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
coderay (1.1.3)
5+
matrix (0.4.2)
6+
method_source (1.1.0)
7+
minitest (5.25.2)
8+
pry (0.15.0)
9+
coderay (~> 1.1)
10+
method_source (~> 1.0)
11+
12+
PLATFORMS
13+
arm64-darwin-22
14+
ruby
15+
16+
DEPENDENCIES
17+
matrix
18+
minitest
19+
pry
20+
21+
RUBY VERSION
22+
ruby 3.2.2p53
23+
24+
BUNDLED WITH
25+
2.5.16
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
# Generic falling block game solver!
2+
3+
Create a program that will play the falling-block game for you, so that you can hijack the high score board and impress all of your friends!
4+
5+
## Problem Description
6+
7+
Imagine a hypothetical game where blocks of different shapes fall from the sky.
8+
9+
Your job is to shift the blocks left and right so they fall into an optimal configuration.
10+
11+
If you complete a full row of blocks, those are eliminated and the playing plane is lowered. If you allow the blocks to stack up too high, you lose!
12+
13+
Blocks can be in ane of of the following shapes:
14+
15+
### Square
16+
17+
```
18+
▓▓▓▓
19+
▓▓▓▓
20+
```
21+
22+
### Line
23+
24+
```
25+
▓▓
26+
▓▓
27+
▓▓
28+
▓▓
29+
```
30+
31+
### Z
32+
33+
```
34+
▓▓▓▓
35+
▓▓▓▓
36+
```
37+
38+
### L
39+
40+
```
41+
▓▓
42+
▓▓
43+
▓▓▓▓
44+
```
45+
46+
Blocks may also have one or more orientations. Each orientation represents the shape turned 90 degrees clockwise. So the L block has 4 orientations:
47+
48+
```
49+
# Orientation 1
50+
▓▓
51+
▓▓
52+
▓▓▓▓
53+
54+
# Orientation 2
55+
▓▓▓▓▓▓
56+
▓▓
57+
58+
# Orientation 3
59+
▓▓▓▓
60+
▓▓
61+
▓▓
62+
63+
# Orientation 4
64+
▓▓
65+
▓▓▓▓▓▓
66+
```
67+
68+
Unlike other popular, hypothetical falling block games, in our game players may choose which shape to play on each turn.
69+
70+
## Requirements and Constraints
71+
72+
### Input / Output Specifications
73+
74+
The input to your solution will be a string of text representing a game board. Note that, to improve the appearance of the grid, each cell in the grid is made up of two characters on one row.
75+
76+
This means that the input will contain a string of 6 lines with 20 characters each, to give the appearance of a grid of 6x10 square cells (see tests below for examples).
77+
78+
The output of your solution will be a string of text representing the best shape to play, given the current state of the game board, and the orientation of the block to play.
79+
80+
### Constraints
81+
82+
none
83+
84+
## Examples and Test Cases
85+
86+
Your solution should include the following integration tests, and they should all pass:
87+
88+
```ruby
89+
require 'minitest/autorun'
90+
91+
class GenericFallingBlocksGameTest < Minitest::Test
92+
def test_recommends_any_block_when_plane_is_level
93+
skip 'Not implemented'
94+
95+
game_plane = <<~PLANE
96+
97+
98+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
99+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
100+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
101+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
102+
PLANE
103+
assert_equal 'Any', described_class.new(game_plane).recommended_block
104+
assert_equal :any, described_class.new(game_plane).recommended_orientation
105+
end
106+
107+
def test_correctly_recommends_square_block_any_orientation
108+
skip 'Not implemented'
109+
110+
game_plane = <<~PLANE
111+
112+
113+
▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
114+
▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
115+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
116+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
117+
PLANE
118+
instance = described_class.new(game_plane)
119+
assert_equal 'Square', instance.recommended_block
120+
assert_equal :any, instance.recommended_orientation
121+
end
122+
123+
def test_correctly_recommends_line_block_orientation_1
124+
skip 'Not implemented'
125+
126+
game_plane = <<~PLANE
127+
128+
129+
▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
130+
▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
131+
▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
132+
▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
133+
PLANE
134+
instance = described_class.new(game_plane)
135+
assert_equal 'Line', instance.recommended_block
136+
assert_equal :orientation_1, instance.recommended_orientation
137+
end
138+
139+
def test_correctly_recommends_line_block_orientation_2
140+
skip 'Not implemented'
141+
142+
game_plane = <<~PLANE
143+
144+
145+
▓▓▓▓▓▓▓▓▓▓ ▓▓
146+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
147+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
148+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
149+
PLANE
150+
instance = described_class.new(game_plane)
151+
assert_equal 'Line', instance.recommended_block
152+
assert_equal :orientation_2, instance.recommended_orientation
153+
end
154+
155+
def test_correctly_recommends_z_block_orientation_1
156+
skip 'Not implemented'
157+
158+
game_plane = <<~PLANE
159+
160+
161+
▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓
162+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓
163+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
164+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
165+
PLANE
166+
instance = described_class.new(game_plane)
167+
assert_equal 'Z', instance.recommended_block
168+
assert_equal :orientation_1, instance.recommended_orientation
169+
end
170+
171+
def test_correctly_recommends_z_block_orientation_2
172+
skip 'Not implemented'
173+
174+
game_plane = <<~PLANE
175+
176+
177+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓
178+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓
179+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
180+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
181+
PLANE
182+
instance = described_class.new(game_plane)
183+
assert_equal 'Z', instance.recommended_block
184+
assert_equal :orientation_2, instance.recommended_orientation
185+
end
186+
187+
def test_correctly_recommends_l_orientation_1
188+
skip 'Not implemented'
189+
190+
game_plane = <<~PLANE
191+
192+
193+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓
194+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓
195+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓
196+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
197+
PLANE
198+
instance = described_class.new(game_plane)
199+
assert_equal 'L', instance.recommended_block
200+
assert_equal :orientation_1, instance.recommended_orientation
201+
end
202+
203+
def test_correctly_recommends_l_orientation_2
204+
skip 'Not implemented'
205+
206+
game_plane = <<~PLANE
207+
208+
209+
▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓
210+
▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓
211+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
212+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
213+
PLANE
214+
instance = described_class.new(game_plane)
215+
assert_equal 'L', instance.recommended_block
216+
assert_equal :orientation_2, instance.recommended_orientation
217+
end
218+
219+
def test_correctly_recommends_l_orientation_3
220+
skip 'Not implemented'
221+
222+
game_plane = <<~PLANE
223+
224+
225+
▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓
226+
▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓
227+
▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓
228+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
229+
PLANE
230+
instance = described_class.new(game_plane)
231+
assert_equal 'L', instance.recommended_block
232+
assert_equal :orientation_3, instance.recommended_orientation
233+
end
234+
235+
def test_correctly_recommends_l_orientation_4
236+
skip 'Not implemented'
237+
238+
game_plane = <<~PLANE
239+
240+
241+
▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓
242+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
243+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
244+
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
245+
PLANE
246+
instance = described_class.new(game_plane)
247+
assert_equal 'L', instance.recommended_block
248+
assert_equal :orientation_4, instance.recommended_orientation
249+
end
250+
251+
private
252+
253+
def described_class
254+
# TODO: Define me!
255+
end
256+
end
257+
```
258+
259+
### Sample Inputs and Outputs
260+
261+
See passing tests above for samples.
262+
263+
### Instructions
264+
265+
1. Set up a test file with the above test cases, so that you are able to run all of the tests and see them pass/fail/skip.
266+
2. Write code that will solve the problem and pass the tests.
267+
3. Don't try to pass all of the tests at once, it's better to solve them one at a time (in the order they are listed above).
268+
269+
## Evaluation Criteria:
270+
271+
- All tests pass
272+
273+
### Bonus criteria
274+
275+
- Your solution is able to handle more complicated game boards and still produce reliable results.
276+
277+
### Mega bonus criteria
278+
279+
(Don't worry if you don't get this far...)
280+
281+
- Your solution is able to handle new block shapes and will produce the most optimal solution based on all the available shapes.
282+
283+
---
284+
285+
## How to run your main file
286+
287+
```
288+
bundle exec ruby katas/generic_falling_blocks_game_solver/bodacious/main.rb
289+
```
290+

0 commit comments

Comments
 (0)