forked from NotAShelf/rogged
map: implement seeded generation; allow passing custom seed
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I742b7e59c7ca872539d4ebfe3a03b44f6a6a6964
This commit is contained in:
parent
09f7e659b5
commit
f51b754e76
3 changed files with 32 additions and 8 deletions
|
|
@ -173,6 +173,8 @@ typedef struct {
|
||||||
int potions_used;
|
int potions_used;
|
||||||
int floors_reached;
|
int floors_reached;
|
||||||
int final_score;
|
int final_score;
|
||||||
|
// Seed for this run
|
||||||
|
unsigned int run_seed;
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
35
src/main.c
35
src/main.c
|
|
@ -12,7 +12,9 @@
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
// Add message to action log
|
// Add message to action log
|
||||||
static void add_log(GameState *gs, const char *msg) {
|
static void add_log(GameState *gs, const char *msg) {
|
||||||
|
|
@ -102,11 +104,14 @@ static void update_effects(GameState *gs) {
|
||||||
|
|
||||||
// Initialize a new floor
|
// Initialize a new floor
|
||||||
static void init_floor(GameState *gs, int floor_num) {
|
static void init_floor(GameState *gs, int floor_num) {
|
||||||
|
// Seed RNG with run seed combined with floor number for deterministic generation
|
||||||
|
rng_seed(gs->run_seed + floor_num * 54321);
|
||||||
|
|
||||||
// Generate dungeon
|
// Generate dungeon
|
||||||
dungeon_generate(&gs->dungeon, &gs->map, floor_num);
|
dungeon_generate(&gs->dungeon, &gs->map, floor_num);
|
||||||
|
|
||||||
// Seed rng for this floor's content
|
// Seed rng for this floor's content
|
||||||
rng_seed(floor_num * 54321);
|
rng_seed(gs->run_seed + floor_num * 98765);
|
||||||
|
|
||||||
// Find spawn position
|
// Find spawn position
|
||||||
int start_x, start_y;
|
int start_x, start_y;
|
||||||
|
|
@ -477,7 +482,9 @@ static int handle_input(GameState *gs) {
|
||||||
|
|
||||||
// Check for restart (works during game over)
|
// Check for restart (works during game over)
|
||||||
if (IsKeyPressed(KEY_R) && gs->game_over) {
|
if (IsKeyPressed(KEY_R) && gs->game_over) {
|
||||||
|
unsigned int saved_seed = gs->run_seed;
|
||||||
memset(gs, 0, sizeof(GameState));
|
memset(gs, 0, sizeof(GameState));
|
||||||
|
gs->run_seed = saved_seed;
|
||||||
init_floor(gs, 1);
|
init_floor(gs, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -508,12 +515,12 @@ void load_audio_assets(GameState *gs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
static void game_loop(void) {
|
static void game_loop(unsigned int run_seed) {
|
||||||
GameState gs;
|
GameState gs;
|
||||||
memset(&gs, 0, sizeof(GameState));
|
memset(&gs, 0, sizeof(GameState));
|
||||||
|
gs.run_seed = run_seed;
|
||||||
load_audio_assets(&gs);
|
load_audio_assets(&gs);
|
||||||
// Initialize first floor
|
// Initialize first floor
|
||||||
rng_seed(12345);
|
|
||||||
init_floor(&gs, 1);
|
init_floor(&gs, 1);
|
||||||
|
|
||||||
// Disable esc to exit
|
// Disable esc to exit
|
||||||
|
|
@ -532,7 +539,9 @@ static void game_loop(void) {
|
||||||
if (IsKeyPressed(KEY_Q))
|
if (IsKeyPressed(KEY_Q))
|
||||||
break;
|
break;
|
||||||
if (IsKeyPressed(KEY_R)) {
|
if (IsKeyPressed(KEY_R)) {
|
||||||
|
unsigned int saved_seed = gs.run_seed;
|
||||||
memset(&gs, 0, sizeof(GameState));
|
memset(&gs, 0, sizeof(GameState));
|
||||||
|
gs.run_seed = saved_seed;
|
||||||
gs.game_over = 0;
|
gs.game_over = 0;
|
||||||
gs.game_won = 0;
|
gs.game_won = 0;
|
||||||
load_audio_assets(&gs);
|
load_audio_assets(&gs);
|
||||||
|
|
@ -599,7 +608,23 @@ static void game_loop(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(int argc, char **argv) {
|
||||||
|
// Parse command-line arguments
|
||||||
|
unsigned int run_seed = 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]);
|
||||||
|
i++; // Skip the value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no seed provided, generate random seed from time
|
||||||
|
if (run_seed == 0) {
|
||||||
|
run_seed = (unsigned int)time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Starting game with seed: %u\n", run_seed);
|
||||||
|
|
||||||
// Initialize audio
|
// Initialize audio
|
||||||
audio_init();
|
audio_init();
|
||||||
// Initialize random number generator
|
// Initialize random number generator
|
||||||
|
|
@ -609,7 +634,7 @@ int main(void) {
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
|
|
||||||
// Run game
|
// Run game
|
||||||
game_loop();
|
game_loop(run_seed);
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
|
|
|
||||||
|
|
@ -170,9 +170,6 @@ void get_random_floor_tile(Map *map, int *x, int *y, int attempts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dungeon_generate(Dungeon *d, Map *map, int floor_num) {
|
void dungeon_generate(Dungeon *d, Map *map, int floor_num) {
|
||||||
// Seed RNG with floor number for deterministic generation
|
|
||||||
rng_seed(floor_num * 12345);
|
|
||||||
|
|
||||||
// Initialize map to all walls
|
// Initialize map to all walls
|
||||||
map_init(map);
|
map_init(map);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue