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_START 's'
#define TILE_UNKNOWN '?' #define TILE_UNKNOWN '?'
#define TILE_UNUSED '.' #define TILE_UNUSED '.'
#define TILE_UNVISITED 'x'
#define ITEM_POTION '0' #define ITEM_POTION '0'
#define ITEM_TRUC '1' #define ITEM_TRUC '1'
@ -75,7 +76,7 @@ typedef struct {
typedef struct { typedef struct {
Character hero; Character hero;
Position position; Position position;
Item inventory[INVENTORY_SIZE]; Item inventory[INVENTORY_SIZE];
char screen; char screen;
} Gamestate; } Gamestate;
@ -89,9 +90,8 @@ Character currentmonster;
Round* firstround = NULL; Round* firstround = NULL;
Round* currentround = NULL; Round* currentround = NULL;
int freedom = 2;
char map[MAP_SIZE * MAP_SIZE]; char map[MAP_SIZE * MAP_SIZE];
int ddl;
Character monsters[2] = { Character monsters[2] = {
{ "alien bleu", 2, 2, 1, 1 }, { "alien bleu", 2, 2, 1, 1 },
{ "vilaine araignée", 5, 8, 2, 1 } { "vilaine araignée", 5, 8, 2, 1 }
@ -146,7 +146,7 @@ void drawmap()
} }
printf("\n"); printf("\n");
} }
printf("freedom: %d\n", freedom); printf("ddl=%d\n", ddl);
} }
void drawpov3d() void drawpov3d()
@ -330,26 +330,6 @@ void update3dpov()
void updatepov() 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 x = state.position.x;
int y = state.position.y; int y = state.position.y;
char orientation = state.position.orientation; char orientation = state.position.orientation;
@ -500,7 +480,7 @@ void createhero(char* name)
state.hero.gold = 0; state.hero.gold = 0;
state.hero.atk = 1; state.hero.atk = 1;
state.hero.def = 1; state.hero.def = 1;
Item potion = { ITEM_POTION, "potion", 20, 0 }; Item potion = { ITEM_POTION, "potion", 20, 0 };
Item truc = { ITEM_TRUC, "truc", 2000, 0 }; Item truc = { ITEM_TRUC, "truc", 2000, 0 };
state.inventory[0] = potion; state.inventory[0] = potion;
@ -587,27 +567,153 @@ void drawrounds()
} }
} }
char gentile() char gentile(int x, int y)
{ {
int r = dice(); char c = charatpos(x, y);
if (r == 1) return 'd'; if (c == TILE_UNKNOWN)
if (r < 4) return 'w'; {
return ' '; 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() void initmap()
{ {
memset(&map, TILE_UNKNOWN, MAP_SIZE * MAP_SIZE); //memset(&map, TILE_UNKNOWN, MAP_SIZE * MAP_SIZE);
setatpos(1, 13, TILE_FREE); 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 x = 0; x < MAP_SIZE; x += 2)
{
for (int y = 14; y >=0; y -= 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) void update(char* command)
@ -622,9 +728,10 @@ void update(char* command)
int x = state.position.x; int x = state.position.x;
int y = state.position.y; int y = state.position.y;
forward(); forward();
//updatemap();
if ( (x != state.position.x || y != state.position.y) && dice() > 4) if ( (x != state.position.x || y != state.position.y) && dice() > 4)
{ {
gotomonster(); // gotomonster();
} }
break; break;
case CMD_RIGHT: case CMD_RIGHT:
@ -667,8 +774,9 @@ void update(char* command)
state.position.x = 1; state.position.x = 1;
state.position.y = 13; state.position.y = 13;
state.position.orientation = NORTH; state.position.orientation = NORTH;
initmap(); initmap();
//updatemap();
updatepov(); updatepov();
} }
else if (c == CMD_GOTOMARKET) else if (c == CMD_GOTOMARKET)
@ -792,8 +900,8 @@ void draw()
else if (state.screen == SC_MAP) else if (state.screen == SC_MAP)
{ {
update3dpov(); update3dpov();
//drawpov3d();
drawmap(); drawmap();
drawpov3d();
if (charatpos(state.position.x, state.position.y) == TILE_START) if (charatpos(state.position.x, state.position.y) == TILE_START)
{ {
@ -844,7 +952,7 @@ void draw()
printf("price: %d\n", item.price); printf("price: %d\n", item.price);
printf("owned: %d\n", item.count); printf("owned: %d\n", item.count);
} }
printf("\nr: Retour à la station\n"); printf("\nr: Retour à la station\n");
} }