/**
a hexagonal-labyrinth generator by guru
press + or - to change the cell-count
press any key to generate a new labyrinth
*/
int [][] d;
int WIDTH=24;
void setup() {
d = generate(WIDTH);
size(600, 600, P2D);
}
void draw() {
background(255);
// float h = width/d.length;
// float di = sqrt( h*h - sq(h/2));
float di = width/d.length;
float h = sqrt( 4 * sq(di)/3);
for ( int r = 0; r < d.length; r++) {
float s = di * d[r].length;
for ( int c = 0; c < d[r].length; c++) {
float x = di/2+ width/2 - s/2 + di * c;
float y = h/2 + r * h*.75;
for ( int i = 0; i < 6; i++) {
if (( d[r][c] & int(pow(2,i))) == 0 ) {
line( x + sin( radians(120 + i*60))*h/2, y + cos( radians(120 +i*60))*h/2,
x + sin( radians(120+(i+1)*60))*h/2, y + cos( radians(120+(i+1)*60))*h/2);
}
}
if ( r == 0 && c == 0 ) {
fill(255);
ellipse( x, y, h/3, h/3 );
} else if ( r == d.length-1 && c == d[r].length - 1) {
fill(0);
ellipse( x, y, h/3, h/3 );
}
}
}
}
int[][] generate( int l ) {
int[][] res = new int[2*l-1][];
for ( int r =0; r<2*l-1; r++) {
int c = l + ( r < l-1 ? r : 2*l-2-r);
res[r] = new int[ c];
for( int i = 0; i < c; i++) {
res[r][i] = 0;
}
}
carve(0,0,res);
return res;
}
void carve( int r, int c, int[][] d) {
int[] dirs = shuffle();
for( int i=0; i < 6;i++) {
int dir = dirs[i];
int nr = r + (( dir == 32 || dir == 4 ) ? 0 : ( dir < 4 ? -1 : 1 ));
int nc = c;
int m = (d.length+1)/2-1;
if (r < m) {
if ( dir == 1 ) { nc = c; }
if ( dir == 2 ) { nc = c - 1; }
if ( dir == 4 ) { nc = c -1; }
if ( dir == 8 ) { nc = c; }
if ( dir == 16 ) { nc = c + 1; }
if ( dir == 32 ) { nc = c + 1; }
} else if ( r == m ) {
if ( dir == 1 ) { nc = c; }
if ( dir == 2 ) { nc = c - 1; }
if ( dir == 4 ) { nc = c -1; }
if ( dir == 8 ) { nc = c -1; }
if ( dir == 16 ) { nc = c; }
if ( dir == 32 ) { nc = c + 1; }
} else {
if ( dir == 1 ) { nc = c +1; }
if ( dir == 2 ) { nc = c; }
if ( dir == 4 ) { nc = c -1; }
if ( dir == 8 ) { nc = c -1; }
if ( dir == 16 ) { nc = c; }
if ( dir == 32 ) { nc = c + 1; }
}
// println( "X, Y = " + nx + " " + ny );
if ( nr >= 0 && nr < d.length && nc >= 0 && nc < d[nr].length && d[nr][nc] == 0 ) {
d[r][c] = d[r][c] | dir;
d[nr][nc] = d[nr][nc] | odir(dir);
carve(nr,nc,d);
}
}
}
int[] shuffle() {
int[] o = new int[] { 1,2,4,8,16,32};
int res[] = new int[6];
for( int i =0; i < 6; i++) {
int ri = int(random(6));
while ( o[ri] == 0 ) {
ri = int(random(6));
}
res[i] = o[ri];
o[ri] = 0;
}
return res;
}
int odir( int dir ) {
if (dir == 1) return 8;
if (dir == 8) return 1;
if (dir == 2) return 16;
if (dir == 16) return 2;
if (dir == 4) return 32;
if (dir == 32) return 4;
return 0;
}
void keyPressed() {
if ( key == '+' && WIDTH < 40 ) { WIDTH++; }
if ( key == '-' && WIDTH > 3 ) { WIDTH--; }
d = generate( WIDTH );
}