TK2048/src/game_logic.c
2025-07-16 14:24:57 +02:00

98 lines
2.5 KiB
C

#include "game_logic.h"
#include <string.h>
static uint8_t game_grid_alpha[GRID_SIDE * GRID_SIDE];
static uint8_t game_grid_beta[GRID_SIDE * GRID_SIDE];
static uint8_t *front_grid = game_grid_alpha;
static uint8_t *back_grid = game_grid_beta;
void swap_grids(void);
void swap_grids(void) {
uint8_t *temp = front_grid;
front_grid = back_grid;
back_grid = temp;
}
uint8_t *get_front_grid(void) {
return front_grid;
}
uint8_t *step_game(step_direction dir) {
// TODO: Update the grid state calculating the new state in the back grid
uint8_t start_offset;
int8_t column_step;
int8_t row_step;
/*
* UP: scans TOP to BOTTOM, RIGHT to LEFT
* DOWN: scans BOTTOM to TOP, RIGHT to LEFT
* LEFT: scans LEFT to RIGHT, TOP to BOTTOM
* RIGHT: scans RIGHT to LEFT, TOP to BOTTOM
*/
switch(dir) {
case UP:
start_offset = GRID_SIDE;
column_step = GRID_SIDE;
row_step = -1;
break;
case DOWN:
start_offset = (GRID_SIDE * GRID_SIDE) - 1;
column_step = -GRID_SIDE;
row_step = -1;
break;
case LEFT:
start_offset = 0;
column_step = 1;
row_step = GRID_SIDE;
break;
break;
case RIGHT:
start_offset = GRID_SIDE - 1;
column_step = -1;
row_step = GRID_SIDE;
break;
};
// Clear the back grid
memset(back_grid, 0, GRID_SIDE * GRID_SIDE);
for (int8_t row = 0; row < GRID_SIDE; row++) {
for(int8_t col = 0; col < GRID_SIDE; col++) {
uint8_t current_offset = start_offset + (col * column_step) + (row * row_step);
uint8_t sub_col;
// Search for the first non-zero value in the front grid and copy it in the current place of the back grid (zeroing it in the front)
for(sub_col = col; sub_col < GRID_SIDE; sub_col++) {
uint8_t sub_col_offset = start_offset + (sub_col * column_step) + (row * row_step);
if(front_grid[sub_col_offset]) {
back_grid[current_offset] = front_grid[sub_col_offset];
front_grid[sub_col_offset] = 0;
break;
}
}
// The value is still 0, we found nothing. On to the next row!
if (!back_grid[current_offset]) break;
// Now search if there is an identical value following this one, so we can merge them
for(; sub_col < GRID_SIDE; sub_col++) {
uint8_t sub_col_offset = start_offset + (sub_col * column_step) + (row * row_step);
if(front_grid[sub_col_offset] == back_grid[current_offset]) {
back_grid[current_offset]++; // Merge them (by increasing the value of the current square and removing the merged one)
front_grid[sub_col_offset] = 0;
break;
}
}
}
}
swap_grids();
return front_grid;
}