From a14bd280ff3d95af372890c22b0121d20106c9f6 Mon Sep 17 00:00:00 2001 From: odweta Date: Sat, 10 Oct 2026 13:58:53 +0200 Subject: [PATCH] add win and lose end conditions --- src/engine/engine.c | 2 ++ src/examples/2048.c | 71 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/engine/engine.c b/src/engine/engine.c index 77aabf6..c6f207a 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -2,6 +2,8 @@ #include "internal/engine_internal.h" +#include + engine_internal_state_t *internal_state = NULL; game_state_t *game_state = NULL; diff --git a/src/examples/2048.c b/src/examples/2048.c index a62758e..a555238 100644 --- a/src/examples/2048.c +++ b/src/examples/2048.c @@ -28,6 +28,14 @@ typedef struct { int col; } line_tile_t; +typedef enum { + GAME_PLAYING, + GAME_WON, + GAME_LOST +} game_status_t; + +static game_status_t game_status; + typedef struct { uint32_t area[SIZE][SIZE]; dir_e direction; @@ -42,6 +50,17 @@ static size_t move_track_count; static double last_frame_time; +static bool +board_is_full(void) +{ + for (int r = 0; r < SIZE; ++r) + for (int c = 0; c < SIZE; ++c) + if (game.area[r][c] == 0) + return false; + + return true; +} + /* Pixel size is calculated from the current window size while drawing. */ static uint32_t colors(uint32_t number) @@ -151,6 +170,8 @@ process_line(dir_e direction, int line, uint32_t output[SIZE]) if (i + 1 < input_count && input[i].value == input[i + 1].value) { uint32_t merged_value = input[i].value * 2; + if (merged_value >= 2048) + game_status = GAME_WON; output[output_count] = merged_value; game.score += merged_value; @@ -194,6 +215,9 @@ process_line(dir_e direction, int line, uint32_t output[SIZE]) static bool slide(dir_e direction) { + if (game_status != GAME_PLAYING || anim_is_active(&movement)) + return false; + if (anim_is_active(&movement)) return false; @@ -260,16 +284,20 @@ client_poll_event(void) game_state->is_running = false; break; case SDLK_W: - slide(UP); + if (game_status == GAME_PLAYING) + slide(UP); break; case SDLK_S: - slide(DOWN); + if (game_status == GAME_PLAYING) + slide(DOWN); break; case SDLK_A: - slide(LEFT); + if (game_status == GAME_PLAYING) + slide(LEFT); break; case SDLK_D: - slide(RIGHT); + if (game_status == GAME_PLAYING) + slide(RIGHT); break; default: break; @@ -324,7 +352,12 @@ client_update_framebuffer(void) dt = 0.05f; if (anim_is_active(&movement) && anim_update(&movement, dt)) { - new_2(); + if (game_status == GAME_PLAYING) { + new_2(); + + if (board_is_full()) + game_status = GAME_LOST; + } } uint32_t tile_size = game_state->width / SIZE; @@ -332,7 +365,26 @@ client_update_framebuffer(void) clear_framebuffer(OVERDRAW, 0x000000); - /* Draw all cell backgrounds first. */ + char score_text[32]; + snprintf(score_text, sizeof score_text, "score: %u", game.score); + put_string(OVERDRAW, score_text, + border_width / 2, tile_size * SIZE + border_width / 2, + 6, 1, 12, 0xFFFFFF, 0x000000); + + if (game_status != GAME_PLAYING) { + clear_framebuffer(BASE, 0x000000); + const char *message = + game_status == GAME_WON ? "YOU WIN!" : "YOU LOSE!"; + + put_string(OVERDRAW, message, + 0 + border_width * 2, + game_state->height / 2, + 6, 1, 12, 0xFFFFFF, 0x000000); + + return; + } + + /* Draw all cell backgrounds. */ for (int r = 0; r < SIZE; ++r) { for (int c = 0; c < SIZE; ++c) { uint32_t x = border_width / 2 + (uint32_t)c * tile_size; @@ -360,17 +412,12 @@ client_update_framebuffer(void) } } } - - char score_text[32]; - snprintf(score_text, sizeof score_text, "score: %u", game.score); - put_string(OVERDRAW, score_text, - border_width / 2, tile_size * SIZE + border_width / 2, - 6, 1, 12, 0xFFFFFF, 0x000000); } static void game_init(void) { + game_status = GAME_PLAYING; memset(&game, 0, sizeof game); anim_init(&movement); srand((unsigned)time(NULL)); -- 2.54.0