Labyrinth/bakcup/src/eller.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;
}