From 1dbfd68878551ddc420907cb57bcf2f49af56d26 Mon Sep 17 00:00:00 2001 From: quenousimporte <quenousimporte@git.ouvaton.coop> Date: Sat, 12 Apr 2025 13:03:50 +0200 Subject: [PATCH] maze generation with dfs algo --- w/w.c | 192 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 150 insertions(+), 42 deletions(-) diff --git a/w/w.c b/w/w.c index bae4347..3b2f0a8 100644 --- a/w/w.c +++ b/w/w.c @@ -41,6 +41,7 @@ #define TILE_START 's' #define TILE_UNKNOWN '?' #define TILE_UNUSED '.' +#define TILE_UNVISITED 'x' #define ITEM_POTION '0' #define ITEM_TRUC '1' @@ -75,7 +76,7 @@ typedef struct { typedef struct { Character hero; - Position position; + Position position; Item inventory[INVENTORY_SIZE]; char screen; } Gamestate; @@ -89,9 +90,8 @@ Character currentmonster; Round* firstround = NULL; Round* currentround = NULL; -int freedom = 2; char map[MAP_SIZE * MAP_SIZE]; - +int ddl; Character monsters[2] = { { "alien bleu", 2, 2, 1, 1 }, { "vilaine araignée", 5, 8, 2, 1 } @@ -146,7 +146,7 @@ void drawmap() } printf("\n"); } - printf("freedom: %d\n", freedom); + printf("ddl=%d\n", ddl); } void drawpov3d() @@ -330,26 +330,6 @@ void update3dpov() void updatepov() { - // generate map - /*setatpos(state.position.x, state.position.y, ' '); - - Position front; - memcpy(&front, &state.position, sizeof(Position)); - if (state.position.orientation - - // right - if (state.position.x + 1 == 0) - { - setatpos(state.position.x + 1, state.position.y, 'w'); - } - else if (charatpos(state.position.x + 1, state.position.y) == '?') - { - char c = dice() > 3 ? 'w' : ' '; - setatpos(state.position.x + 1, state.position.y, c); - if (c == 'w') freedom--; - }*/ - - int x = state.position.x; int y = state.position.y; char orientation = state.position.orientation; @@ -500,7 +480,7 @@ void createhero(char* name) state.hero.gold = 0; state.hero.atk = 1; state.hero.def = 1; - + Item potion = { ITEM_POTION, "potion", 20, 0 }; Item truc = { ITEM_TRUC, "truc", 2000, 0 }; state.inventory[0] = potion; @@ -587,27 +567,153 @@ void drawrounds() } } -char gentile() +char gentile(int x, int y) { - int r = dice(); - if (r == 1) return 'd'; - if (r < 4) return 'w'; - return ' '; + char c = charatpos(x, y); + if (c == TILE_UNKNOWN) + { + int d = dice(); + if (d == 1) + { + c = TILE_DOOR; + ddl++; + } + else if (d < 5 && ddl > 1) + { + c = TILE_WALL; + ddl--; + } + else + { + c = TILE_FREE; + ddl++; + } + setatpos(x, y, c); + } + return TILE_UNUSED; +} + +void updatemap() +{ + int x = state.position.x; + int y = state.position.y; + + // north + char c = gentile(x, y - 1); + if (c == TILE_FREE) + { + ddl--; + gentile(x - 1, y - 2); + gentile(x + 1, y - 2); + } + + // south + c = gentile(x, y + 1); + if (c == TILE_FREE) + { + ddl--; + gentile(x - 1, y + 2); + gentile(x + 1, y + 2); + } + + // east + c = gentile(x + 1, y); + if (c == TILE_FREE) + { + ddl--; + gentile(x + 2, y - 1); + gentile(x + 2, y + 1); + } + + // west + c = gentile(x - 1, y); + if (c == TILE_FREE) + { + ddl--; + gentile(x - 2, y - 1); + gentile(x - 2, y + 1); + } +} + +void dfs(int x, int y) +{ + setatpos(x, y, TILE_FREE); + + bool nok = false; + bool eok = false; + bool sok = false; + bool wok = false; + + while (! (nok && eok && sok && wok)) + { + char orientation = rand() % 4; + switch (orientation) + { + case NORTH: + nok = true; + if (charatpos(x, y - 2) == TILE_UNVISITED) + { + setatpos(x, y - 1, dice() == 6 ? TILE_DOOR : TILE_FREE); + dfs(x, y - 2); + } + break; + case SOUTH: + sok = true; + if (charatpos(x, y + 2) == TILE_UNVISITED) + { + setatpos(x, y + 1, dice() == 6 ? TILE_DOOR : TILE_FREE); + dfs(x, y + 2); + } + break; + case EAST: + eok = true; + if (charatpos(x - 2, y) == TILE_UNVISITED) + { + setatpos(x - 1, y, dice() == 6 ? TILE_DOOR : TILE_FREE); + dfs(x - 2, y); + } + break; + case WEST: + wok = true; + if (charatpos(x + 2, y) == TILE_UNVISITED) + { + setatpos(x + 1, y, dice() == 6 ? TILE_DOOR : TILE_FREE); + dfs(x + 2, y); + } + break; + } + } } void initmap() { - memset(&map, TILE_UNKNOWN, MAP_SIZE * MAP_SIZE); - setatpos(1, 13, TILE_FREE); + //memset(&map, TILE_UNKNOWN, MAP_SIZE * MAP_SIZE); + memset(&map, TILE_WALL, MAP_SIZE * MAP_SIZE); // dfs: put walls everywhere + + // dfs: add random room + for (int x = 0; x < MAP_SIZE; x ++) + for (int y = 0; y < MAP_SIZE; y++) + if (dice() > 4) + // setatpos(x, y, TILE_FREE); - setatpos(0, 13, TILE_WALL); - setatpos(0, 11, TILE_WALL); - setatpos(1, 14, TILE_WALL); - setatpos(3, 14, TILE_WALL); - for (int x = 0; x < MAP_SIZE; x += 2) + { for (int y = 14; y >=0; y -= 2) - setatpos(x, y, TILE_UNUSED); + { + setatpos(0, y - 1, TILE_WALL); + setatpos(14, y - 1, TILE_WALL); + + setatpos(x, y, TILE_WALL); // => instead of TILE_UNUSED, for readibility + + //setatpos(x + 1, y + 1, TILE_FREE); + setatpos(x + 1, y + 1, TILE_UNVISITED); // dfs + } + setatpos(x + 1, 0, TILE_WALL); + setatpos(x + 1, 14, TILE_WALL); + } + + // setatpos(1, 13, TILE_FREE); + dfs(1,13); } void update(char* command) @@ -622,9 +728,10 @@ void update(char* command) int x = state.position.x; int y = state.position.y; forward(); + //updatemap(); if ( (x != state.position.x || y != state.position.y) && dice() > 4) { - gotomonster(); + // gotomonster(); } break; case CMD_RIGHT: @@ -667,8 +774,9 @@ void update(char* command) state.position.x = 1; state.position.y = 13; state.position.orientation = NORTH; - + initmap(); + //updatemap(); updatepov(); } else if (c == CMD_GOTOMARKET) @@ -792,8 +900,8 @@ void draw() else if (state.screen == SC_MAP) { update3dpov(); - //drawpov3d(); drawmap(); + drawpov3d(); if (charatpos(state.position.x, state.position.y) == TILE_START) { @@ -844,7 +952,7 @@ void draw() printf("price: %d\n", item.price); printf("owned: %d\n", item.count); } - + printf("\nr: Retour à la station\n"); }