ref: be641a495dbf3c12757c1cceaec81a83406aa44c
parent: c43fe6ddcfe9b0c93572f0042267573e05361bef
author: qwx <qwx@sciops.net>
date: Tue Oct 25 22:56:37 EDT 2022
path(1): store existing results per scenario, output paths, and misc improvements - don't run all scenarios by default; properly segment the different code paths, remove redundancies - don't start graphics for non-interactive profiling mode - add start/goal/block node mouse modes to avoid conflicts with panning and selection; mb1 now only selects, mb2 pans, mb3 inserts a node given mouse mode - on-hud error display - rename opened→expanded, touched→opened, more correct terms - better default parameters handling - reduce stack size until it's actually warranted to go that high, probably still is too high
--- a/app/path/client.c
+++ b/app/path/client.c
@@ -11,9 +11,10 @@
#include "dat.h"
#include "fns.h"
-int (*mousefn)(Mouse, Point);
-int (*keyfn)(Rune);
+typedef Vertex Point;
+static int (*mousefn)(Mouse, Point);
+static int (*keyfn)(Rune);
static Keyboardctl *kc;
static Mousectl *mc;
@@ -64,18 +65,24 @@
}
void
-init(char *scen, char *res, Vertex v, int m, int a, int d)
+initgraphics(int (*kfn)(Rune), int (*mfn)(Mouse, Point))
{
- fmtinstall('P', Pfmt);
- fmtinstall('R', Rfmt);
- fmtinstall('V', Vfmt);
- fmtinstall('N', Nfmt);
- initfs();
- if(initmap(scen, res, v, m, a, d) < 0)
- sysfatal("init: %r");
+ keyfn = kfn;
+ mousefn = mfn;
initdrw();
if((kc = initkeyboard(nil)) == nil)
sysfatal("initkeyboard: %r");
if((mc = initmouse(nil, screen)) == nil)
sysfatal("initmouse: %r");
+}
+
+void
+init(char *map, Vertex dim, int m, int a, int d)
+{
+ fmtinstall('P', Pfmt);
+ fmtinstall('R', Rfmt);
+ fmtinstall('V', Vfmt);
+ fmtinstall('N', Nfmt);
+ initfs();
+ initmap(map, dim, m, a, d);
}
--- a/app/path/dat.h
+++ b/app/path/dat.h
@@ -1,14 +1,31 @@
+typedef struct Sim Sim;
+
extern Node *selected;
extern Node *start, *goal;
enum{
+ Mmodegoal,
+ Mmodestart,
+ Mmodeblock,
+ Mmodes,
+};
+extern int mousemode;
+
+enum{
Pbfs,
Pdijkstra,
Pa∗,
};
-extern int (*pathfn)(Node*, Node*);
-extern int nscen, scenid;
+struct Sim{
+ Prof;
+ VArray *path;
+ Vertex start;
+ Vertex goal;
+};
+extern int nscen, curscen;
+extern char *mapfile;
+extern VArray *sims;
extern int nodesz;
extern int showgrid;
--- a/app/path/drw.c
+++ b/app/path/drw.c
@@ -50,6 +50,21 @@
pan.y -= p.y;
}
+void
+errmsg(char *fmt, ...)
+{
+ char s[256];
+ va_list arg;
+ Point p;
+
+ va_start(arg, fmt);
+ vseprint(s, s+sizeof s, fmt, arg);
+ va_end(arg);
+ p = addpt(screen->r.min, subpt(Pt(2, viewr.max.y+2), viewΔ));
+ p.y += font->height * 2;
+ string(screen, p, col[Cgoal], ZP, font, s);
+}
+
Node *
scrselect(Point p)
{
@@ -98,6 +113,10 @@
else if(n->open)
sp = strecpy(sp, s+sizeof s, "O");
}
+ sp = seprint(sp, s+sizeof s, "; RMB sets %s",
+ mousemode == Mmodegoal ? "goal" :
+ mousemode == Mmodestart ? "start" :
+ "block");
USED(sp);
p = addpt(screen->r.min, subpt(Pt(2, viewr.max.y+2), viewΔ));
string(screen, p, col[Cfree], ZP, font, s);
@@ -104,7 +123,7 @@
if(start != nil && goal != nil){
seprint(s, s+sizeof s,
"path len=%d Δ=%.2f $=%.2f opened=%d expanded=%d updated=%d closed=%d",
- stats.steps, stats.dist, stats.cost, stats.touched, stats.opened,
+ stats.steps, stats.dist, stats.cost, stats.opened, stats.expanded,
stats.updated, stats.closed);
p.y += font->height;
string(screen, p, col[Cfree], ZP, font, s);
@@ -206,7 +225,7 @@
if(-viewΔ.y < font->height * 2)
viewΔ.y = 0;
hudr.min = addpt(screen->r.min, subpt(Pt(2, viewr.max.y+2), viewΔ));
- hudr.max = addpt(hudr.min, Pt(screen->r.max.x, font->height*2));
+ hudr.max = addpt(hudr.min, Pt(screen->r.max.x, font->height*3));
freeimage(view);
view = eallocimage(viewr, 0, DNofill);
updatedrw(1);
--- a/app/path/fns.h
+++ b/app/path/fns.h
@@ -1,18 +1,25 @@
-void init(char*, char*, Vertex, int, int, int);
+void initgraphics(int (*)(Rune), int (*)(Mouse, Point));
+void init(char*, Vertex, int, int, int);
Node* scrselect(Point);
+void errmsg(char*, ...);
void updatedrw(int);
int menter(char*, char*, int);
void evloop(void);
-void showscen(int);
-void reloadscen(void);
-void runscens(void);
-int readscen(char*, char*, Vertex*);
+void writeresults(void);
+int readresults(char*);
+int readscens(char*);
+int readmaphdr(char*, Vertex*);
+int readmap(char*);
void initfs(void);
int Vfmt(Fmt*);
int Nfmt(Fmt*);
-int initmap(char*, char*, Vertex, int, int, int);
+int trypath(Node*, Node*);
+int showscen(int);
+int reloadscen(void);
+void runallscens(void);
+int initmap(char*, Vertex, int, int, int);
void initdrw(void);
void resetdrw(void);
Vertex n2s(Node*);
-void clearmap(void);
-int setparm(int, int, int);
+
+#pragma varargck argpos errmsg 1
--- a/app/path/fs.c
+++ b/app/path/fs.c
@@ -7,41 +7,50 @@
#include "dat.h"
#include "fns.h"
+char *mapfile;
int nscen, scenid;
/* https://bitbucket.org/dharabor/pathfinding/src/gppc/gppc-2014/scenarios/ */
-typedef struct Sim Sim;
-struct Sim{
- Prof;
- Vertex start;
- Vertex goal;
+enum{
+ Nscen = 4100,
};
-static VArray *sims;
-static char *scenmap;
+VArray *sims;
-void
-showscen(int id)
+static VArray *
+parsepath(char *s, Sim *sim)
{
- Sim *sp;
+ int n;
+ u64int x;
+ char *p, *t;
+ VArray *v;
+ Vertex px;
- assert(id >= 0 && id < nscen);
- sp = sims->p;
- sp += id;
- start = p2n(sp->start);
- goal = p2n(sp->goal);
- if(pathfn(start, goal) < 0)
- fprint(2, "showscen: findpath from %N to %N: %r\n",
- start, goal);
+ n = 0;
+ v = valloc(sim->steps, sizeof(Vertex));
+ while((p = strchr(s, ',')) != nil){
+ *p = 0;
+ x = strtoull(s, &t, 10);
+ if(t == s)
+ sysfatal("parsepath: invalid node number");
+ px = V(x % gridwidth, x / gridwidth);
+ vinsert(v, (char*)&px);
+ n++;
+ s = p + 1;
+ }
+ if(n != sim->steps)
+ sysfatal("parsepath -- phase error");
+ return v;
}
-static void
+int
readresults(char *path)
{
int n;
- char *s, *arg[32];
+ char *s, *arg[9];
Biobuf *bf;
Sim *sp, *se;
+ assert(sims != nil);
if((bf = Bopen(path, OREAD)) == nil)
sysfatal("readresults: %r");
sp = sims->p;
@@ -49,77 +58,113 @@
while(sp < se){
if((s = Brdstr(bf, '\n', 1)) == nil)
sysfatal("readresults: %r");
- if((n = getfields(s, arg, nelem(arg), 1, " \t")) != 8)
- sysfatal("invalid record length %d not 8", n);
+ if((n = getfields(s, arg, nelem(arg), 1, " \t")) != nelem(arg)){
+ werrstr("invalid record length %d not %d", n, nelem(arg));
+ return -1;
+ }
sp->cost = strtod(arg[7], nil);
sp->steps = atoi(arg[2]);
- sp->touched = atoi(arg[3]);
- sp->opened = atoi(arg[4]);
+ sp->opened = atoi(arg[3]);
+ sp->expanded = atoi(arg[4]);
sp->updated = atoi(arg[5]);
sp->closed = atoi(arg[6]);
+ if(sp->steps <= 0)
+ dprint(Lognone, "path::readresults: invalid entry line %zd\n",
+ sp - (Sim *)sims->p);
+ else
+ sp->path = parsepath(arg[8], sp);
free(s);
sp++;
}
Bterm(bf);
+ if(sp - (Sim *)sims->p != nscen){
+ werrstr("results file -- phase error");
+ return -1;
+ }
+ return 0;
}
void
-runscens(void)
+writeresults(void)
{
+ int i;
Sim *sp, *se;
+ Vertex *p, *e;
- sp = sims->p;
- se = sp + sims->n;
- fprint(2, "id\tsteps\ttouched\texpanded\tupdated\topened\tcost\tdist\n");
- while(sp < se){
- start = p2n(sp->start);
- goal = p2n(sp->goal);
- if(pathfn(start, goal) < 0)
- fprint(2, "runscens: findpath from %N to %N: %r\n",
- start, goal);
- sp->Prof = stats;
- fprint(2, "%zd\t%d\t%d\t%d\t%d\t%d\t%.3f\t%.3f\n",
- sp - (Sim*)sims->p,
- stats.steps, stats.touched, stats.opened,
- stats.updated, stats.closed, stats.cost, stats.dist);
- sp++;
+ print("id\tsteps\topened\texpanded\tupdated\texpanded\tcost\tdist\n");
+ for(i=0, sp=sims->p, se=sp+sims->n; sp<se; sp++, i++){
+ print("%d\t%d\t%d\t%d\t%d\t%d\t%.3f\t%.3f\t",
+ i, sp->steps, sp->opened, sp->expanded,
+ sp->updated, sp->closed, sp->cost, sp->dist);
+ for(p=sp->path->p, e=p+sp->path->n; p<e; p++)
+ print("%s%d", p == sp->path->p ? "" : ",",
+ p->y * gridwidth + p->x);
+ print("\n");
}
}
-static int
-readscenmaphdr(Biobuf *bf, Vertex *v)
+int
+readmaphdr(char *path, Vertex *dim)
{
- int done;
+ int r, done;
char *s, *t;
+ Biobuf *bf;
+ if((bf = Bopen(path, OREAD)) == nil)
+ sysfatal("readmaphdr: %r");
done = 0;
+ r = -1;
while((s = Brdstr(bf, '\n', 1)) != nil){
t = strtok(s, " ");
if(strcmp(t, "type") == 0 || strcmp(t, "version") == 0){
;
}else if(strcmp(t, "height") == 0){
- if((t = strtok(nil, " ")) == nil)
- return -1;
- v->y = atoi(t);
+ if((t = strtok(nil, " ")) == nil){
+ werrstr("invalid height field");
+ goto end;
+ }
+ dim->y = atoi(t);
}else if(strcmp(t, "width") == 0){
- if((t = strtok(nil, " ")) == nil)
- return -1;
- v->x = atoi(t);
+ if((t = strtok(nil, " ")) == nil){
+ werrstr("invalid width field");
+ goto end;
+ }
+ dim->x = atoi(t);
}else if(strcmp(t, "map") == 0)
done = 1;
else{
werrstr("unknown verb %s", t);
- return -1;
+ goto end;
}
free(s);
+ if(done){
+ r = 0;
+ break;
+ }
+ }
+end:
+ Bterm(bf);
+ return r;
+}
+
+static int
+skiphdr(Biobuf *bf)
+{
+ int done;
+ char *s;
+
+ while((s = Brdstr(bf, '\n', 1)) != nil){
+ done = strcmp(s, "map") == 0;
+ free(s);
if(done)
return 0;
}
+ werrstr("skipheader: skipped past eof");
return -1;
}
-static int
-readscenmap(char *path, Vertex *v)
+int
+readmap(char *path)
{
char c, *s, *t;
Vertex u;
@@ -126,12 +171,8 @@
Biobuf *bf;
if((bf = Bopen(path, OREAD)) == nil)
- sysfatal("readscenmap: %r");
- if(readscenmaphdr(bf, v) < 0)
- return -1;
- if(gridwidth == 0)
- initgrid(v->x, v->y);
- cleargrid();
+ sysfatal("readmap: %r");
+ skiphdr(bf);
for(u.y=0; u.y<gridheight; u.y++){
if((s = Brdstr(bf, '\n', 1)) == nil)
return -1;
@@ -156,74 +197,22 @@
return 0;
}
-void
-reloadscen(void)
-{
- Vertex v;
-
- if(readscenmap(scenmap, &v) < 0)
- sysfatal("reloadscen: %r");
-}
-
-static int
-readscenhdr(Biobuf *bf, Vertex *v)
-{
- int done;
- char *s, *t;
-
- done = 0;
- while((s = Brdstr(bf, '\n', 1)) != nil){
- t = strtok(s, " ");
- if(strcmp(t, "type") == 0){
- ;
- }else if(strcmp(t, "height") == 0){
- if((t = strtok(nil, " ")) == nil)
- return -1;
- v->y = atoi(t);
- }else if(strcmp(t, "width") == 0){
- if((t = strtok(nil, " ")) == nil)
- return -1;
- v->x = atoi(t);
- }else if(strcmp(t, "map") == 0)
- done = 1;
- else{
- werrstr("unknown verb %s", t);
- return -1;
- }
- free(s);
- if(done)
- return 0;
- }
- return -1;
-}
-
int
-readscen(char *path, char *respath, Vertex *v)
+readscens(char *path)
{
int n;
- char *s, *arg[32];
+ char *s, *arg[9];
Biobuf *bf;
Sim sim;
- if(path == nil)
- return 0;
- doprof = 1;
- if((s = strrchr(path, '.')) == nil){
- werrstr("invalid path name");
- return -1;
- }
- *s = 0;
- scenmap = estrdup(path);
- if(readscenmap(path, v) < 0)
- return -1;
- *s = '.';
if((bf = Bopen(path, OREAD)) == nil)
sysfatal("readscen: %r");
- sims = valloc(4100, sizeof(Sim));
+ memset(&sim, 0, sizeof sim);
+ sims = valloc(Nscen, sizeof(Sim));
free(Brdstr(bf, '\n', 1)); /* "version 1\n" */
while((s = Brdstr(bf, '\n', 1)) != nil){
- if((n = getfields(s, arg, nelem(arg), 1, " \t")) != 9){
- werrstr("invalid record length %d not 9", n);
+ if((n = getfields(s, arg, nelem(arg), 1, " \t")) < nelem(arg)){
+ werrstr("invalid record length %d not %d", n, nelem(arg));
return -1;
}
sim.start.x = atoi(arg[4]);
@@ -236,12 +225,8 @@
free(s);
}
Bterm(bf);
- if(nscen != 4100)
- sysfatal("scen file -- phase error");
- if(respath != nil){
- readresults(respath);
- showscen(0);
- }
+ if(nscen != Nscen)
+ sysfatal("scenario file -- phase error");
return 0;
}
--- a/app/path/map.c
+++ b/app/path/map.c
@@ -7,8 +7,10 @@
#include "fns.h"
int movemode;
-int (*pathfn)(Node*, Node*);
+int curscen;
+static int (*pathfn)(Node*, Node*);
+
Vertex
n2s(Node *n)
{
@@ -21,17 +23,102 @@
}
int
-setparm(int mmode, int alg, int dist)
+trypath(Node *a, Node *b)
{
- switch(mmode){
+ if(a == nil || b == nil)
+ return -1;
+ dprint(Logdebug, "path::trypath: from %N to %N: ", start, goal);
+ if(pathfn(a, b) < 0){
+ dprint(Logdebug, "failed: %r\n");
+ return -1;
+ }
+ dprint(Logdebug, "success\n");
+ return 0;
+}
+
+int
+showscen(int id)
+{
+ Sim *sp;
+
+ assert(id >= 0 && id < sims->n);
+ curscen = id;
+ sp = sims->p;
+ sp += id;
+ start = p2n(sp->start);
+ goal = p2n(sp->goal);
+ if(trypath(start, goal) < 0){
+ errmsg("failed: %r");
+ return -1;
+ }
+ return 0;
+}
+
+int
+reloadscen(void)
+{
+ cleargrid();
+ if(mapfile == nil)
+ return 0;
+ if(readmap(mapfile) < 0)
+ return -1;
+ return showscen(curscen);
+}
+
+void
+savepath(Sim *sp)
+{
+ Node *n;
+ Vertex v;
+
+ if(sp->path == nil)
+ sp->path = valloc(sp->steps, sizeof(Vertex));
+ else
+ vnuke(sp->path);
+ for(n=start; n!=nil; n=n->to){
+ v = n->Vertex;
+ vinsert(sp->path, (char*)&v);
+ if(n == goal)
+ return;
+ }
+ /* FIXME: dumpcore function? */
+ fprint(2, "savepath: malformed path\n");
+ abort();
+}
+
+void
+runallscens(void)
+{
+ Sim *sp, *se;
+
+ for(sp=sims->p, se=sp+sims->n; sp<se; sp++){
+ if(showscen(sp - (Sim *)sims->p) < 0)
+ continue;
+ sp->Prof = stats;
+ savepath(sp);
+ }
+}
+
+static int
+setparm(Vertex *dim, int move, int alg, int dist)
+{
+ switch(move){
case Move8: /* wet floor */
- case Move4: movemode = mmode; break;
- default: sysfatal("setparm: unknown move mode %d", mmode);
+ case Move4: movemode = move; break;
+ case -1:
+ movemode = Move8;
+ dprint(Logdebug, "set by default: 8-direction movement\n");
+ break;
+ default: sysfatal("setparm: unknown move mode %d", move);
}
switch(alg){
case Pa∗: pathfn = a∗findpath; break;
case Pbfs: pathfn = bfsfindpath; break;
case Pdijkstra: pathfn = dijkstrafindpath; break;
+ case -1:
+ pathfn = a∗findpath;
+ dprint(Logdebug, "set by default: unmodified A∗ algorithm\n");
+ break;
default: sysfatal("setparm: unknown algo type %d", alg);
}
switch(dist){
@@ -38,28 +125,30 @@
case Deuclid: distfn = eucdist; break;
case Dmanhattan: distfn = manhdist; break;
case Doctile: distfn = octdist; break;
+ case -1:
+ distfn = octdist;
+ dprint(Logdebug, "set by default: octile distance\n");
+ break;
default: sysfatal("setparm: unknown distance function %d", dist);
}
- clearmap();
+ if(dim->x == -1)
+ dim->x = 64;
+ if(dim->y == -1)
+ dim->y = 64;
+ if(dim->x <= 0 || dim->x >= 512 || dim->y <= 0 || dim->y >= 512)
+ sysfatal("setparm: invalid map size, must be in ]0,512]");
return 0;
}
-void
-clearmap(void)
-{
- start = goal = nil;
- if(grid == nil || doprof)
- return;
- cleargrid();
-}
-
int
-initmap(char *scen, char *res, Vertex v, int m, int a, int d)
+initmap(char *map, Vertex dim, int move, int alg, int dist)
{
- setparm(m, a, d);
- if(scen == nil)
- initgrid(v.x, v.y);
- else if(readscen(scen, res, &v) < 0)
- sysfatal("readscen: %r");
+ mapfile = map;
+ setparm(&dim, move, alg, dist);
+ if(map != nil && readmaphdr(map, &dim) < 0)
+ sysfatal("initmap: %r");
+ initgrid(dim.x, dim.y);
+ if(map != nil && readmap(map) < 0)
+ sysfatal("initmap: %r");
return 0;
}
--- a/app/path/path.c
+++ b/app/path/path.c
@@ -11,17 +11,14 @@
#include "dat.h"
#include "fns.h"
-extern int (*mousefn)(Mouse, Point);
extern void dopan(Point);
extern Point pan;
-extern int (*keyfn)(Rune);
-mainstacksize = 512*1024;
+mainstacksize = 128*1024;
Node *start, *goal;
+int mousemode;
-static setgoalmode;
-
static int
grmouse(Mouse m, Point Δ)
{
@@ -28,9 +25,10 @@
static Node *old;
Node *n;
- if(m.buttons == 0)
+ if(m.buttons == 0){
+ old = nil;
return 0;
- else if((m.buttons & 7) == 2){
+ }else if((m.buttons & 7) == 2){
dopan(Δ);
updatedrw(1);
return 1;
@@ -38,26 +36,20 @@
if((n = scrselect(m.xy)) == nil || old == n)
return 0;
switch(m.buttons & 7){
- case 1:
- if(old == nil || isblocked(n) ^ isblocked(old))
- toggleblocked(n);
- break;
+ case 1: break; /* just selecting the node */
case 4:
- if(setgoalmode){
- if(start != n && !isblocked(n))
- goal = n;
- }else{
- if(goal != n && !isblocked(n))
- start = n;
+ switch(mousemode){
+ case Mmodegoal: if(n != start && !isblocked(n)) goal = n; break;
+ case Mmodestart: if(n != goal && !isblocked(n)) start = n; break;
+ case Mmodeblock:
+ if(n != start && n != goal
+ && (old == nil || isblocked(n) ^ isblocked(old)))
+ toggleblocked(n);
+ break;
}
- break;
}
old = n;
- if(start != nil && goal != nil)
- if(pathfn(start, goal) < 0){
- dprint(Logdebug, "grid::findpath: findpath from [%#p,%P] to [%#p,%P]: %r\n",
- start, n2p(start), goal, n2p(goal));
- }
+ trypath(start, goal);
return 1;
}
@@ -67,7 +59,7 @@
int n;
char buf[128];
- snprint(buf, sizeof buf, "%d", scenid);
+ snprint(buf, sizeof buf, "%d", curscen);
if(menter("Scenario id?", buf, sizeof buf) < 0){
fprint(2, "getscen: %r\n");
return -1;
@@ -76,7 +68,6 @@
fprint(2, "getscen: invalid id %s\n", buf);
return -1;
}
- scenid = n;
showscen(n);
return 0;
}
@@ -89,16 +80,13 @@
case 'q':
threadexitsall(nil);
case 'r':
- if(doprof){
- reloadscen();
- showscen(scenid);
- }else
- cleargrid();
+ reloadscen();
updatedrw(0);
break;
case ' ':
case '\n':
- setgoalmode ^= 1;
+ mousemode = (mousemode + 1) % Mmodes;
+ updatedrw(0);
break;
case 'g':
showgrid ^= 1;
@@ -106,8 +94,6 @@
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- if(!doprof)
- break;
if(setscen() >= 0)
updatedrw(0);
break;
@@ -135,7 +121,7 @@
static void
usage(void)
{
- fprint(2, "usage: %s [-D4] [-a algo] [-d dist] [-s width[,height]] [-m scen]\n", argv0);
+ fprint(2, "usage: %s [-D4p] [-a algo] [-d dist] [-s width[,height]] [-m map] [-S scen] [-r res]\n", argv0);
threadexits("usage");
}
@@ -143,15 +129,17 @@
threadmain(int argc, char **argv)
{
int w, h, a, d, m;
- char *s, *scenres, *scenmap;
+ char *s, *map, *scen, *res;
- w = 64;
- h = 64;
+ w = -1;
+ h = -1;
a = -1;
d = -1;
- m = Move8;
- scenmap = nil;
- scenres = nil;
+ m = -1;
+ doprof = 0;
+ map = nil;
+ scen = nil;
+ res = nil;
ARGBEGIN{
case 'D':
if(++debuglevel >= Logparanoid)
@@ -188,11 +176,17 @@
}
break;
case 'm':
- scenmap = EARGF(usage());
+ map = EARGF(usage());
break;
+ case 'p':
+ doprof = 1;
+ break;
case 'r':
- scenres = EARGF(usage());
+ res = EARGF(usage());
break;
+ case 'S':
+ scen = EARGF(usage());
+ break;
case 's':
w = strtol(EARGF(usage()), &s, 0);
if(w <= 0)
@@ -207,18 +201,24 @@
break;
default: usage();
}ARGEND
- if(w <= 0 || w > 512
- || h <= 0 || h > 512)
- sysfatal("invalid map size, must be in ]0,512]");
- if(d < 0)
- d = m == Move8 ? Doctile : Dmanhattan;
- if(a < 0)
- a = Pa∗;
- keyfn = grkey;
- mousefn = grmouse;
- init(scenmap, scenres, (Vertex){w,h}, m, a, d);
- if(doprof && scenres == nil)
- runscens();
+ init(map, (Vertex){w,h}, m, a, d);
+ if(scen != nil){
+ if(map == nil)
+ sysfatal("mat not run scenarios without a map");
+ readscens(scen);
+ if(doprof){
+ runallscens();
+ writeresults();
+ threadexitsall(nil);
+ }
+ if(res != nil)
+ readresults(res);
+ }
+ initgraphics(grkey, grmouse);
+ if(scen != nil){
+ showscen(0);
+ updatedrw(0);
+ }
evloop();
threadexitsall(nil);
}
--- a/path/a∗.c
+++ b/path/a∗.c
@@ -76,7 +76,7 @@
sysfatal("a∗: %r");
for(v=*vl++; v!=nil; v=*vl++){
pv = v->aux;
- stats.touched++;
+ stats.opened++;
if(v->closed)
continue;
g = pu->g + unitmovecost(u, v);
@@ -84,10 +84,10 @@
if(!v->open){
v->from = u;
v->open = 1;
- stats.opened++;
+ stats.expanded++;
pv->h = distfn(v, b);
pv->g = g;
- dprint(Logtrace, "a∗: opened [%#p,%P] h %.4f g %.4f f %.4f\n",
+ dprint(Logtrace, "a∗: expanded [%#p,%P] h %.4f g %.4f f %.4f\n",
v, n2p(v), pv->h, pv->g, pv->h + pv->g);
pv->pq = pushqueue(pv->g + pv->h, pv, &queue);
}else if(Δg > 0){
--- a/path/bfs.c
+++ b/path/bfs.c
@@ -42,10 +42,10 @@
if((vl = expand(u)) == nil)
sysfatal("bfs: %r");
for(v=*vl++; v!=nil; v=*vl++){
- stats.touched++;
+ stats.opened++;
if(v->open)
continue;
- stats.opened++;
+ stats.expanded++;
v->from = u;
vecpush(front, &v);
v->open = 1;
--- a/path/dijkstra.c
+++ b/path/dijkstra.c
@@ -79,7 +79,7 @@
sysfatal("a∗: %r");
for(v=*vl++; v!=nil; v=*vl++){
pv = v->aux;
- stats.touched++;
+ stats.opened++;
if(v->closed)
continue;
g = pu->g + unitmovecost(u, v);
@@ -88,9 +88,9 @@
if(!v->open){
v->from = u;
v->open = 1;
- stats.opened++;
+ stats.expanded++;
pv->g = g;
- dprint(Logtrace, "dijkstra: opened [%#p,%P] g %.4f\n",
+ dprint(Logtrace, "dijkstra: expanded [%#p,%P] g %.4f\n",
v, n2p(v), pv->g);
pv->pq = pushqueue(pv->g, pv, &queue);
}
--- a/path/path.h
+++ b/path/path.h
@@ -70,8 +70,8 @@
double dist;
double cost;
int steps;
- int touched;
int opened;
+ int expanded;
int updated;
int closed;
};