map: implement seeded generation; allow passing custom seed #17
3 changed files with 70 additions and 5 deletions
various: persist seed display; fix seed 0 handling
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I349ed28a792d4de685f8468eddd33a136a6a6964
commit
4475e6c276
56
src/main.c
56
src/main.c
|
|
@ -10,6 +10,7 @@
|
|||
#include "render.h"
|
||||
#include "rng.h"
|
||||
#include "settings.h"
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -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 <number>]\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
|
||||
|
|
|
|||
15
src/render.c
15
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue