X-Git-Url: https://pd.if.org/git/?p=hexagon;a=blobdiff_plain;f=astar.c;fp=astar.c;h=67889c24b0e29402054ea4aa604712e2d1c28eb1;hp=fd92bfcc8ddc24f611ff3d7b71980a119fead6c4;hb=06868ef42497f1cbc480831029f5f69b395dfdd2;hpb=c5a7aa5029146b2bcea5daae53c6aa3e5e33ed04 diff --git a/astar.c b/astar.c index fd92bfc..67889c2 100644 --- a/astar.c +++ b/astar.c @@ -17,11 +17,11 @@ #define DEBUG_ASTAR 1 #endif -static double default_metric(int a, int b) { +static double default_metric(struct HL_hex a, struct HL_hex b) { return 1.0; } -static double default_heuristic(int a, int b) { +static double default_heuristic(struct HL_hex a, struct HL_hex b) { return (double)HL_distance(a, b); } @@ -42,7 +42,7 @@ struct HL_astar *HL_astar_init(struct HL_astar *state) { state->metric = default_metric; state->heuristic = default_heuristic; - state->neighbor = HL_adjacent_hex; + state->neighbor = HL_adjhexp; return state; } @@ -91,10 +91,10 @@ void HL_astar_free(struct HL_astar *s) { } } -static struct HL_astar_hex *add_open(struct HL_astar *s, int hex) { +static struct HL_astar_hex *add_open(struct HL_astar *s, struct HL_hex hex) { struct HL_astar_hex *node; #ifdef DEBUG_ASTAR - fprintf(stderr, "add to open %d\n", hex); + fprintf(stderr, "add to open %d\n", HL_cantor(hex)); #endif if (!s || s->error) { @@ -111,7 +111,7 @@ static struct HL_astar_hex *add_open(struct HL_astar *s, int hex) { /* TODO check in open or closed */ node = malloc(sizeof *node); #ifdef DEBUG_ASTAR - fprintf(stderr, "add to open %d = %p\n", hex, node); + fprintf(stderr, "add to open %d = %p\n", HL_cantor(hex), node); #endif node->hex = hex; @@ -138,7 +138,7 @@ static struct HL_astar_hex *closehex(struct HL_astar *s, struct HL_astar_hex *h) } #ifdef DEBUG_ASTAR - fprintf(stderr, "Closing hex: (%d,%d)\n", HL_cantor_x(h->hex), HL_cantor_y(h->hex)); + fprintf(stderr, "Closing hex: (%d,%d)\n", h->hex.x, h->hex.y); #endif h->open = 0; if (h->prev) h->prev->next = h->next; @@ -152,22 +152,22 @@ static struct HL_astar_hex *closehex(struct HL_astar *s, struct HL_astar_hex *h) return h; } -struct HL_astar_hex *in_closed(struct HL_astar *s, int hex) { +struct HL_astar_hex *in_closed(struct HL_astar *s, struct HL_hex hex) { struct HL_astar_hex *h; if (!s) return 0; for (h = s->closed; h; h = h->next) { - if (h->hex == hex) return h; + if (h->hex.x == hex.x && h->hex.y == hex.y) return h; } return NULL; } -struct HL_astar_hex *in_open(struct HL_astar *s, int hex) { +struct HL_astar_hex *in_open(struct HL_astar *s, struct HL_hex hex) { struct HL_astar_hex *h; if (!s) return 0; for (h = s->open; h; h = h->next) { - if (h->hex == hex) return h; + if (h->hex.x == hex.x && h->hex.y == hex.y) return h; } return NULL; } @@ -191,7 +191,7 @@ static struct HL_astar_hex *lowrank(struct HL_astar *s) { void dump_list(char *name, struct HL_astar_hex *x) { fprintf(stderr, "%s list: ", name); for(; x; x = x->next) { - fprintf(stderr, "(%d,%d)", HL_cantor_x(x->hex), HL_cantor_y(x->hex)); + fprintf(stderr, "(%d,%d)", x->hex.x, x->hex.y); } fprintf(stderr, "\n"); } @@ -201,14 +201,15 @@ void dump_list(char *name, struct HL_astar_hex *x) { * find a path from start to end. we use A* */ int HL_findpath(struct HL_astar *s, int loops) { - int dir, y; + int dir; + struct HL_hex y; struct HL_astar_hex *node, *x, *yopen; int tent_better; double cost; s->error = 0; - if (s->start == s->goal) return 0; + if (HL_distance(s->start, s->goal) == 0) return 0; node = add_open(s, s->start); node->g = 0.0; @@ -217,9 +218,9 @@ int HL_findpath(struct HL_astar *s, int loops) { #ifdef DEBUG_ASTAR fprintf(stderr, "A* findpath: "); - fprintf(stderr, "(%d,%d)", HL_cantor_x(s->start), HL_cantor_y(s->start)); + fprintf(stderr, "(%d,%d)", s->start.x, s->start.y); fprintf(stderr, " -> "); - fprintf(stderr, "(%d,%d)", HL_cantor_x(s->goal), HL_cantor_y(s->goal)); + fprintf(stderr, "(%d,%d)", s->goal.x, s->goal.y); fprintf(stderr, "\n"); #endif @@ -233,23 +234,24 @@ int HL_findpath(struct HL_astar *s, int loops) { x = lowrank(s); #ifdef DEBUG_ASTAR fprintf(stderr, "checking lowest f hex = (%d,%d) f = %f, g = %f, h = %f\n", - HL_cantor_x(x->hex), HL_cantor_y(x->hex), + x->hex.x, x->hex.y, x->f, x->g, x->h ); #endif - if (x->hex == s->goal) { + if (HL_distance(x->hex, s->goal) == 0) { break; } closehex(s, x); - for (dir = 0; y = s->neighbor(x->hex, dir),dir<6; dir++) { - if (y == 0) continue; /* no hex in that direction */ + int n; + for (dir = 0; n = s->neighbor(x->hex, dir, &y),dir<6; dir++) { + if (n == 0) continue; /* no hex in that direction */ if (in_closed(s, y)) { continue; } #ifdef DEBUG_ASTAR fprintf(stderr, "checking dir %d, hex (%d, %d)\n", dir, - HL_cantor_x(y), HL_cantor_y(y)); + y.x, y.y); #endif cost = x->g + s->metric(x->hex, y); @@ -280,7 +282,7 @@ int HL_findpath(struct HL_astar *s, int loops) { yopen->f = yopen->g + yopen->h; #ifdef DEBUG_ASTAR fprintf(stderr, "maybe better hex = (%d,%d) f = %f, g = %f, h = %f\n", - HL_cantor_x(yopen->hex), HL_cantor_y(yopen->hex), + yopen->hex.x, yopen->hex.y, yopen->f, yopen->g, yopen->h ); #endif @@ -290,7 +292,7 @@ int HL_findpath(struct HL_astar *s, int loops) { } /* error no path ? */ - if (x->hex != s->goal) { + if (HL_distance(x->hex, s->goal) != 0) { s->error = 1; return 0; } @@ -306,12 +308,12 @@ int HL_findpath(struct HL_astar *s, int loops) { if (yopen->parent) { yopen->parent->next = yopen; } - if (yopen->hex == s->start) s->from = yopen; + if (HL_distance(yopen->hex, s->start) == 0) s->from = yopen; #ifdef DEBUG_ASTAR fprintf(stderr, "(%p %d %d,%d)", yopen, yopen->hex, - HL_cantor_x(yopen->hex), - HL_cantor_y(yopen->hex) + yopen->hex.x, + yopen->hex.y ); #endif s->pathlen++;