usaa21/sk1a/maze.c
Peter Petrek 32ccd86934 memory
2022-01-14 02:12:14 +01:00

127 lines
3.7 KiB
C

#include <stdio.h>
#include <string.h>
#include "maze.h"
#include <assert.h>
#include <unistd.h>
#define CHECKED_BIT 16
#define DIRECTION_BITS 15
enum direction {
NORTH = 8,
EAST = 4,
SOUTH = 2,
WEST = 1,
NONE = 0
};
int solve_maze(char* maze, int size) {
if (maze[0] == 'x') {
return 0;
}
char maze2d[size][size];
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
maze2d[y][x] = maze[size * y + x] == 'x' ? 'x' : 0;
}
}
int posY = 0, posX = 0;
while (1) {
enum direction next_step;
if (posX + 1 != size && maze2d[posY][posX + 1] != 'x' && !(maze2d[posY][posX + 1] & CHECKED_BIT)) {
next_step = EAST;
} else if (posY + 1 != size && maze2d[posY + 1][posX] != 'x' && !(maze2d[posY + 1][posX] & CHECKED_BIT)) {
next_step = SOUTH;
} else if (posX - 1 >= 0 && maze2d[posY][posX - 1] != 'x' && !(maze2d[posY][posX - 1] & CHECKED_BIT)) {
next_step = WEST;
} else if (posY - 1 >= 0 && maze2d[posY - 1][posX] != 'x' && !(maze2d[posY - 1][posX] & CHECKED_BIT)) {
next_step = NORTH;
} else {
next_step = NONE;
}
if (next_step != NONE) {
maze2d[posY][posX] |= CHECKED_BIT;
switch (next_step) {
case EAST:
posX += 1;
maze2d[posY][posX] |= WEST;
break;
case SOUTH:
posY += 1;
maze2d[posY][posX] |= NORTH;
break;
case WEST:
posX -= 1;
maze2d[posY][posX] |= EAST;
break;
case NORTH:
posY -= 1;
maze2d[posY][posX] |= SOUTH;
break;
default:
break;
}
} else {
char came_from = maze2d[posY][posX] & DIRECTION_BITS;
maze2d[posY][posX] = CHECKED_BIT;
switch (came_from) {
case EAST:
posX += 1;
break;
case SOUTH:
posY += 1;
break;
case WEST:
posX -= 1;
break;
case NORTH:
posY -= 1;
break;
default:
break;
}
}
if (posX == 0 && posY == 0) {
return 0;
} else if (posX == size - 1 && posY == size - 1) {
maze2d[0][0] = '*';
//cleanup data bits
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (maze2d[i][j] == CHECKED_BIT || maze2d[i][j] == 0) {
maze2d[i][j] = ' ';
} else if (maze2d[i][j] != 'x') {
maze2d[i][j] = '*';
}
}
}
//cleanup redundant routes
/*for (int i = size - 2; i >= 0; i--) {
for (int j = size - 2; j >= 0; j--) {
if (maze2d[i][j] == '*' && maze2d[i + 1][j] == '*' && maze2d[i + 1][j + 1] == '*' && maze2d[i][j + 1] == '*') {
maze2d[i + 1][j + 1] = ' ';
maze2d[i][j + 1] = ' ';
}
}
}*/
//serialize
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
maze[i * size + j] = maze2d[i][j];
}
}
return 1;
}
}
}