@@ -184,10 +184,16 @@ piece_t new_piece(shape_t s) {
184184game_t * new_game (game_t * g , char * gname ) {
185185 if (!g ) {
186186 g = calloc (sizeof (game_t ), 1 );
187+ } else {
188+ memset (g , 0 , sizeof (game_t ));
187189 }
190+
188191 if (!gname ) {
189192 gname = "" ;
190193 }
194+ /* fixme add to game struct */
195+ memset (bag , 0 , sizeof bag );
196+ bag_fullness = 7 ;
191197 g -> p = new_piece (0 );
192198 for (int i = 0 ; i < PIECE_PREVIEWS ; i ++ ) {
193199 g -> preview [i ] = rand_shape ();
@@ -196,14 +202,19 @@ game_t *new_game(game_t *g, char *gname) {
196202 return g ;
197203}
198204
199- /* Return true if p overlaps with any placed piece in g
200- * BUG: The piece can be above the board, so the returned value can be an
201- * out-of-bounds read */
202- /* Other than intentional leaks, do not call unless you're sure the piece is on
203- * the board */
205+ /* Return true if p overlaps with any placed piece in g */
204206shape_t check_dead (game_t * g , const piece_t * const p ) {
205207 pos_t cells [4 ];
206208 get_cells (* p , cells );
209+ int min_x = min4 (cells [0 ].x , cells [1 ].x , cells [2 ].x , cells [3 ].x );
210+ int max_x = max4 (cells [0 ].x , cells [1 ].x , cells [2 ].x , cells [3 ].x );
211+ int min_y = min4 (cells [0 ].y , cells [1 ].y , cells [2 ].y , cells [3 ].y );
212+ int max_y = max4 (cells [0 ].y , cells [1 ].y , cells [2 ].y , cells [3 ].y );
213+
214+ if (min_x < 0 || min_y < 0 || max_x >= BOARD_W || max_y >= BOARD_H ) {
215+ return P_WALL ;
216+ }
217+
207218 for (int i = 0 ; i < 4 ; i ++ ) {
208219 shape_t on_board = g -> board [cells [i ].y ][cells [i ].x ];
209220 if (on_board != P_NONE ) {
@@ -344,24 +355,20 @@ shape_t print_game(game_t *g) {
344355 * hop over the cookie and rbp, so i copy the game pointer after the bad array
345356 * instead. */
346357int clear_lines_write_shape (game_t * g ) {
347- volatile struct {
348- score_t scores [5 ];
349- game_t * g2 ;
350- } tsp_bug = {{0 , 100 , 300 , 500 , 800 }, g };
351-
358+ score_t scores [6 ] = {0 , 100 , 300 , 500 , 800 , 1000 };
352359 int should_clear = 0 ;
353360 int rowcnt [BOARD_H ] = {0 }; /* row fullness */
354361
355362 pos_t curr_cells [4 ];
356- get_cells (tsp_bug . g2 -> p , curr_cells );
363+ get_cells (g -> p , curr_cells );
357364
358365 for (int i = 0 ; i < 4 ; i ++ ) {
359366 /* count the current piece */
360367 rowcnt [curr_cells [i ].y ]++ ;
361368 }
362369 for (int y = 0 ; y < BOARD_H ; y ++ ) {
363370 for (int x = 0 ; x < BOARD_W ; x ++ ) {
364- if (tsp_bug . g2 -> board [y ][x ] != P_NONE ) {
371+ if (g -> board [y ][x ] != P_NONE ) {
365372 rowcnt [y ]++ ;
366373 }
367374 }
@@ -374,8 +381,7 @@ int clear_lines_write_shape(game_t *g) {
374381 if (!should_clear ) {
375382 /* writing the shape to the board */
376383 for (int i = 0 ; i < 4 ; i ++ ) {
377- tsp_bug .g2 -> board [curr_cells [i ].y ][curr_cells [i ].x ] =
378- tsp_bug .g2 -> p .s ;
384+ g -> board [curr_cells [i ].y ][curr_cells [i ].x ] = g -> p .s ;
379385 }
380386 return 0 ;
381387 }
@@ -384,51 +390,45 @@ int clear_lines_write_shape(game_t *g) {
384390 * triple gives score_i = 5 */
385391 int score_i = 0 ;
386392
387- if (tsp_bug . g2 -> p .s == P_T ) {
393+ if (g -> p .s == P_T ) {
388394 /* puts("is T"); */
389- piece_t new_p = tsp_bug . g2 -> p ;
390- new_p .pos .y = tsp_bug . g2 -> p .pos .y - 1 ;
395+ piece_t new_p = g -> p ;
396+ new_p .pos .y = g -> p .pos .y - 1 ;
391397
392398 pos_t cells [4 ];
393399 get_cells (new_p , cells );
394400 int min_y = min4 (cells [0 ].y , cells [1 ].y , cells [2 ].y , cells [3 ].y );
395401 if (min_y >= 0 && check_dead (g , & new_p )) {
396- /* BUG: If we find a t-spin (last piece was a t piece AND it cannot
397- * be moved up one spot AND we clear at least one line) we try to
398- * boost the score by setting score_i. Since the line clear counting
399- * happens after regardless, we get max points for a t-spin single,
400- * and two possible leaks for 2 and 3 cleared lines respectively.
401- */
402- score_i = 3 ;
402+ score_i = 2 ;
403403 }
404404 }
405405
406406 /* writing the shape to the board */
407407 for (int i = 0 ; i < 4 ; i ++ ) {
408- tsp_bug . g2 -> board [curr_cells [i ].y ][curr_cells [i ].x ] = tsp_bug . g2 -> p .s ;
408+ g -> board [curr_cells [i ].y ][curr_cells [i ].x ] = g -> p .s ;
409409 }
410410
411411 int src_y = BOARD_H - 1 ;
412412 /* I suppose an overflow when shifting things down could also be good */
413413 for (int dst_y = BOARD_H - 1 ; dst_y >= 0 ; dst_y -- , src_y -- ) {
414414 if (src_y < 0 ) { /* nothing to shift; copy a blank line */
415415 for (int x = 0 ; x < BOARD_W ; x ++ ) {
416- tsp_bug . g2 -> board [dst_y ][x ] = P_NONE ;
416+ g -> board [dst_y ][x ] = P_NONE ;
417417 }
418418 } else {
419419 while (rowcnt [src_y ] == BOARD_W && src_y >= 0 ) { /* clear */
420420 src_y -- ;
421421 score_i ++ ;
422422 }
423423 for (int x = 0 ; x < BOARD_W ; x ++ ) {
424- tsp_bug . g2 -> board [dst_y ][x ] = tsp_bug . g2 -> board [src_y ][x ];
424+ g -> board [dst_y ][x ] = g -> board [src_y ][x ];
425425 }
426426 }
427427 }
428428
429429 /* printf("score_i: %d\n", score_i); */
430430 fflush (stdout );
431- return tsp_bug . scores [score_i ];
431+ return scores [score_i ];
432432}
433433
434434/* Shift the queue forward, filling in the new spot, and throwing away curr.
0 commit comments