maze generation with dfs algo

This commit is contained in:
quenousimporte 2025-04-12 13:03:50 +02:00
parent d82c3ccbea
commit 1dbfd68878
1 changed files with 150 additions and 42 deletions

192
w/w.c
View File

@ -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");
}