From a6da01d4acb3fc0cf3d88e0eff2c4823d34d5eda Mon Sep 17 00:00:00 2001 From: odweta Date: Fri, 9 Oct 2026 23:10:26 +0200 Subject: [PATCH] add basic rendering and improve edge cases --- src/examples/2048.c | 211 +++++++++++++++++++++++++------------------- 1 file changed, 121 insertions(+), 90 deletions(-) diff --git a/src/examples/2048.c b/src/examples/2048.c index 75c253e..9915437 100644 --- a/src/examples/2048.c +++ b/src/examples/2048.c @@ -1,3 +1,4 @@ +#include "dangerzone/render/rect.h" #include #include #include @@ -27,39 +28,6 @@ typedef struct { static game_t game; -// polling events every frame -void -client_poll_event() -{ - SDL_Event ev = game_state->event; - - if (ev.type == SDL_EVENT_QUIT) { - game_state->is_running = false; - } - - if (ev.type == SDL_EVENT_KEY_DOWN) { - switch (ev.key.key) { - case SDLK_Q: - game_state->is_running = false; - break; - case SDLK_W: - game.direction = UP; - break; - case SDLK_S: - game.direction = DOWN; - break; - case SDLK_A: - game.direction = LEFT; - break; - case SDLK_D: - game.direction = RIGHT; - break; - default: - break; - } - } -} - void print_area() { @@ -74,17 +42,19 @@ print_area() printf("\n"); } -void +bool move() { + bool retval = false; switch (game.direction) { case LEFT: for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { for (int k = 0; k < SIZE - 1; k++) { - if (game.area[i][k] == 0) { + if (game.area[i][k] == 0 && game.area[i][k + 1] != 0) { game.area[i][k] = game.area[i][k + 1]; game.area[i][k + 1] = 0; + retval = true; } } } @@ -95,9 +65,10 @@ move() uint32_t *row = game.area[i]; for (int j = SIZE - 1; j >= 0; j--) { for (int k = SIZE - 1; k > 0; k--) { - if (game.area[i][k] == 0) { + if (game.area[i][k] == 0 && game.area[i][k - 1] != 0) { game.area[i][k] = game.area[i][k - 1]; game.area[i][k - 1] = 0; + retval = true; } } } @@ -107,9 +78,10 @@ move() for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { for (int k = 0; k < SIZE - 1; k++) { - if (game.area[k][i] == 0) { + if (game.area[k][i] == 0 && game.area[k + 1][i] != 0) { game.area[k][i] = game.area[k + 1][i]; game.area[k + 1][i] = 0; + retval = true; } } } @@ -119,9 +91,10 @@ move() for (int i = 0; i < SIZE; i++) { for (int j = SIZE - 1; j >= 0; j--) { for (int k = SIZE - 1; k > 0; k--) { - if (game.area[k][i] == 0) { + if (game.area[k][i] == 0 && game.area[k][i - 1] != 0) { game.area[k][i] = game.area[k - 1][i]; game.area[k - 1][i] = 0; + retval = true; } } } @@ -130,43 +103,15 @@ move() default: break; } + + return retval; } -/** - * Python alternative (only horizontal) - * -# combines a shifted row as per the rules of 2048 -# returns whether there were modifications done -def combine_row(row: list[int], to_left: bool) -> bool: - # make sure it is shifted - retval = shift_row(row, to_left) - - if to_left: - direction = 1 - start = 0 - end = len(row) - 1 - else: - direction = -1 - start = len(row) - 1 - end = 0 - - for i in range(start, end, direction): - if row[i] == 0: - continue - if row[i] == row[i + direction]: - retval = True - row[i] *= 2 - row[i + direction] = 0 - for j in range(i + direction, end, direction): - row[j] = row[j + direction] - row[end] = 0 - - return retval -*/ - -void -combine_horizontal() -{ +bool +combine_horizontal( + bool has_moved +) { + bool retval = has_moved; int8_t direction; uint32_t start, end; switch (game.direction) { @@ -194,6 +139,7 @@ combine_horizontal() continue; } if (row[i] == row[i - direction]) { + retval = true; row[i] *= 2; row[i - direction] = 0; for (int j = i - direction; (game.direction == LEFT) ? j < end : j > end; j -= direction) { @@ -203,11 +149,15 @@ combine_horizontal() } } } + + return retval; } -void -combine_vertical() -{ +bool +combine_vertical( + bool has_moved +) { + bool retval = has_moved; int8_t direction; uint32_t start, end; switch (game.direction) { @@ -233,6 +183,7 @@ combine_vertical() continue; } if (game.area[i][col_index] == game.area[i - direction][col_index]) { + retval = true; game.area[i][col_index] *= 2; game.area[i - direction][col_index] = 0; for (int j = i - direction; (game.direction == UP) ? j < end : j > end; j -= direction) { @@ -242,41 +193,121 @@ combine_vertical() } } } + + return retval; } -void -combine() -{ +bool +combine( + bool has_moved +) { if (game.direction == LEFT || game.direction == RIGHT) { - combine_horizontal(); + return combine_horizontal(has_moved); } else { - combine_vertical(); + return combine_vertical(has_moved); } } +// finds a random empty position and puts a two there +void +new_2() +{ + uint32_t row = rand() % SIZE; + uint32_t col = rand() % SIZE; + while (game.area[row][col] != 0) { + row = rand() % SIZE; + col = rand() % SIZE; + } + + game.area[row][col] = 2; +} + void slide() { // 1. move all squares in one direction - move(); + bool has_moved = move(); // 2. then combine them and shift the potential rest by one in the given direction - combine(); + bool has_combined = combine(has_moved); + + printf("moved? %s, combined? %s\n", (has_moved) ? "true" : "false", (has_combined) ? "true" : "false"); + + // 3. generate a new 2 + if (has_moved || has_combined) { + new_2(); + } } +// polling events every frame +void +client_poll_event() +{ + SDL_Event ev = game_state->event; + + if (ev.type == SDL_EVENT_QUIT) { + game_state->is_running = false; + } + + if (ev.type == SDL_EVENT_KEY_DOWN) { + switch (ev.key.key) { + case SDLK_Q: + game_state->is_running = false; + break; + case SDLK_W: + game.direction = UP; + slide(); + break; + case SDLK_S: + game.direction = DOWN; + slide(); + break; + case SDLK_A: + game.direction = LEFT; + slide(); + break; + case SDLK_D: + game.direction = RIGHT; + slide(); + break; + default: + break; + } + } +} + +#define CHR(ord) ((ord) + 48) +#define ORD(chr) ((chr) - 48) + // performed every frame void client_update_framebuffer() { - //slide(); + // clear_framebuffer(0xFFFF00); + // put_string("Welcome to the most\n*DANGEROUS* 2048 game!", + // 20, 20, 2, 2, 3, 0x000000, 0xFFFF00 + // ); - // single green demo pixel - game_state->framebuffer[0] = 0x00FF00; + clear_framebuffer(0x000000); + + uint32_t tile_size = game_state->width / SIZE; + uint8_t border_width = 10; + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + // background + uint32_t x = (border_width / 2) + i * tile_size; + uint32_t y = (border_width / 2)+ j * tile_size; + uint32_t w = tile_size - border_width; + uint32_t h = tile_size - border_width; + uint32_t background_color = 0xFFFFFF; + put_rect(x, y, w, h, background_color); - clear_framebuffer(0xFFFF00); - put_string("Welcome to the most\n*DANGEROUS* 2048 game!", - 20, 20, 2, 2, 3, 0x000000, 0xFFFF00 - ); + // number in foreground + uint32_t foreground_color = 0x000000; + uint8_t font_size = 7; + put_char(CHR(game.area[j][i]), x + border_width, y + border_width, font_size, foreground_color, background_color); + } + } } bool