:: PlayerAdvance.org ::  

Précédent   :: PlayerAdvance.org :: > :: Développement Amateur :: > Autres > Tutoriels

Tutoriels Tutoriels dédiés au développement sur d'autres supports

Publicité

Réponse
 
Outils de la discussion Modes d'affichage
Vieux 18/09/2006, 23h50   #1
Bobby Sixkilla
Maître Chinpoko-extra-mon
 
Date d'inscription: 10/11/2005
Localisation: Palaiseau (Rive sud)
Messages: 6 466
Voir les codes amis Nintendo DS
Par défaut Génération de labyrinthe

Génération de labyrinthe

Auteur : rmstudiogames

Alors voilà comme je l'avais proposé, voici un algo tres simple pour créer un labyrinthe fermé, ce qui veut dire que l'on ne peut pas tourner en rond. Si l'on ne fait qu'avancer, on ne repassera jamais deux fois au même endroit.

Attention, le code n'est pas très propre, je vous file la version qui m'a servi de test. La version finale est codée pour NGage, donc ça ne recompilera jamais sur GBA ou n'importe quoi d'autre !

Par exemple, c'est "hardcode" pour un labyrinthe 11x12 cases, à changer bien sur avec des variables que l'on pourra initialiser au runtime. Egalement, pour le système de backtrack, l'implementation optimale devrait utiliser une stack, j'ai salement utilisé un tableau de la taille du nombre maximum de cases (beurk c'est moche, à proscrire). Je n'ai même pas utilisé de structures, j'ai des variables differentes pour les x et les y.

Il est conseillé de modifier l'algo de façon à le modeler pour ses besoins. Ainsi à chaque "step", choisissant une direction aléatoirement, je n'obtenais pas beaucoup de lignes droites, ca zigzaguait dans tous les sens. Pour mon jeu, lorsque je pars dans une direction, pour le prochain step j'affecte plus de probabilité à cette direction. On pourrait faire plein d'améliorations de ce style.

Bon assez parlé, voilà le code...
Code:
#include "stdlib.h"
#include "string.h"

static char	maze[132];	//	The array which stores the state of each maze cell.
static int	neighbourX[] = { 1, -1, 0, 0 };	//	An array which is used to determine coordinates of
static int	neighbourY[] = { 0, 0, 1, -1 };	//	an adjacent cell (up, down, left, right).

int GivePossibleNeighbours(int x, int y)
{
//	For a given cell, gives the total number of adjacent cells.
//	adjacent does not include diagonals.
if(((x == 0) || (x == 10)) && ((y == 0) || (y == 11)))
 return 2;
else if((x == 0) || (x == 10) ||(y == 0) || (y == 11))
 return 3;
else
 return 4;
}

bool CellIsFree(int x, int y)
{
//	A cell is considered as free if it is included in the maze
//	and has not been visited yet, so it still holds a '1' flag.
if((x >= 0) && (x < 11) &&(y >= 0) && (y < 12) && (maze[y*11+x] == '1'))
 return true;
else
 return false;
}

int GiveFreeNeighbours(int x, int y)
{
int	result;
int	scan;

result	= 0;
//	We inspect every adjacent cell and we increment the counter
//	when each of them is free.
for(scan = 0; scan < 4; scan++)
 if(CellIsFree(x+neighbourX[scan], y+neighbourY[scan]))
 	result++;

return result;
}

int main(int argc, char* argv[])
{
int	currentX;	//	The current cell visited during the algorithm.
int	currentY;
int	backTracksX[132];	//	The array of points where we store every cell
int	backTracksY[132];	//	which has been used as a progression in the maze.
int	numBackTrack;  //	Number of the cells filling the array.

//	All the maze if filled with blocks. Thus, all cells are not visited.
memset(maze, '1', 132);

//	By doing this, we consider the top left cell is being visited. This is the
//	starting point of the algorithm. It could be randomly chosen.
currentX  = 0;
currentY  = 0;
backTracksX[0]	= 0;
backTracksY[0]	= 0;
numBackTrack	= 0;

//	The main algorithm.
do
{
 int	possibleNeighbours, freeNeighbours;
 int	direction;
 int	test;

 //	We now clear the current cell
 maze[currentY*11+currentX]	= '0';

 //	We choose a random direction and increment the counter of tests.
 direction	= ((double)rand()/(double) RAND_MAX)*4;
 test  = 1;

 while(test <= 4)
 {
 	//	For a given direction, we get the number of possible and actual free neighbours.
 	//	If there is exactly one less free neighbour (because we come from a visited neighbour),
 	//	this means that this cell has no neighbours which has been visited before. We can safely
 	//	visit it, we will not "break" the maze.
 	possibleNeighbours	= GivePossibleNeighbours(currentX+neighbourX[direction], currentY+neighbourY[direction]);
 	freeNeighbours  = GiveFreeNeighbours(currentX+neighbourX[direction], currentY+neighbourY[direction]);
 	if((freeNeighbours == possibleNeighbours - 1) && CellIsFree(currentX+neighbourX[direction], currentY+neighbourY[direction]))
   	break;

 	//	Otherwise, we look for another close cell. If we have tested four times, it means all
 	//	neighbours have been visited.
 	test++;
 	direction++;
 	if(direction == 4)
   direction	= 0;
 }

 //	If we have found a free neighbour then we can jump to this cell.
 if(test <= 4)
 {
 	//	The current cell is added to the stack of visited cells (yes, this is an array),
 	//	before using the free neighbour as the current cell and restarting the algorithm.
 	numBackTrack++;
 	backTracksX[numBackTrack-1]	= currentX;
 	backTracksY[numBackTrack-1]	= currentY;
 	currentX	= currentX+neighbourX[direction];
 	currentY	= currentY+neighbourY[direction];
 }
 else
 {
 	//	Otherwise, this cell has no free neighbour, we have come to a dead end.
 	//	We leave this cell and use our stack (our array) to inspect the last visited
 	//	cell in case it can lead somewhere else.
 	numBackTrack--;
 	currentX	= backTracksX[numBackTrack-1];
 	currentY	= backTracksY[numBackTrack-1];
 }
}
while(numBackTrack);	//	Of course we can stop when there are no more visited cells available.

return 0;
}
Bobby Sixkilla est déconnecté   Réponse avec citation

Publicité

Réponse

Liens sociaux

Publicité



Utilisateurs regardant la discussion actuelle : 1 (0 membre(s) et 1 invité(s))
 
Outils de la discussion
Modes d'affichage

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 03h59.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd. Tous droits réservés.
Version française #16 par l'association vBulletin francophone
Design par Ass-Itch, DJP et Dr.Vince