-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLabyrinthe.cpp
121 lines (100 loc) · 3.93 KB
/
Labyrinthe.cpp
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
#include "Labyrinthe.h"
using namespace Laby;
Cell::Cell(unsigned int id,unsigned int posX,unsigned posY){
this->id = id;
this->posX = posX;
this->posY = posY;
}
void Cell::changeId(unsigned int id, Cell* source){
this->id = id;
for( auto it : linked )
{
if(it != source)
{
it->changeId(id,this);
}
}
}
void Cell::openWallTo(Cell* target){
if( sqrDistanceTo(target) == 1 ) //verification que target est bien adjacente
{
/*suivant leurs positions relatives, on ouvre tel ou tel mur */
if( posX > target->posX ){ walls[W] = false; target->walls[E] = false; }
else if( posX < target->posX ){ walls[E] = false; target->walls[W] = false; }
else if( posY > target->posY ){ walls[N] = false; target->walls[S] = false; }
else if( posY < target->posY ){ walls[S] = false; target->walls[N] = false; }
/*on link les deux cellules entre elles*/
linked.insert(target);
target->linked.insert(this);
target->changeId(id,this);
}
}
Labyrinthe::Labyrinthe(unsigned int sizeX , unsigned int sizeY ){
this->sizeX = sizeX;
this->sizeY = sizeY;
nbrWallMax = sizeX*sizeY-1;
generator = std::default_random_engine( (unsigned int)time(0) );
distribX = std::uniform_int_distribution<unsigned int>(0,sizeX-1);
distribY = std::uniform_int_distribution<unsigned int>(0,sizeY-1);
distribCard = std::uniform_int_distribution<unsigned int>(N,W);
for( unsigned int x=0 ; x<sizeX ; x++ )
{
cells_array.push_back( std::vector< Cell* >() );
for( unsigned int y=0 ; y<sizeY ; y++ )
{
Cell* cell = new Cell(y*sizeX + x , x , y);
cells_array[x].push_back( cell );
}
}
}
Cell* Labyrinthe::getCellAt(unsigned int x , unsigned int y){
if( x > sizeX-1 || y > sizeY-1)return nullptr;
return cells_array[x][y];
}
Cell* Labyrinthe::getRandomCellCard(Cell* source){
Cell* target = source;
unsigned int exc1,exc2,card=0; //exc1 et exc2 represente les directions où il sera impossible de liberer un mur suivant la disposition
if( source->getX() == 0 && source->getY() == 0 ){exc1=N;exc2=W;}
else if( source->getX() == 0 && source->getY() == sizeY-1){exc1=S;exc2=W;}
else if( source->getX() == 0 ){exc1=W;exc2=NONE;}
else if( source->getX() == sizeX-1 && source->getY() == 0){exc1=N;exc2=E;}
else if( source->getX() == sizeX-1 && source->getY() == sizeY-1){exc1=E;exc2=S;}
else if( source->getX() == sizeX-1 ){exc1=E;exc2=NONE;}
else if( source->getY() == 0 ){exc1=N;exc2=NONE;}
else if( source->getY() == sizeY-1){exc1=S;exc2=NONE;}
else { exc1=NONE;exc2=NONE; }
do {
card = distribCard(generator); //on tir une direction au hasard
switch(card)
{
case N : if(source->getY() > 0) target = cells_array[source->getX()][source->getY()-1]; break;
case E : if(source->getX() < sizeX-1) target = cells_array[source->getX()+1][source->getY()]; break;
case S : if(source->getY() < sizeY-1) target = cells_array[source->getX()][source->getY()+1]; break;
case W : if(source->getX() > 0) target = cells_array[source->getX()-1][source->getY()]; break;
}
} while(card == exc1 || card == exc2 ); //tant que la direction tirée est impossible à ouvrir , on recommence (TODO : creation d'une petite liste d'exclusion pour ne passer qu'au maximum 4 fois dans la boucle)
if( source->getId() == target->getId() )return source;
return target;
}
void Labyrinthe::generate(){
Cell* source = nullptr;
Cell* target = nullptr;
for(unsigned int i=0 ; i<nbrWallMax ; i++)
{
do {
source = getRandomCell();
target = getRandomCellCard(source);
} while(target == source);
source->openWallTo(target);
}
}
Labyrinthe::~Labyrinthe()
{
for( unsigned int x=0 ; x<sizeX ; x++ )
{
for( unsigned int y=0 ; y<sizeY ; y++ )
{
delete cells_array[x][y];
}
}
}