137 lines
3.6 KiB
C
137 lines
3.6 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include "../include/eller.h"
|
|
#include "../include/queue.h"
|
|
|
|
#define ELLER_COST 2
|
|
|
|
Labyrinth* eller_(int n, int m, bool show);
|
|
|
|
Labyrinth* eller(int n, int m){
|
|
return eller_(n, m, false);
|
|
}
|
|
|
|
Labyrinth* ellerShow(int n, int m){
|
|
return eller_(n, m, true);
|
|
}
|
|
|
|
Labyrinth* eller_(int n, int m, bool show){
|
|
int i, j, h, tmp, tp;
|
|
Labyrinth* labyrinth = newLabyrinth(n, m);
|
|
|
|
int sets[m][m];
|
|
int setSizes[m];
|
|
|
|
queue(freeSets);
|
|
|
|
int arr[m];
|
|
for(i=0; i<m; i++){
|
|
int* s = (int*)malloc(sizeof(int));
|
|
*s = i;
|
|
queuePush(freeSets, s);
|
|
setSizes[i] = 0;
|
|
|
|
arr[i] = i;
|
|
}
|
|
|
|
int down[m];
|
|
|
|
|
|
printLab(labyrinth);
|
|
|
|
for(i=0; i<n; i++){
|
|
// reset sets
|
|
for(j=0; j<m; j++){
|
|
setSizes[j] = 0;
|
|
down[j] = 0;
|
|
}
|
|
|
|
// gives cells with no set a set
|
|
for(j=0; j<m; j++){
|
|
if(labyrinth->at[i][j].dp < 0){
|
|
int* tmp = (int*)freeSets->front->element;
|
|
labyrinth->at[i][j].dp = *tmp;
|
|
queuePop(freeSets);
|
|
}
|
|
|
|
tmp = labyrinth->at[i][j].dp;
|
|
sets[tmp][setSizes[tmp]] = j;
|
|
setSizes[tmp]++;
|
|
}
|
|
|
|
// randomizes order
|
|
for(j=m; j>0; j--){
|
|
tmp = rand() % j;
|
|
tp = arr[tmp];
|
|
arr[tmp] = arr[j-1];
|
|
arr[j-1] = tp;
|
|
}
|
|
|
|
// randomly merge cells
|
|
for(j=0; j<m; j++){
|
|
tmp = arr[j];
|
|
if(tmp < m-1 && labyrinth->at[i][tmp].dp != labyrinth->at[i][tmp+1].dp && (rand()%ELLER_COST || i==n-1)){
|
|
labyrinth->at[i][tmp].east = 1;
|
|
|
|
tp = labyrinth->at[i][tmp].dp;
|
|
tmp = labyrinth->at[i][tmp+1].dp;
|
|
for(h=0; h<setSizes[tmp]; h++){
|
|
sets[tp][setSizes[tp]] = sets[tmp][h];
|
|
setSizes[tp]++;
|
|
labyrinth->at[i][sets[tmp][h]].dp = tp;
|
|
}
|
|
setSizes[tmp] = 0;
|
|
|
|
int* s = (int*)malloc(sizeof(int));
|
|
*s = tmp;
|
|
queuePush(freeSets, s);
|
|
|
|
if(show){
|
|
labyrinth->at[i][tmp].color = ORANGE;
|
|
printLab(labyrinth);
|
|
labyrinth->at[i][tmp].color = WHITE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// randomly makes cells go down
|
|
for(j=0; j<m && i<n-1; j++){
|
|
// all but last cell
|
|
for(h=setSizes[j]; h>1; h--){
|
|
tmp = rand()%h;
|
|
tp = sets[j][tmp];
|
|
sets[j][tmp] = sets[j][h-1];
|
|
|
|
if(rand()%ELLER_COST){
|
|
labyrinth->at[i][tp].south = 1;
|
|
labyrinth->at[i+1][tp].dp = labyrinth->at[i][tp].dp;
|
|
down[j] = 1;
|
|
|
|
if(show){
|
|
labyrinth->at[i][tp].color = ORANGE;
|
|
printLab(labyrinth);
|
|
labyrinth->at[i][tp].color = WHITE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// last cell
|
|
if(setSizes[j] && (!down[j] || rand()%ELLER_COST)){
|
|
labyrinth->at[i][sets[j][0]].south = 1;
|
|
labyrinth->at[i+1][sets[j][0]].dp = labyrinth->at[i][sets[j][0]].dp;
|
|
|
|
if(show){
|
|
labyrinth->at[i][sets[j][0]].color = ORANGE;
|
|
printLab(labyrinth);
|
|
labyrinth->at[i][sets[j][0]].color = WHITE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
resetLabyrinth(labyrinth);
|
|
queueFree(freeSets);
|
|
|
|
return labyrinth;
|
|
} |