1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
| #include "Generator.h"
Generator::Generator(){
//Variables de taille, pour le moment aléatoires
int const longueur(5), largeur(5);
//Initialisation de rand
srand(time(NULL));
labyrinthe.resize(boost::extents[longueur][largeur][5]);
labyrintheDos.resize(boost::extents[longueur][largeur][5]);
for(int i=0; i<longueur; ++i){
for(int j=0; j<largeur; ++j){
for(int k=0; k<5; ++k){
labyrinthe[i][j][k] = false;
labyrintheDos[i][j][k] = false;
}
}
}
int larg = labyrinthe
this->resetDirections();
this->genereChemin();
}
Generator::~Generator(){
//dtor
}
void Generator::genereChemin(){
//On part toujours du coin supérieur gauche
chemin.push_back(std::make_pair(0, 0));
position = std::make_pair(0, 0);
labyrinthe[0][0][0] = true; //La première case est visitée
//Tant qu'on est pas revenu au début, on poursuit la génération
while(!chemin.empty()){
//Le principe est simple, on avance toujours et quand on ne peut plus, on recule
//On remet le bordures à zéro
this->resetDirections();
//Délimitation des bordures
this->findBorders();
//Élimination des cases visitées adjacentes
//HINT : Accepter une case visitée dans 20% des cas!
this->findVisited();
bool avancer = false;
std::map<Generator::direction, bool>::iterator it;
while(!avancer){
//On fait des tours de boucle tant qu'on ne peut pas avancer
for(it = directions.begin(); it != directions.end(); ++it){
if(directions[it->first]){
avancer = true;
break;
}//Fin IF
}//Fin FOR
if(!avancer){
//Si on est ici, c'est qu'il est impossible d'avancer
this->resetDirections();
//On vérifie qu'on est pas revenu au début
if(chemin.empty()){
return;
}
chemin.pop_back();
position = chemin.back();
//On recherche les bordures
this->findBorders();
//Et les cases visitées
this->findVisited();
}
}//Fin WHILE
//S'il est possible d'avancer, on tire une direction au hasard
Generator::direction wayToGo;
bool ok = false;
//Tant que la direction n'est pas OK, on retire
while(!ok){
wayToGo = static_cast<Generator::direction>(rand() % (static_cast<int>(Generator::direction::DROITE)+1));
if(directions[wayToGo]){
//Si la direction est bonne, on la garde
ok = true;
}
}
//Si on est ici, c'est qu'on a une direction donc, on bouge!
switch(wayToGo){
case Generator::direction::HAUT:
//On change la position
position = std::make_pair(position.first, position.second-1);
chemin.push_back(position);
//Et on visite les cases
labyrinthe[position.first][position.second][0] = true;
labyrinthe[position.first][position.second][2] = true; //BAS (vu qu'on monte)
labyrinthe[position.first][position.second-1][1] = true; //HAUT
break;
case Generator::direction::BAS:
position = std::make_pair(position.first, position.second+1);
chemin.push_back(position);
//Visite des cases
labyrinthe[position.first][position.second][0] = true;
labyrinthe[position.first][position.second][1] = true; //HAUT
labyrinthe[position.first][position.second+1][2] = true; //BAS
break;
case Generator::direction::GAUCHE:
position = std::make_pair(position.first-1, position.second);
chemin.push_back(position);
//Visite des cases
labyrinthe[position.first][position.second][0] = true;
labyrinthe[position.first][position.second][4] = true; //DROITE
labyrinthe[position.first-1][position.second][3] = true; //GAUCHE
break;
case Generator::direction::DROITE:
position = std::make_pair(position.first+1, position.second);
chemin.push_back(position);
//Visite des cases
labyrinthe[position.first][position.second][0] = true;
labyrinthe[position.first][position.second][3] = true; //GAUCHE
labyrinthe[position.first+1][position.second][4] = true; //DROITE
break;
default:
std::cerr << "ERREUR fatale" << std::endl << "La direction choisie est invalide" << std::endl;
exit(EXIT_FAILURE);
break;
}
}
return;
}
//Remet toutes les directions à TRUE
void Generator::resetDirections(){
directions[direction::HAUT] = true;
directions[direction::BAS] = true;
directions[direction::GAUCHE] = true;
directions[direction::DROITE] = true;
return;
}
//Trouve les bordures du labyrinche
void Generator::findBorders(){
if(position.second == 0)
directions[direction::HAUT] = false;
if(position.second == 4)
directions[direction::BAS] = false;
if(position.first == 0)
directions[direction::GAUCHE] = false;
if(position.first == 4)
directions[direction::DROITE] = false;
return;
}
//Trouve les cases visitées aux alentours de la case actuelle
void Generator::findVisited(){
std::map<Generator::direction, bool>::iterator it;
for(it = directions.begin(); it != directions.end(); ++it){
switch(it->first){
case direction::HAUT:
if(directions[it->first]){
if(labyrinthe[position.first][position.second-1][0]){
directions[direction::HAUT] = false;
}
}
break;
case direction::BAS:
if(directions[it->first]){
if(labyrinthe[position.first][position.second+1][0]){
directions[direction::BAS] = false;
}
}
break;
case direction::GAUCHE:
if(directions[it->first]){
if(labyrinthe[position.first-1][position.second][0]){
directions[direction::GAUCHE] = false;
}
}
break;
case direction::DROITE:
if(directions[it->first]){
if(labyrinthe[position.first+1][position.second][0]){
directions[direction::DROITE] = false;
}
}
break;
default:
std::cout << "ERREUR*FATALE" << std::endl << "Exception de direction trouvée" << std::endl;
exit(EXIT_FAILURE);
} //Fin du SWITCH
}//Fin du FOR
} |
Partager