Merge branch 'old-astar' into pathfind-test
This commit is contained in:
commit
fc0c658646
3 changed files with 93 additions and 17 deletions
|
@ -58,6 +58,15 @@ static struct as_frompath **fromhead = (struct as_frompath **)0;
|
||||||
|
|
||||||
static int as_cachepath_on = 0; /* Default to off */
|
static int as_cachepath_on = 0; /* Default to off */
|
||||||
|
|
||||||
|
#ifdef AS_STATS
|
||||||
|
unsigned as_cache_tries, as_cache_hits;
|
||||||
|
#define as_cache_try() ((void)as_cache_tries++)
|
||||||
|
#define as_cache_hit() ((void)as_cache_hits++)
|
||||||
|
#else
|
||||||
|
#define as_cache_try() ((void)0)
|
||||||
|
#define as_cache_hit() ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
as_enable_cachepath(void)
|
as_enable_cachepath(void)
|
||||||
{
|
{
|
||||||
|
@ -142,6 +151,13 @@ as_clear_cachepath(void)
|
||||||
struct as_frompath *from, *from2;
|
struct as_frompath *from, *from2;
|
||||||
struct as_topath *to, *to2;
|
struct as_topath *to, *to2;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
#ifdef AS_STATS
|
||||||
|
size_t index_sz = 0;
|
||||||
|
unsigned index_nb = 0, paths_nb = 0, paths = 0;
|
||||||
|
#define stats_index(sz) ((void)(index_sz += (sz), index_nb++))
|
||||||
|
#else
|
||||||
|
#define stats_index(sz) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Cache not used yet :) */
|
/* Cache not used yet :) */
|
||||||
if (fromhead == NULL)
|
if (fromhead == NULL)
|
||||||
|
@ -153,22 +169,43 @@ as_clear_cachepath(void)
|
||||||
for (to = from->tolist[i]; to; to = to2) {
|
for (to = from->tolist[i]; to; to = to2) {
|
||||||
to2 = to->next;
|
to2 = to->next;
|
||||||
/* Free this path */
|
/* Free this path */
|
||||||
|
#ifdef AS_STATS
|
||||||
|
{
|
||||||
|
struct as_path *pp;
|
||||||
|
for (pp = to->path; pp; pp = pp->next)
|
||||||
|
paths_nb++;
|
||||||
|
paths++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
as_free_path(to->path);
|
as_free_path(to->path);
|
||||||
/* Free this node */
|
/* Free this node */
|
||||||
free(to);
|
free(to);
|
||||||
|
stats_index(sizeof(*to));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Now, free the list of lists */
|
/* Now, free the list of lists */
|
||||||
free(from->tolist);
|
free(from->tolist);
|
||||||
|
stats_index(WORLD_Y * sizeof(*from->tolist));
|
||||||
/* Save the next pointer */
|
/* Save the next pointer */
|
||||||
from2 = from->next;
|
from2 = from->next;
|
||||||
/* now, free this from node */
|
/* now, free this from node */
|
||||||
free(from);
|
free(from);
|
||||||
|
stats_index(sizeof(*from));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Note we don't free the fromhead here, we just zero it. That way,
|
/* Note we don't free the fromhead here, we just zero it. That way,
|
||||||
we can use it next time without mallocing int */
|
we can use it next time without mallocing int */
|
||||||
memset(fromhead, 0, (sizeof(struct as_frompath *) * WORLD_Y));
|
memset(fromhead, 0, (sizeof(struct as_frompath *) * WORLD_Y));
|
||||||
|
stats_index(WORLD_Y * sizeof(*fromhead));
|
||||||
|
#ifdef AS_STATS
|
||||||
|
fprintf(stderr, "as_cache %u searches, %u hits, %u entries,"
|
||||||
|
" index %zu bytes %u blocks, paths %zu bytes %u blocks\n",
|
||||||
|
as_cache_tries, as_cache_hits,
|
||||||
|
paths,
|
||||||
|
index_sz, index_nb,
|
||||||
|
paths_nb * sizeof(struct as_path), paths_nb);
|
||||||
|
as_cache_hits = as_cache_tries = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct as_path *
|
struct as_path *
|
||||||
|
@ -177,6 +214,7 @@ as_find_cachepath(coord fx, coord fy, coord tx, coord ty)
|
||||||
struct as_frompath *from;
|
struct as_frompath *from;
|
||||||
struct as_topath *to;
|
struct as_topath *to;
|
||||||
|
|
||||||
|
as_cache_try();
|
||||||
/* Is the cache on? if not, return NULL */
|
/* Is the cache on? if not, return NULL */
|
||||||
if (as_cachepath_on == 0)
|
if (as_cachepath_on == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -189,10 +227,12 @@ as_find_cachepath(coord fx, coord fy, coord tx, coord ty)
|
||||||
for (from = fromhead[fy]; from; from = from->next) {
|
for (from = fromhead[fy]; from; from = from->next) {
|
||||||
if (from->x == fx) {
|
if (from->x == fx) {
|
||||||
for (to = from->tolist[ty]; to; to = to->next) {
|
for (to = from->tolist[ty]; to; to = to->next) {
|
||||||
if (to->x == tx)
|
if (to->x == tx) {
|
||||||
|
as_cache_hit();
|
||||||
return to->path;
|
return to->path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,11 @@ as_stats(struct as_data *adp, FILE * fp)
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
int total_q;
|
int total_q;
|
||||||
|
int total_p;
|
||||||
int total_h;
|
int total_h;
|
||||||
|
size_t other;
|
||||||
struct as_queue *qp;
|
struct as_queue *qp;
|
||||||
|
struct as_path *pp;
|
||||||
struct as_hash *hp;
|
struct as_hash *hp;
|
||||||
|
|
||||||
fprintf(fp, "Statistics:\n");
|
fprintf(fp, "Statistics:\n");
|
||||||
|
@ -52,6 +55,10 @@ as_stats(struct as_data *adp, FILE * fp)
|
||||||
i++;
|
i++;
|
||||||
fprintf(fp, "\tsubsumed:\t%d\n", i);
|
fprintf(fp, "\tsubsumed:\t%d\n", i);
|
||||||
total_q += i;
|
total_q += i;
|
||||||
|
for (i = 0, pp = adp->path; pp; pp = pp->next)
|
||||||
|
i++;
|
||||||
|
total_p = i;
|
||||||
|
fprintf(fp, "path length: %d\n", total_p);
|
||||||
fprintf(fp, "hash table statistics (size %d):\n", adp->hashsize);
|
fprintf(fp, "hash table statistics (size %d):\n", adp->hashsize);
|
||||||
for (i = 0; i < adp->hashsize; i++) {
|
for (i = 0; i < adp->hashsize; i++) {
|
||||||
for (j = 0, hp = adp->hashtab[i]; hp; hp = hp->next)
|
for (j = 0, hp = adp->hashtab[i]; hp; hp = hp->next)
|
||||||
|
@ -64,10 +71,18 @@ as_stats(struct as_data *adp, FILE * fp)
|
||||||
fprintf(fp, "\tqueues\t%d\n",
|
fprintf(fp, "\tqueues\t%d\n",
|
||||||
(int)(total_q * sizeof(struct as_queue)));
|
(int)(total_q * sizeof(struct as_queue)));
|
||||||
fprintf(fp, "\tnodes\t%d\n", (int)(total_q * sizeof(struct as_node)));
|
fprintf(fp, "\tnodes\t%d\n", (int)(total_q * sizeof(struct as_node)));
|
||||||
|
fprintf(fp, "\tpath\t%d\n", (int)(total_p * sizeof(struct as_path)));
|
||||||
fprintf(fp, "\thash ents\t%d\n",
|
fprintf(fp, "\thash ents\t%d\n",
|
||||||
(int)(total_h * sizeof(struct as_hash)));
|
(int)(total_h * sizeof(struct as_hash)));
|
||||||
|
other = sizeof(struct as_data);
|
||||||
|
other += adp->maxneighbors * sizeof(struct as_coord);
|
||||||
|
other += (adp->maxneighbors + 1) * sizeof(struct as_node *);
|
||||||
|
other += adp->hashsize * sizeof(struct as_hash *);
|
||||||
|
fprintf(fp, "\tother\t%d\n", (int)other);
|
||||||
fprintf(fp, "\ttotal\t%d\n",
|
fprintf(fp, "\ttotal\t%d\n",
|
||||||
(int)(total_q * sizeof(struct as_queue) +
|
(int)(total_q * sizeof(struct as_queue) +
|
||||||
total_q * sizeof(struct as_node) +
|
total_q * sizeof(struct as_node) +
|
||||||
total_h * sizeof(struct as_hash)));
|
total_p * sizeof(struct as_path) +
|
||||||
|
total_h * sizeof(struct as_hash) +
|
||||||
|
other));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
* ---
|
* ---
|
||||||
*
|
*
|
||||||
* path.c: Empire/A* Interface code.
|
* path.c: Empire/A* Interface code.
|
||||||
* Define AS_STATS for A* statistics.
|
|
||||||
*
|
*
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Phil Lapsley, 1991
|
* Phil Lapsley, 1991
|
||||||
|
@ -34,6 +33,18 @@
|
||||||
* Steve McClure, 1997
|
* Steve McClure, 1997
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define AS_STATS for A* statistics on stderr.
|
||||||
|
*
|
||||||
|
* Define AS_NO_PATH_CACHE to disable the path cache. The path cache
|
||||||
|
* saves a lot of work, but uses lots of memory. It should be a
|
||||||
|
* significant net win, unless you run out of memory.
|
||||||
|
*
|
||||||
|
* Define AS_NO_NEIGHBOR_CACHE to disable the neighbor cache. The
|
||||||
|
* neighbor cache trades a modest amount of memory to save a bit of
|
||||||
|
* work. In its current form, it doesn't really make a difference.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -50,8 +61,6 @@
|
||||||
#define BP_NEIGHBORS 6 /* max number of neighbors */
|
#define BP_NEIGHBORS 6 /* max number of neighbors */
|
||||||
|
|
||||||
struct bestp {
|
struct bestp {
|
||||||
int sctcache_hits;
|
|
||||||
int sctcache_misses;
|
|
||||||
int bp_mobtype;
|
int bp_mobtype;
|
||||||
struct as_data *adp;
|
struct as_data *adp;
|
||||||
};
|
};
|
||||||
|
@ -81,8 +90,10 @@ bp_init(void)
|
||||||
if (bp->adp == NULL)
|
if (bp->adp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#ifndef AS_NO_NEIGHBOR_CACHE
|
||||||
if (neighsects == NULL)
|
if (neighsects == NULL)
|
||||||
neighsects = calloc(WORLD_SZ() * 6, sizeof(struct sctstr *));
|
neighsects = calloc(WORLD_SZ() * 6, sizeof(struct sctstr *));
|
||||||
|
#endif
|
||||||
|
|
||||||
return bp;
|
return bp;
|
||||||
}
|
}
|
||||||
|
@ -99,11 +110,16 @@ best_path(struct sctstr *from, struct sctstr *to, char *path, int mob_type)
|
||||||
static struct bestp *mybestpath;
|
static struct bestp *mybestpath;
|
||||||
struct as_data *adp;
|
struct as_data *adp;
|
||||||
struct as_path *ap;
|
struct as_path *ap;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (!mybestpath)
|
if (!mybestpath)
|
||||||
mybestpath = bp_init();
|
mybestpath = bp_init();
|
||||||
adp = mybestpath->adp;
|
adp = mybestpath->adp;
|
||||||
|
#ifdef AS_NO_PATH_CACHE
|
||||||
|
ap = NULL;
|
||||||
|
#else
|
||||||
ap = as_find_cachepath(from->sct_x, from->sct_y, to->sct_x, to->sct_y);
|
ap = as_find_cachepath(from->sct_x, from->sct_y, to->sct_x, to->sct_y);
|
||||||
|
#endif
|
||||||
if (ap == NULL) {
|
if (ap == NULL) {
|
||||||
adp->from.x = from->sct_x;
|
adp->from.x = from->sct_x;
|
||||||
adp->from.y = from->sct_y;
|
adp->from.y = from->sct_y;
|
||||||
|
@ -111,22 +127,21 @@ best_path(struct sctstr *from, struct sctstr *to, char *path, int mob_type)
|
||||||
adp->to.y = to->sct_y;
|
adp->to.y = to->sct_y;
|
||||||
mybestpath->bp_mobtype = mob_type;
|
mybestpath->bp_mobtype = mob_type;
|
||||||
|
|
||||||
if (as_search(adp) < 0)
|
res = as_search(adp);
|
||||||
|
#ifdef AS_STATS
|
||||||
|
as_stats(adp, stderr);
|
||||||
|
#ifndef AS_NO_NEIGHBOR_CACHE
|
||||||
|
fprintf(stderr, "neighbor cache %zu bytes\n",
|
||||||
|
WORLD_SZ() * 6 * sizeof(struct sctstr *));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
if (res < 0)
|
||||||
return -1;
|
return -1;
|
||||||
ap = adp->path;
|
ap = adp->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bp_path(ap, path) < 0)
|
if (bp_path(ap, path) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#ifdef AS_STATS
|
|
||||||
as_stats(adp, stderr);
|
|
||||||
#endif /* AS_STATS */
|
|
||||||
#ifdef BP_STATS
|
|
||||||
fprintf(stderr, "best path %s\n", path);
|
|
||||||
fprintf(stderr, "cache hits/misses: %d/%d\n",
|
|
||||||
bp->sctcache_hits, bp->sctcache_misses);
|
|
||||||
#endif /* BP_STATS */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,8 +226,8 @@ bp_neighbors(struct as_coord c, struct as_coord *cp, void *pp)
|
||||||
*ssp = sp;
|
*ssp = sp;
|
||||||
} else {
|
} else {
|
||||||
sp = *ssp;
|
sp = *ssp;
|
||||||
sx = XNORM(sp->sct_x);
|
sx = sp->sct_x;
|
||||||
sy = YNORM(sp->sct_y);
|
sy = sp->sct_y;
|
||||||
}
|
}
|
||||||
/* No need to calculate cost each time, just make sure we can
|
/* No need to calculate cost each time, just make sure we can
|
||||||
move through it. We calculate it later. */
|
move through it. We calculate it later. */
|
||||||
|
@ -281,19 +296,25 @@ bp_coord_hash(struct as_coord c)
|
||||||
void
|
void
|
||||||
bp_enable_cachepath(void)
|
bp_enable_cachepath(void)
|
||||||
{
|
{
|
||||||
|
#ifndef AS_NO_PATH_CACHE
|
||||||
as_enable_cachepath();
|
as_enable_cachepath();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bp_disable_cachepath(void)
|
bp_disable_cachepath(void)
|
||||||
{
|
{
|
||||||
|
#ifndef AS_NO_PATH_CACHE
|
||||||
as_disable_cachepath();
|
as_disable_cachepath();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bp_clear_cachepath(void)
|
bp_clear_cachepath(void)
|
||||||
{
|
{
|
||||||
|
#ifndef AS_NO_PATH_CACHE
|
||||||
as_clear_cachepath();
|
as_clear_cachepath();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue