Skip to content

Instantly share code, notes, and snippets.

@Quackster
Last active January 19, 2018 06:34
Show Gist options
  • Save Quackster/d3fcd34120d5e78d318d0a71bce1f998 to your computer and use it in GitHub Desktop.
Save Quackster/d3fcd34120d5e78d318d0a71bce1f998 to your computer and use it in GitHub Desktop.
Pathfinder port from C# to C11
#include "stdafx.h"
#include "stdlib.h"
#include "PathfinderTest.h"
#include <limits.h>
#include <windows.h>
typedef struct coord_s {
int x;
int y;
int z;
} coord;
typedef struct node_s node;
typedef struct node_s {
node *node;
int cost;
int open;
int closed;
int x;
int y;
} node;
typedef struct pathfinder_s {
node **map;
node **open_list;
node *current;
node *new_mode;
} pathfinder;
pathfinder *make_path_reversed(coord, coord);
int distance_squared(int first_x, int first_y, int point_x, int point_y) {
int dx = first_x - point_x;
int dy = first_y - point_y;
return (dx * dx) + (dy * dy);
}
coord DIAGONAL_MOVE_POINTS[] = {
{ 0, -1, 0 },
{ 0, 1, 0 },
{ 1, 0, 0 },
{ -1, 0, 0 },
{ 1, -1, 0 },
{ -1, 1, 0 },
{ 1, 1, 0 },
{ -1, -1, 0 }
};
int get_address(int x, int y, int map_size_y) {
return x * map_size_y + y;
}
node *create_node() {
node *current = malloc(sizeof(node));
current->cost = INT_MAX;
current->open = 0;
current->closed = 0;
current->x = 0;
current->y = 0;
current->node = NULL;
return current;
}
void start_pathfinder_test() {
coord from;
from.x = 1;
from.y = 1;
coord to;
to.x = 5;
to.y = 9;
int map_size_x = 20;
int map_size_y = 20;
pathfinder *pathfinder = make_path_reversed(from, to, map_size_x, map_size_y);
if (pathfinder->new_mode != NULL) {
while (pathfinder->new_mode->node != NULL) {
node *current_node = pathfinder->new_mode;
int x = pathfinder->new_mode->x;
int y = pathfinder->new_mode->y;
printf("Next X: %d and Y: %d\n", x, y);
pathfinder->new_mode = pathfinder->new_mode->node;
}
for (int y = 0; y < map_size_y; y++) {
for (int x = 0; x < map_size_x; x++) {
node *node = pathfinder->map[get_address(x, y, map_size_y)];
if (node != NULL) {
free(node);
pathfinder->map[get_address(x, y, map_size_y)] = NULL;
}
}
}
free(pathfinder->map);
free(pathfinder->open_list);
free(pathfinder);
}
}
int is_valid_tile(coord from, coord to) {
// Don't use negative coordinates
if (from.x < 0 || from.y < 0 || to.x < 0 || to.y < 0) {
return 0; // 0 for false
}
// TODO: Add your checking here
// The "to" variable is the tile around the "from" variable.
return 1; // 1 for true
}
pathfinder *make_path_reversed(coord from, coord to, int map_size_x, int map_size_y) {
int map_size = map_size_x * map_size_y;
pathfinder *p = malloc(sizeof(pathfinder));
p->map = malloc(sizeof(node) * map_size);
p->open_list = malloc(sizeof(node) * map_size);
node **adjust_list = p->open_list;
memset(p->map, (int)NULL, sizeof(node) * map_size);
memset(p->open_list, (int)NULL, sizeof(node) * map_size);
p->current = create_node();
p->current->x = from.x;
p->current->y = from.y;
coord tmp;
int cost = 0;
int diff = 0;
p->map[get_address(p->current->x, p->current->y, map_size_y)] = p->current;
p->open_list[0] = p->current;
int list_size = 1;
while (adjust_list[0] != NULL) {
p->current = adjust_list[0];
p->current->closed = 1;
adjust_list++;
list_size--;
for (int i = 0; i < 8; i++) {
tmp.x = p->current->x + DIAGONAL_MOVE_POINTS[i].x;
tmp.y = p->current->y + DIAGONAL_MOVE_POINTS[i].y;
int isFinalMove = (tmp.x == to.x && tmp.y == to.y);
coord c;
c.x = p->current->x;
c.y = p->current->y;
if (is_valid_tile(c, tmp)) {
int array_index = get_address(tmp.x, tmp.y, map_size_y);
if (p->map[array_index] == NULL) {
p->new_mode = create_node();
p->new_mode->x = tmp.x;
p->new_mode->y = tmp.y;
p->map[array_index] = p->new_mode;
}
else {
p->new_mode = p->map[array_index];
}
if (!p->new_mode->closed) {
diff = 0;
if (p->current->x != p->new_mode->x) {
diff += 1;
}
if (p->current->y != p->new_mode->y) {
diff += 1;
}
cost = p->current->cost + diff + distance_squared(p->new_mode->x, p->new_mode->y, to.x, to.y);
if (cost < p->new_mode->cost) {
p->new_mode->cost = cost;
p->new_mode->node = p->current;
}
if (!p->new_mode->open) {
if (p->new_mode->x == to.x && p->new_mode->y == to.y) {
p->new_mode->node = p->current;
return p;
}
p->new_mode->open = 1;
adjust_list[list_size++] = p->new_mode;
}
}
}
}
}
return p;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment