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) {
// 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.cur = dat.pdat.nxt[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
dat.pdat.idx = 0;
shuffle(dat.pdat.nxt, TETROMINO_COUNT - 1, 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;
shuffle(dat.pdat.nxt, TETROMINO_COUNT, sizeof(u8));
}
struct gamedata* game_init(void) {
@@ -61,6 +57,8 @@ struct gamedata* game_init(void) {
// initialise the placing data correctly
dat.pdat.sel = (i8vec2){COLUMNS / 2 - SHAPE_WIDTH / 2, 0};
shuffle(dat.pdat.nxt, TETROMINO_COUNT, sizeof(u8));
dat.pdat.cur = dat.pdat.nxt[dat.pdat.idx];
dat.pdat.idx++;
return &dat;
}

View File

@@ -24,6 +24,7 @@ struct pdat {
u8 nxt[TETROMINO_COUNT]; // shuffled data representing the next shapes
i8vec2 sel; // position 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 */

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) {
// store the current index and ID, only changes when placed (which yields no movement) and rotation (which occurs last)
int tmp;
u8 idx = gdat->pdat.idx;
u8 id = gdat->pdat.nxt[idx];
u8 id = gdat->pdat.cur;
// update Y axis
tmp = !!(movdat & MOVD);
@@ -114,5 +113,5 @@ void place_update(struct gamedata* gdat, int movdat) {
// update roll
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();
render_level();
draw_shape(gdat->pdat.nxt[gdat->pdat.idx], gdat->pdat.sel);
draw_shape(gdat->pdat.nxt[gdat->pdat.idx + 1], (i8vec2){COLUMNS + 1, 3});
draw_shape(gdat->pdat.cur, gdat->pdat.sel);
draw_shape(gdat->pdat.nxt[gdat->pdat.idx], (i8vec2){COLUMNS + 1, 3});
SDL_RenderPresent(rend);
}