diff --git a/src/main.c b/src/main.c index c7332a8..6bd5351 100644 --- a/src/main.c +++ b/src/main.c @@ -10,6 +10,7 @@ #include "render.h" #include "rng.h" #include "settings.h" +#include #include #include #include @@ -486,6 +487,10 @@ static int handle_input(GameState *gs) { // Generate a new random seed for the new run gs->run_seed = (unsigned int)time(NULL); init_floor(gs, 1); + // Update window title with new seed + char title[128]; + snprintf(title, sizeof(title), "Roguelike - Seed: %u", gs->run_seed); + SetWindowTitle(title); return 0; } @@ -546,6 +551,10 @@ static void game_loop(unsigned int run_seed) { gs.game_won = 0; load_audio_assets(&gs); init_floor(&gs, 1); + // Update window title with new seed + char title[128]; + snprintf(title, sizeof(title), "Roguelike - Seed: %u", gs.run_seed); + SetWindowTitle(title); } } @@ -588,6 +597,9 @@ static void game_loop(unsigned int run_seed) { render_message(gs.last_message); } + // Draw persistent seed display in top right + render_seed_display(gs.run_seed); + // Draw game over screen if (gs.game_over) { // Compute final score @@ -608,18 +620,50 @@ static void game_loop(unsigned int run_seed) { } } +// Check if a string is a valid unsigned integer +static int is_valid_uint(const char *str) { + if (str == NULL || *str == '\0') + return 0; + // Check for optional leading + + if (*str == '+') + str++; + // Must have at least one digit + if (*str == '\0') + return 0; + // All characters must be digits + for (const char *p = str; *p != '\0'; p++) { + if (!isdigit((unsigned char)*p)) + return 0; + } + return 1; +} + int main(int argc, char **argv) { // Parse command-line arguments unsigned int run_seed = 0; + int seed_provided = 0; + for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--seed") == 0 && i + 1 < argc) { - run_seed = (unsigned int)atoi(argv[i + 1]); + if (strcmp(argv[i], "--seed") == 0) { + if (i + 1 >= argc) { + fprintf(stderr, "Error: --seed requires a value\n"); + fprintf(stderr, "Usage: %s [--seed ]\n", argv[0]); + return 1; + } + const char *seed_str = argv[i + 1]; + if (!is_valid_uint(seed_str)) { + fprintf(stderr, "Error: Invalid seed value: %s\n", seed_str); + fprintf(stderr, "Seed must be a non-negative integer\n"); + return 1; + } + run_seed = (unsigned int)strtoul(seed_str, NULL, 10); + seed_provided = 1; i++; // Skip the value } } // If no seed provided, generate random seed from time - if (run_seed == 0) { + if (!seed_provided) { run_seed = (unsigned int)time(NULL); } @@ -629,8 +673,10 @@ int main(int argc, char **argv) { audio_init(); // Initialize random number generator SetRandomSeed(88435); - // Initialize window - InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT + 60, "Roguelike"); + // Initialize window with seed in title + char title[128]; + snprintf(title, sizeof(title), "Roguelike - Seed: %u", run_seed); + InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT + 60, title); SetTargetFPS(60); // Run game diff --git a/src/render.c b/src/render.c index 2badee3..8d7bbaa 100644 --- a/src/render.c +++ b/src/render.c @@ -679,3 +679,18 @@ void render_message(const char *message) { DrawText(message, text_x, text_y, font_size, WHITE); } + +void render_seed_display(unsigned int seed) { + char seed_text[64]; + snprintf(seed_text, sizeof(seed_text), "Seed: %u", seed); + + const int font_size = 14; + int text_width = MeasureText(seed_text, font_size); + + // Position at top right with padding + int x = SCREEN_WIDTH - text_width - 10; + int y = 5; + + // Draw with non-obstructive dim text color + DrawText(seed_text, x, y, font_size, TEXT_DIM); +} diff --git a/src/render.h b/src/render.h index c571f19..aa5c181 100644 --- a/src/render.h +++ b/src/render.h @@ -1,3 +1,4 @@ + #ifndef RENDER_H #define RENDER_H @@ -105,4 +106,7 @@ void render_end_screen(int is_victory, int kills, int items, int damage_dealt, i // Render a message popup void render_message(const char *message); +// Render seed display at top right of screen +void render_seed_display(unsigned int seed); + #endif // RENDER_H