@@ -8,6 +8,12 @@ enum GamePhase {
8
8
GameOver ,
9
9
}
10
10
11
+ enum Bound {
12
+ Floor ( i32 ) ,
13
+ LeftWall ( i32 ) ,
14
+ RightWall ( i32 ) ,
15
+ }
16
+
11
17
pub struct GameState < TBlockTypeRand , TBlockPosRand >
12
18
where
13
19
TBlockTypeRand : RangeRng < usize > ,
82
88
}
83
89
}
84
90
91
+ pub fn move_block_horizontal ( & mut self , horizontal_motion : i32 ) {
92
+ match self . game_phase {
93
+ GamePhase :: MoveBlock => {
94
+ let moving_block_id = self . block_count - 1 ; // we are always moving the last block
95
+ if self . can_block_move ( moving_block_id, horizontal_motion) {
96
+ self . block_positions [ moving_block_id] . 1 += horizontal_motion;
97
+ }
98
+ } ,
99
+ GamePhase :: GenerateBlock | GamePhase :: GameOver => ( ) ,
100
+ }
101
+ }
102
+
85
103
pub fn block_count ( & self ) -> usize {
86
104
self . block_count
87
105
}
@@ -97,15 +115,36 @@ where
97
115
pub fn has_block_landed ( & self , block_id : usize ) -> bool {
98
116
assert_eq ! ( self . blocks. len( ) , self . block_positions. len( ) ) ;
99
117
100
- is_resting_on_floor (
118
+ is_touching_bound (
101
119
self . blocks [ block_id] ,
102
120
self . block_positions [ block_id] ,
103
- self . board_height ,
104
- ) || is_resting_on_other_block (
121
+ Bound :: Floor ( self . board_height ) ,
122
+ ) || is_touching_block (
105
123
block_id,
106
124
self . block_count ,
107
125
& self . blocks ,
108
126
& self . block_positions ,
127
+ ( 1 , 0 ) ,
128
+ )
129
+ }
130
+
131
+ pub fn can_block_move ( & self , block_id : usize , horizontal_motion : i32 ) -> bool {
132
+ assert_eq ! ( self . blocks. len( ) , self . block_positions. len( ) ) ;
133
+
134
+ if horizontal_motion == 0 {
135
+ return false ;
136
+ }
137
+
138
+ !is_touching_bound (
139
+ self . blocks [ block_id] ,
140
+ self . block_positions [ block_id] ,
141
+ if horizontal_motion < 0 { Bound :: LeftWall ( 0 ) } else { Bound :: RightWall ( self . board_width ) } ,
142
+ ) && !is_touching_block (
143
+ block_id,
144
+ self . block_count ,
145
+ & self . blocks ,
146
+ & self . block_positions ,
147
+ ( 0 , horizontal_motion) ,
109
148
)
110
149
}
111
150
@@ -124,22 +163,29 @@ fn translate_cells(cells: &[Cell; 4], row_translation: i32, col_translation: i32
124
163
translated_cells
125
164
}
126
165
127
- fn is_resting_on_floor ( block : BlockType , block_pos : Cell , floor_pos : i32 ) -> bool {
128
- block_pos. 0 + block. height ( ) >= floor_pos
166
+ fn is_touching_bound ( block : BlockType , block_pos : Cell , bound : Bound ) -> bool {
167
+ match bound {
168
+ Bound :: Floor ( floor) => block_pos. 0 + block. height ( ) >= floor,
169
+ Bound :: LeftWall ( left) => block_pos. 1 <= left,
170
+ Bound :: RightWall ( right) => block_pos. 1 + block. width ( ) >= right,
171
+ }
129
172
}
130
173
131
- fn is_resting_on_other_block (
174
+ fn is_touching_block (
132
175
block_id : usize ,
133
176
block_count : usize ,
134
177
blocks : & [ BlockType ] ,
135
178
block_positions : & [ Cell ] ,
179
+ touch_vector : ( i32 , i32 )
136
180
) -> bool {
137
181
assert_eq ! ( blocks. len( ) , block_positions. len( ) ) ;
138
182
assert ! ( blocks. len( ) >= block_count) ;
139
183
140
- let block = blocks[ block_id] ;
141
- let block_pos = block_positions[ block_id] ;
142
- let block_cells = translate_cells ( & block. cells ( ) , block_pos. 0 , block_pos. 1 ) ;
184
+ let block_cells = translate_cells (
185
+ & blocks[ block_id] . cells ( ) ,
186
+ block_positions[ block_id] . 0 + touch_vector. 0 ,
187
+ block_positions[ block_id] . 1 + touch_vector. 1 ,
188
+ ) ;
143
189
144
190
// Only need to check for collisions against blocks that were created before this block id
145
191
// since all other blocks will always be higher up in the grid.
@@ -148,14 +194,15 @@ fn is_resting_on_other_block(
148
194
continue ;
149
195
}
150
196
151
- let other_block = blocks[ other_block_id] ;
152
- let other_block_pos = block_positions[ other_block_id] ;
153
- let other_block_cells =
154
- translate_cells ( & other_block. cells ( ) , other_block_pos. 0 , other_block_pos. 1 ) ;
197
+ let other_block_cells = translate_cells (
198
+ & blocks[ other_block_id] . cells ( ) ,
199
+ block_positions[ other_block_id] . 0 ,
200
+ block_positions[ other_block_id] . 1 ,
201
+ ) ;
155
202
156
203
for cell in block_cells. iter ( ) {
157
204
for other_cell in other_block_cells. iter ( ) {
158
- if ( cell. 1 == other_cell. 1 ) && ( cell . 0 + 1 == other_cell . 0 ) {
205
+ if cell == other_cell {
159
206
return true ;
160
207
}
161
208
}
0 commit comments