@@ -159,18 +159,16 @@ void compute_observations(Breakout* env) {
159159 env -> observations [7 ] = env -> score / 864.0f ;
160160 env -> observations [8 ] = env -> num_balls / 5.0f ;
161161 env -> observations [9 ] = env -> paddle_width / (2.0f * HALF_PADDLE_WIDTH );
162- for (int i = 0 ; i < env -> num_bricks ; i ++ ) {
163- env -> observations [10 + i ] = env -> brick_states [i ];
164- }
162+ memcpy (env -> observations + 10 , env -> brick_states , sizeof (float ) * env -> num_bricks );
165163}
166164
167165// Collision of a stationary vertical line segment (xw,yw) to (xw,yw+hw)
168166// with a moving line segment (x+vx*t,y+vy*t) to (x+vx*t,y+vy*t+h).
169167static inline bool calc_vline_collision (float xw , float yw , float hw , float x ,
170168 float y , float vx , float vy , float h , CollisionInfo * col ) {
171169 float t_new = (xw - x ) / vx ;
172- float topmost = fmin (yw + hw , y + h + vy * t_new );
173- float botmost = fmax (yw , y + vy * t_new );
170+ float topmost = fminf (yw + hw , y + h + vy * t_new );
171+ float botmost = fmaxf (yw , y + vy * t_new );
174172 float overlap_new = topmost - botmost ;
175173
176174 // Collision finds the smallest time of collision with the greatest overlap
@@ -248,26 +246,52 @@ static inline void calc_brick_collision(Breakout* env, int idx,
248246 }
249247}
250248static inline int column_index (Breakout * env , float x ) {
251- return (int )(floorf ( x / env -> brick_width ) );
249+ return (int )(x / env -> brick_width );
252250}
253251static inline int row_index (Breakout * env , float y ) {
254- return (int )(floorf (( y - Y_OFFSET ) / env -> brick_height ) );
252+ return (int )(( y - Y_OFFSET ) / env -> brick_height );
255253}
256254
257255void calc_all_brick_collisions (Breakout * env , CollisionInfo * collision_info ) {
258- int column_from = column_index (env , fminf (env -> ball_x + env -> ball_vx , env -> ball_x ));
259- column_from = fmaxf (column_from , 0 );
260- int column_to = column_index (env , fmaxf (env -> ball_x + env -> ball_width + env -> ball_vx , env -> ball_x + env -> ball_width ));
261- column_to = fminf (column_to , env -> brick_cols - 1 );
262- int row_from = row_index (env , fminf (env -> ball_y + env -> ball_vy , env -> ball_y ));
263- row_from = fmaxf (row_from , 0 );
264- int row_to = row_index (env , fmaxf (env -> ball_y + env -> ball_height + env -> ball_vy , env -> ball_y + env -> ball_height ));
265- row_to = fminf (row_to , env -> brick_rows - 1 );
256+ float ball_x = env -> ball_x ;
257+ float ball_x_dst = ball_x + env -> ball_vx ;
258+ float ball_y = env -> ball_y ;
259+ float ball_y_dst = ball_y + env -> ball_vy ;
260+ float ball_width = env -> ball_width ;
261+ float ball_height = env -> ball_height ;
262+
263+ int row_from = row_index (env , ball_y < ball_y_dst ? ball_y : ball_y_dst );
264+ if (row_from < 0 ) {
265+ row_from = 0 ;
266+ }
267+
268+ if (row_from > env -> brick_rows ) {
269+ return ;
270+ }
271+
272+ int column_from = column_index (env , ball_x < ball_x_dst ? ball_x : ball_x_dst );
273+ if (column_from < 0 ) {
274+ column_from = 0 ;
275+ }
276+
277+ float ball_x_end = ball_x + ball_width ;
278+ float ball_x_dst_end = ball_x_dst + ball_width ;
279+ int column_to = column_index (env , ball_x_dst_end > ball_x_end ? ball_x_dst_end : ball_x_end );
280+ if (column_to >= env -> brick_cols ) {
281+ column_to = env -> brick_cols - 1 ;
282+ }
283+
284+ float ball_y_end = ball_y + ball_height ;
285+ float ball_y_dst_end = ball_y_dst + ball_height ;
286+ int row_to = row_index (env , ball_y_dst_end > ball_y_end ? ball_y_dst_end : ball_y_end );
287+ if (row_to >= env -> brick_rows ) {
288+ row_to = env -> brick_rows - 1 ;
289+ }
266290
267291 for (int row = row_from ; row <= row_to ; row ++ ) {
268292 for (int column = column_from ; column <= column_to ; column ++ ) {
269293 int brick_index = row * env -> brick_cols + column ;
270- if (env -> brick_states [brick_index ] == 0.0 )
294+ if (env -> brick_states [brick_index ] == 0.0f )
271295 calc_brick_collision (env , brick_index , collision_info );
272296 }
273297 }
@@ -297,8 +321,8 @@ bool calc_paddle_ball_collisions(Breakout* env, CollisionInfo* collision_info) {
297321 float relative_intersection = (
298322 (env -> ball_x + env -> ball_width / 2 ) - env -> paddle_x ) / env -> paddle_width ;
299323 float angle = - base_angle + relative_intersection * 2 * base_angle ;
300- env -> ball_vx = sin (angle ) * env -> ball_speed * TICK_RATE ;
301- env -> ball_vy = - cos (angle ) * env -> ball_speed * TICK_RATE ;
324+ env -> ball_vx = sinf (angle ) * env -> ball_speed * TICK_RATE ;
325+ env -> ball_vy = - cosf (angle ) * env -> ball_speed * TICK_RATE ;
302326 env -> hits += 1 ;
303327 if (env -> hits % 4 == 0 && env -> ball_speed < env -> max_ball_speed ) {
304328 env -> ball_speed += 64 ;
@@ -430,8 +454,8 @@ void step_frame(Breakout* env, float action) {
430454 env -> balls_fired = 1 ;
431455 float direction = M_PI / 3.25f ;
432456
433- env -> ball_vy = cos (direction ) * env -> ball_speed * TICK_RATE ;
434- env -> ball_vx = sin (direction ) * env -> ball_speed * TICK_RATE ;
457+ env -> ball_vy = cosf (direction ) * env -> ball_speed * TICK_RATE ;
458+ env -> ball_vx = sinf (direction ) * env -> ball_speed * TICK_RATE ;
435459 if (rand () % 2 == 0 ) {
436460 env -> ball_vx = - env -> ball_vx ;
437461 }
0 commit comments