-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaze_solver.c
139 lines (108 loc) · 3.05 KB
/
maze_solver.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <stdio.h>
#include <stdlib.h>
#include "bmp/bmp_helpers.h"
#include "common.h"
#include "maze_solver.h"
#include "maze_solver_helpers.h"
/**
* Free the nodes (if any) in the shortest path queue when the shortest
* path could not be successfully found.
*/
static void free_sp_queue(struct sp_queue_head *sp)
{
while(!sp_queue_empty(sp))
{
free(sp_remove_elem(sp));
}
}
int solve_maze(struct maze_image *const maze)
{
int ret_val = 0;
// find the padding
maze->padding = find_padding(maze->width);
#ifdef KS_MAZE_SOLVER_DEBUG
printf("solve_maze: sizeof(struct maze_image): %zu\n", sizeof(struct maze_image));
printf("solve_maze: padding: %u bytes\n", maze->padding);
// find the image data size
const unsigned long image_data_size = (maze->height*maze->width*bytes_per_pixel) +
(maze->padding*maze->height); // a way to find data size without file size
printf("solve_maze: Size of image data: %lu\n", image_data_size);
#endif
struct openings *const gates = find_openings(maze);
if (gates == NULL)
{
return ERROPENINGS;
}
#ifdef KS_MAZE_SOLVER_DEBUG
printf("solve_maze: Start gate pixel: %u\t End gate pixel: %u\n",
gates->start_gate_pixel, gates->end_gate_pixel);
#endif
#ifdef KS_MAZE_SOLVER_DEBUG_PROGRESS
printf("solve_maze: Progress: Graph creation for the maze ...\n");
#endif
if (create_graph(maze, gates))
{
ret_val = ERRMEMORY;
goto CLEANUP_GRAPH;
}
#ifdef KS_MAZE_SOLVER_DEBUG_PROGRESS
printf("solve_maze: Progress: Graph generated successfully for the maze.\n");
#endif
// find the shortest path to the end node from the source node
// for the constructed graph
struct sp_queue_head *const sp = malloc(sizeof(struct sp_queue_head));
if (sp == NULL)
{
ret_val = ERRMEMORY;
goto CLEANUP_GRAPH;
}
initialise_sp_queue(sp);
#ifdef KS_MAZE_SOLVER_DEBUG_PROGRESS
printf("solve_maze: Progress: Shortest path to destination using the graph ..\n");
#endif
unsigned dest_distance = find_shortest_path(gates, sp);
if (dest_distance != 0)
{
#ifdef KS_MAZE_SOLVER_DEBUG_PROGRESS
printf("solve_maze: Progress: Shortest path generated successfully.\n");
#endif
#ifdef KS_MAZE_SOLVER_DEBUG_PRINT_SHORTEST_PATH
// Warning: This removes the items from the queue!
printf("Shortest path from %u to %u:\n", gates->start_gate_pixel, gates->end_gate_pixel);
while (!sp_queue_empty(sp))
{
struct sp_queue_elem *const curr_elem = sp_remove_elem(sp);
if (curr_elem == NULL)
{
fprintf(stderr, "solve_maze: Removing element from queue failed!\n");
exit(EXIT_FAILURE);
}
printf("%u\t", curr_elem->elem);
fflush(stdout);
free(curr_elem);
}
printf("\n");
#else
#ifdef KS_MAZE_SOLVER_DEBUG_PROGRESS
printf("solve_maze: Progress: Colour the shortest path ..\n");
#endif
colour_path(maze, sp);
#ifdef KS_MAZE_SOLVER_DEBUG_PROGRESS
printf("solve_maze: Progress: Colouring of shortest path completed.\n");
#endif
#endif
}
else
{
free_sp_queue(sp);
ret_val = ERRSHPATH;
goto CLEANUP;
}
CLEANUP:
// free the queue head
free(sp);
CLEANUP_GRAPH:
delete_graph();
free(gates);
return ret_val;
}