Il seguente codice è un semplice programma che permette di generare casualmente dei labirinti composti da caratteri e stamparli su schermo.
Il programma è stato commentato per renderne più facile la comprensione.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 81 // 40 * 2 + 1
#define CELLA 1600 // 40^2
#define MURO 1
#define VIA 0
using namespace std;
void iniz_labi(int labi[MAX][MAX]);
void labi_generator(int indiceks, int labi[MAX][MAX], int retrotraccia_x[CELLA], int retrotraccia_y[CELLA], int x, int y, int n, int visitato);
void stampa_labi(int labi[MAX][MAX], int labi_taglia);
int e_chiuso(int labi[MAX][MAX], int x, int y);
int main(void)
{
srand((unsigned)time(NULL));
int taglia, indiceks = 0;
int labi[MAX][MAX], retrotraccia_x[CELLA], retrotraccia_y[CELLA];
cout << "CREATORE LABIRINTO\n\n";
cout << "input (0 ~ 40): ";
cin >> taglia;
cout << endl;
iniz_labi(labi);
retrotraccia_x[indiceks] = 1;
retrotraccia_y[indiceks] = 1;
labi_generator(indiceks, labi, retrotraccia_x, retrotraccia_y, 1, 1, taglia, 1);
stampa_labi(labi, taglia);
getch();
return EXIT_SUCCESS;
}
// inizializzazione labirinto vuoto e pieno
void iniz_labi(int labi[MAX][MAX])
{
for(int a = 0; a < MAX; a++)
{
for(int b = 0; b < MAX; b++)
{
if(a % 2 == 0 || b % 2 == 0)
labi[a][b] = MURO;
else
labi[a][b] = VIA;
}
}
}
// generazione aperture casuali nel percorso
void labi_generator(int indiceks, int labi[MAX][MAX], int retrotraccia_x[CELLA], int retrotraccia_y[CELLA], int x, int y, int n, int visitato)
{
if(visitato < n * n)
{
int vicino_valido = -1;
int vicino_x[4], vicino_y[4], passo[4];
int x_prossimo;
int y_prossimo;
if(x - 2 > 0 && e_chiuso(labi, x - 2, y)) // sopra
{
vicino_valido++;
vicino_x[vicino_valido]=x - 2;;
vicino_y[vicino_valido]=y;
passo[vicino_valido]=1;
}
if(y - 2 > 0 && e_chiuso(labi, x, y - 2)) // a sinistra
{
vicino_valido++;
vicino_x[vicino_valido]=x;
vicino_y[vicino_valido]=y - 2;
passo[vicino_valido]=2;
}
if(y + 2 < n * 2 + 1 && e_chiuso(labi, x, y + 2)) // a destra
{
vicino_valido++;
vicino_x[vicino_valido]=x;
vicino_y[vicino_valido]=y + 2;
passo[vicino_valido]=3;
}
if(x + 2 < n * 2 + 1 && e_chiuso(labi, x + 2, y)) // basso
{
vicino_valido++;
vicino_x[vicino_valido]=x+2;
vicino_y[vicino_valido]=y;
passo[vicino_valido]=4;
}
if(vicino_valido == -1)
{
// traccia lasciata ed arretramento
x_prossimo = retrotraccia_x[indiceks];
y_prossimo = retrotraccia_y[indiceks];
indiceks--;
}
if(vicino_valido!=-1)
{
// traccia lasciata ed arretramento
int casualizzare = vicino_valido + 1, random = rand()%casualizzare;
x_prossimo = vicino_x[random];
y_prossimo = vicino_y[random];
indiceks++;
retrotraccia_x[indiceks] = x_prossimo;
retrotraccia_y[indiceks] = y_prossimo;
int rpasso = passo[random];
if(rpasso == 1)
labi[x_prossimo+1][y_prossimo] = VIA;
else if(rpasso == 2)
labi[x_prossimo][y_prossimo + 1] = VIA;
else if(rpasso == 3)
labi[x_prossimo][y_prossimo - 1] = VIA;
else if(rpasso == 4)
labi[x_prossimo - 1][y_prossimo] = VIA;
visitato++;
}
// richiamo a se stessa
labi_generator(indiceks, labi, retrotraccia_x, retrotraccia_y, x_prossimo, y_prossimo, n, visitato);
}
}
// determina se cella chiusa
int e_chiuso(int labi[MAX][MAX], int x, int y)
{
if(labi[x - 1][y] == MURO && labi[x][y - 1] == MURO
&& labi[x][y + 1] == MURO && labi[x + 1][y] == MURO ) return 1;
return 0;
}
// visualizzazione labirinto
void stampa_labi(int labi[MAX][MAX], int labi_taglia)
{
for(int a = 0; a < labi_taglia * 2 + 1; a++)
{
for(int b = 0; b < labi_taglia * 2 + 1; b++)
{
if(labi[a][b] == MURO)
cout << "@";
else
cout <<" ";
}
printf("\n");
}
}
Nessun commento:
Posta un commento