/* cliparound(x, y)-- Make sure that the user is more-or-less centered on the screen if the playing area is larger than the screen. -- This function is only defined if CLIPPING is defined. */ void curses_cliparound(int x, int y) { int sx, sy, ex, ey; boolean redraw = curses_map_borders(&sx, &sy, &ex, &ey, x, y); if (redraw) { curses_draw_map(sx, sy, ex, ey); } }
/* Naive Path Code: placeholders to give demo output This is placeholder code that does not find the lowest cost path. You will need to not call this function and instead write make_path with your own implementation of the algorithm. The code here is extremely simple just to produce output. This is not an accurate guide for how your algorithm should work! */ void naive_path(struct map *map, int x0, int y0, int x1, int y1) { int i, j; /* set flags for the goal and start squares */ map->grid[y0*map->width+x0].flags |= SQ_FLAG_START; map->grid[y1*map->width+x1].flags |= SQ_FLAG_GOAL; curses_draw_map(map); i = x0; j = y0; while ((i != x1) || (j != y1)) { if (i > x1) { i--; } else if (i < x1) { i++; } else if (j > y1) { j--; } else if (j < y1) { j++; } map->grid[j*map->width+i].flags |= SQ_FLAG_ENQUEUED; curses_draw_map(map); map->grid[j*map->width+i].flags &= ~SQ_FLAG_ENQUEUED; map->grid[j*map->width+i].flags |= SQ_FLAG_VISITED; } /* finally mark the "path" */ i = x0; j = y0; while ((i != x1) || (j != y1)) { if (i > x1) { i--; } else if (i < x1) { i++; } else if (j > y1) { j--; } else if (j < y1) { j++; } map->grid[j*map->width+i].flags |= SQ_FLAG_PATH; } curses_draw_map(map); }
/* find the lowest cost path and mark it on the map */ void make_path(struct map *map, int x0, int y0, int x1, int y1) { int start, end, cost, i, index, mdistance; pq_t * pq; int edges[4]; pq = pq_create(); cost = 0; start = y0 * map->width + x0; end = y1 * map->width + x1; map->grid[start].flags |= SQ_FLAG_START; map->grid[end].flags |= SQ_FLAG_GOAL; map->grid[start].glyph = 'A'; map->grid[end].glyph = 'B'; if(map->grid[start].cost == -1 || map->grid[end].cost == -1) { map->cost = -1; return; } curses_draw_map(map); mdistance = man_distance(start, end, map); if(!pq_enqueue(pq, start, map->grid[start].cost + mdistance)) exit(EXIT_FAILURE); while(1) { if(!pq_dequeue(pq, &index, &cost)) exit(EXIT_FAILURE); if(map->grid[index].parent) /* * Kill two birds with one stone (Visited == enqueued in this case) */ map->grid[index].flags |= SQ_FLAG_VISITED; map->grid[index].flags &= ~SQ_FLAG_ENQUEUED; if(index == end) break; get_edges(index, edges, map); curses_draw_map(map); for(i = 0; i < 4; i++) { if(edges[i] != -1) { map->grid[edges[i]].parent = index; mdistance = man_distance(edges[i], end, map); if(!pq_enqueue(pq, edges[i], (cost) + map->grid[edges[i]].cost)) exit(EXIT_FAILURE); map->grid[edges[i]].flags |= SQ_FLAG_ENQUEUED; map->grid[edges[i]].flags |= SQ_FLAG_VISITED; } } } /* * This next section will fill the path array in the map struct by iterating * through the path found in the above code, which is done by following each * node's parent. * It will begin with setting the total cost of the path to the cost of the * end node, then working backwards towards the start node which has a zero cost * (which is actually appended to the total cost). * It will then begin iteration, setting the glyph and flags, then setting the * start and end node's glyphs, as these will be set with 'o' during the loop. * If the start and the end have the same coordinates, there will be a zero cost * because the only node which is appended to the total is the end, which is * the start, which has a zero cost. */ i = end; /* * Instantiate the path array */ map->path = safe_malloc(map->width * map->height * sizeof(int)); map->path_index = 0; map->cost = -1; /* * Dont include the start node's cost in the calculation */ map->grid[start].cost = 0; /* * Make sure the start node's parent is 0; * */ map->grid[start].parent = 0; map->cost = map->grid[i].cost; while(map->grid[i].parent) { /* This will miss the start node, therefore we will append it after the loop */ map->grid[i].flags |= SQ_FLAG_PATH; map->grid[i].glyph = 'o'; map->path[map->path_index++] = i; i = map->grid[i].parent; map->cost += map->grid[i].cost; } map->path[map->path_index++] = i; map->grid[start].glyph = 'A'; map->grid[end].glyph = 'B'; curses_draw_map(map); pq_destroy(pq); }