fix: a tetromino can't appear twice in a row, and rotation is no longer preserved

Tetrominos can now appear twice in a row, and rotation is no longer
preserved for each shape.
(if you rotated a specific shape 90°, now whenever you encounter this
shape, it spawns with a 90° rotation, and so forth)
This commit is contained in:
2025-06-27 12:30:11 +02:00
parent 699bc7a547
commit 7b3b09ebe7
4 changed files with 10 additions and 12 deletions

View File

@@ -36,17 +36,13 @@ static void shuffle(void* restrict ptr, size_t nmemb, size_t membs) {
void next_shape(void) { void next_shape(void) {
// as long as we're not at the last shape, we can just increment // as long as we're not at the last shape, we can just increment
dat.pdat.sel = (i8vec2){COLUMNS / 2 - SHAPE_WIDTH / 2, 0}; dat.pdat.sel = (i8vec2){COLUMNS / 2 - SHAPE_WIDTH / 2, 0};
dat.pdat.cur = dat.pdat.nxt[dat.pdat.idx];
dat.pdat.idx++; dat.pdat.idx++;
if (dat.pdat.idx < TETROMINO_COUNT - 1) return; if (dat.pdat.idx < TETROMINO_COUNT) return;
// shuffle all next shapes, preserving the last // shuffle all next shapes, preserving the last
dat.pdat.idx = 0; dat.pdat.idx = 0;
shuffle(dat.pdat.nxt, TETROMINO_COUNT - 1, sizeof(u8)); shuffle(dat.pdat.nxt, TETROMINO_COUNT, sizeof(u8));
// swap the first and last shape, thus preserving what the shape would've been
u8 cache = dat.pdat.nxt[0];
dat.pdat.nxt[0] = dat.pdat.nxt[TETROMINO_COUNT - 1];
dat.pdat.nxt[TETROMINO_COUNT - 1] = cache;
} }
struct gamedata* game_init(void) { struct gamedata* game_init(void) {
@@ -61,6 +57,8 @@ struct gamedata* game_init(void) {
// initialise the placing data correctly // initialise the placing data correctly
dat.pdat.sel = (i8vec2){COLUMNS / 2 - SHAPE_WIDTH / 2, 0}; dat.pdat.sel = (i8vec2){COLUMNS / 2 - SHAPE_WIDTH / 2, 0};
shuffle(dat.pdat.nxt, TETROMINO_COUNT, sizeof(u8)); shuffle(dat.pdat.nxt, TETROMINO_COUNT, sizeof(u8));
dat.pdat.cur = dat.pdat.nxt[dat.pdat.idx];
dat.pdat.idx++;
return &dat; return &dat;
} }

View File

@@ -24,6 +24,7 @@ struct pdat {
u8 nxt[TETROMINO_COUNT]; // shuffled data representing the next shapes u8 nxt[TETROMINO_COUNT]; // shuffled data representing the next shapes
i8vec2 sel; // position of the current shape i8vec2 sel; // position of the current shape
u8 idx; // the index of the current shape u8 idx; // the index of the current shape
u8 cur; // the current id of the shape
}; };
/* contains game data that's commonly shared */ /* contains game data that's commonly shared */

View File

@@ -92,8 +92,7 @@ static int shape_intersects(u8* restrict const* restrict const rows, u8 const id
void place_update(struct gamedata* gdat, int movdat) { void place_update(struct gamedata* gdat, int movdat) {
// store the current index and ID, only changes when placed (which yields no movement) and rotation (which occurs last) // store the current index and ID, only changes when placed (which yields no movement) and rotation (which occurs last)
int tmp; int tmp;
u8 idx = gdat->pdat.idx; u8 id = gdat->pdat.cur;
u8 id = gdat->pdat.nxt[idx];
// update Y axis // update Y axis
tmp = !!(movdat & MOVD); tmp = !!(movdat & MOVD);
@@ -114,5 +113,5 @@ void place_update(struct gamedata* gdat, int movdat) {
// update roll // update roll
tmp = id ^ (((!!(movdat & MOVRR) - !!(movdat & MOVRL)) * 8 + id) & 31); tmp = id ^ (((!!(movdat & MOVRR) - !!(movdat & MOVRL)) * 8 + id) & 31);
gdat->pdat.nxt[idx] ^= (tmp && !shape_intersects(gdat->rows, id ^ tmp, gdat->pdat.sel)) * tmp; gdat->pdat.cur ^= (tmp && !shape_intersects(gdat->rows, id ^ tmp, gdat->pdat.sel)) * tmp;
} }

View File

@@ -114,8 +114,8 @@ void render_update(void) {
if (font) draw_score_text(); if (font) draw_score_text();
render_level(); render_level();
draw_shape(gdat->pdat.nxt[gdat->pdat.idx], gdat->pdat.sel); draw_shape(gdat->pdat.cur, gdat->pdat.sel);
draw_shape(gdat->pdat.nxt[gdat->pdat.idx + 1], (i8vec2){COLUMNS + 1, 3}); draw_shape(gdat->pdat.nxt[gdat->pdat.idx], (i8vec2){COLUMNS + 1, 3});
SDL_RenderPresent(rend); SDL_RenderPresent(rend);
} }