2022-01-14 01:01:07 +00:00
|
|
|
#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;
|
|
|
|
}
|
|
|
|
|
2022-01-14 01:26:39 +00:00
|
|
|
printf("\n");
|
2022-01-14 02:10:57 +00:00
|
|
|
char maze2d[size][size];
|
2022-01-14 01:01:07 +00:00
|
|
|
for (int y = 0; y < size; y++) {
|
|
|
|
for (int x = 0; x < size; x++) {
|
2022-01-14 01:34:31 +00:00
|
|
|
printf("%c", maze[size * y + x]);
|
2022-01-14 02:10:57 +00:00
|
|
|
maze2d[y][x] = maze[size * y + x] == 'x' ? 'x' : 0;
|
2022-01-14 01:01:07 +00:00
|
|
|
}
|
2022-01-14 01:26:39 +00:00
|
|
|
printf("\n");
|
2022-01-14 01:01:07 +00:00
|
|
|
}
|
2022-01-14 02:10:57 +00:00
|
|
|
printf("\nstart %d\n\n", size);
|
|
|
|
|
|
|
|
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) {
|
|
|
|
printf("\nend");
|
|
|
|
return 0;
|
|
|
|
} else if (posX == size - 1 && posY == size - 1) {
|
|
|
|
maze2d[0][0] = '*';
|
|
|
|
|
2022-01-19 16:41:10 +00:00
|
|
|
//cleanuup data bits
|
2022-01-14 02:10:57 +00:00
|
|
|
for (int y = 0; y < size; y++) {
|
|
|
|
for (int x = 0; x < size; x++) {
|
|
|
|
if (maze2d[y][x] == CHECKED_BIT || maze2d[y][x] == 0) {
|
|
|
|
maze2d[y][x] = ' ';
|
|
|
|
} else if (maze2d[y][x] != 'x') {
|
|
|
|
maze2d[y][x] = '*';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-19 16:47:23 +00:00
|
|
|
//cleanuup redundant routes
|
2022-01-14 02:10:57 +00:00
|
|
|
for (int y = size - 2; y >= 0; y--) {
|
|
|
|
for (int x = size - 2; x >= 0; x--) {
|
|
|
|
if (maze2d[y][x] == '*' && maze2d[y + 1][x] == '*' && maze2d[y + 1][x + 1] == '*' && maze2d[y][x + 1] == '*') {
|
|
|
|
maze2d[y + 1][x + 1] = ' ';
|
|
|
|
maze2d[y][x + 1] = ' ';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//serialize
|
|
|
|
for (int y = 0; y < size; y++) {
|
|
|
|
for (int x = 0; x < size; x++) {
|
|
|
|
maze[y * size + x] = maze2d[y][x];
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 16:41:10 +00:00
|
|
|
printf("\n\nend");
|
2022-01-14 02:10:57 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2022-01-14 01:01:07 +00:00
|
|
|
}
|