7 static int dirlist[] = { Up, Down, Left, Right, Up, Down, Left, Right, };
27 validpush(Point g, Step *s, Point *t)
35 m = dir2point(s->dir);
37 // first test for Cargo next to us (in direction dir)
40 if (!ptinrect(g, Rpt(Pt(0,0), level.max)))
42 switch (level.board[g.x][g.y]) {
49 // then test for enough free space for us _and_ Cargo
50 for (i=0; i < s->count; i++) {
52 if (!ptinrect(g, Rpt(Pt(0,0), level.max)))
54 switch (level.board[g.x][g.y]) {
67 isvalid(Point s, Route* r, int (*isallowed)(Point, Step*, Point*))
76 for (p = r->step; p < r->step + r->nstep; p++)
77 if (!isallowed(m, p, &m))
87 w = mallocz(sizeof *w, 1);
89 sysfatal("cannot allocate walk");
98 if (w == nil || w->route == nil)
101 for (p=w->route; p < w->route + w->nroute; p++)
119 addroute(Walk *w, Route *r)
121 if (w == nil || r == nil)
124 if (w->beyond < w->nroute+1) {
125 w->beyond = w->nroute+1;
126 w->route = realloc(w->route, sizeof(Route*)*w->beyond);
129 sysfatal("cannot allocate route in addroute");
130 w->route[w->nroute] = r;
144 extend(Route *rr, int dir, int count, Point dest)
148 r = mallocz(sizeof *r, 1);
150 sysfatal("cannot allocate route in extend");
156 r->nstep += rr->nstep;
158 r->step = malloc(sizeof(Step)*r->nstep);
160 sysfatal("cannot allocate step in extend");
163 memmove(r->step, rr->step, sizeof(Step)*rr->nstep);
165 r->step[r->nstep-1].dir = dir;
166 r->step[r->nstep-1].count = count;
174 if (r != nil && r->nstep > 0)
175 return &r->step[r->nstep-1];
180 startwithdirfromroute(Route *r, int* dl, int n)
185 if (r == nil || dl == nil)
189 if (s == nil || s->count == 0)
192 for (p=dl; p < dl + n; p++)
199 bfstrydir(Route *r, int dir, Visited *v)
210 if (ptinrect(n, Rpt(Pt(0,0), level.max)) && v->board[n.x][n.y] == 0) {
211 v->board[n.x][n.y] = 1;
212 switch (level.board[n.x][n.y]) {
215 return extend(r, dir, 1, n);
222 bfs(Point src, Point dst, Visited *v)
224 Walk *cur, *new, *tmp;
226 int progress, *dirs, *dirp;
234 v->board[src.x][src.y] = 1;
235 r = extend(nil, 0, 0, src);
236 if (eqpt(src, dst)) {
245 for (p=cur->route; p < cur->route + cur->nroute; p++) {
246 dirs = startwithdirfromroute(*p, dirlist, ndir);
247 for (dirp=dirs; dirp < dirs + ndir; dirp++) {
248 r = bfstrydir(*p, *dirp, v);
272 findroute(Point src, Point dst)
277 memset(&v, 0, sizeof(Visited));
278 r = bfs(src, dst, &v);