В настоящее время я работаю над программой, которая должна решать 10x10 лабиринт, например, такой:
1 2 3 4 5 6 7 8 9 10
___________________________________________
1| + [] + [] + [] + + + []
2| + [] + + [] + + [] [] []
3| + + [] [] [] + [] [] + +
4| [] [] [] [] + + + [] [] +
5| + [] + [] + [] + + + []
6| + + + + + + [] [] + []
7| [] + + + [] [] + + + []
8| + + + [] + + + [] [] +
9| + + + [] [] + + [] [] +
10| + [] + [] + + [] + + +
Игнорировать числа, они просто координаты.Что касается []
, это просто способ печати лабиринта.На самом деле, где есть +
, то это означает путь, где []
означает, что есть препятствие.
Я использую алгоритм возврата:
void backtrack(int curX, int curY, char(*char_maze)[10], int position)
{
if (curX < 0 || curY < 0 ||
curX > 9 || curY > 9) {
//out of bounds
return;
}
Node tmp;
tmp.x = curX, tmp.y = curY;
queue(&head, &tmp);
position++;
if (char_maze[curX][curY] == finish) {
//destination found TODO print path
printf("route found");
}
if (char_maze[curX][curY] == path) {
char_maze[curX][curY] = visited;
}
backtrack(curX, curY - 1, char_maze, position);
backtrack(curX - 1, curY, char_maze, position);
backtrack(curX, curY + 1, char_maze, position);
backtrack(curX + 1, curY, char_maze, position);
char_maze[curX][curY] = path;
if (position) {
del_nth(head, position);
}
if (!position) {
del_first(&head);
}
position--;
}
Правильный маршрутбудет состоять из связанного списка, вот узел этого списка:
typedef struct coords {
int x;
int y;
struct coords * next;
}Node;
всякий раз, когда backtrack(...)
натыкается на проходимую ячейку, он должен пометить его как посещенный и добавить в список.Добавление в список осуществляется с помощью этих 2 функций:
void queue(Node ** head, Node * object)
{
Node * tmp = (Node *)malloc(sizeof(Node)); //this is the problematic line
*tmp = *object;
Node * last = get_last(*(head));
if (!last) {
(*head) = tmp;
tmp->next = NULL;
}
else {
last->next = tmp;
tmp->next = NULL;
}
}
и
Node * get_last(Node * head)
{
while (1) {
if (head) {
head = head->next;
}
else {
return NULL;
}
}
return head;
}
, а также при соответствующих условиях backtrack(...)
следует снять отметку с ячейки и удалить ее из списка.Удаление выполняется с помощью этих двух функций:
void del_nth(Node * head, int index)
{
Node * previous;
for (int i = 0; i < index - 1; i++) {
head = head->next;
}
previous = head;
head = head->next;
previous->next = head->next;
free(head);
}
и
void del_first(Node ** head)
{
Node * del = (*head);
(*head) = (*head)->next;
free(del);
}
path, visited, finish
и т. Д. const char
-s, которые представляют ячейки лабиринта.
backtrack(...)
вызывается с 2-мя координатами, установленными пользователем, с самим лабиринтом и position
, для которого установлено 0
.
Теперь, когда я объяснил, как работает код, проблема.Я прогнал этот код через отладчик Visual Studio и получил исключение Stack overflow (parameters: 0x00000001, 0x00492FFC).
в этой строке
Node * tmp = (Node *) malloc(sizeof(Node));
, которое является частью функции queue(...)
.Это не имеет никакого смысла для меня, так как malloc()
выделяет в куче.Я в тупике, у меня нет объяснений, я понятия не имею, почему это происходит.Я включил весь код, используемый в функции backtrack(...)
, потому что проблема действительно может быть.Это был бы не первый случай, когда отладчик указал неверную строку.В любом случае, большое спасибо за вашу помощь заранее.