int main(int argc, char *argv[]) { loginit(NULL); if (argc < 4) fatal("Expected 3 arguments"); parseargs(argc, argv); rng(&r); int w = strtol(argv[1], NULL, 10); int h = strtol(argv[2], NULL, 10); int d = strtol(argv[3], NULL, 10); Lvl *lvl = lvlnew(d, w, h, 0); unsigned int x0 = 2, y0 = 2; if (randstart) { x0 = rnd(1, w-2); y0 = rnd(1, h-2); } mvsinit(); do{ init(lvl); if (addwater) water(lvl); Loc loc = (Loc) { x0, y0, 0 }; Path *p = pathnew(lvl); pathbuild(lvl, p, loc); pathfree(p); morereach(lvl); closeunits(lvl); }while(closeunreach(lvl) < lvl->w * lvl->h * lvl->d * 0.40); stairs(&r, lvl, x0, y0); bool foundstart = false; for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { if (blk(lvl, x, y, 0)->tile == 'u' || blk(lvl, x, y, 0)->tile == 'U') { foundstart = true; break; } } } assert(foundstart); lvlwrite(stdout, lvl); lvlfree(lvl); return 0; }
struct path * pathcopy(struct path *o) { struct path *n, *nn; if (o == nil) return nil; lock(&pathalloc.lock); n = pathalloc.free; if (n == nil) { n = malloc(sizeof(struct path)); if (n == nil) { return nil; } } else { pathalloc.free = n->next; } unlock(&pathalloc.lock); nn = n; nn->prev = nil; while (o != nil) { memmove(nn->s, o->s, NAMEMAX); o = o->next; if (o != nil) { lock(&pathalloc.lock); nn->next = pathalloc.free; if (nn->next == nil) { nn->next = malloc(sizeof(struct path)); if (nn->next == nil) { pathfree(n); return nil; } } else { pathalloc.free = nn->next->next; } unlock(&pathalloc.lock); nn->next->prev = nn; nn = nn->next; } } nn->next = nil; return n; }
void pathfree(struct path *p) { if (p == nil) return; pathfree(p->next); lock(&pathalloc.lock); p->next = pathalloc.free; pathalloc.free = p; unlock(&pathalloc.lock); }
struct path * strtopath(struct path *p, const char *str) { struct path *path, *n; int i, j; if (str[0] == '/' || p == nil) { path = p = nil; } else { path = pathcopy(p); if (path == nil) { return nil; } for (p = path; p != nil && p->next != nil; p = p->next) ; } while (*str != 0) { for (i = 0; str[i] != 0 && str[i] != '/'; i++) ; if (i == 0) { str += 1; continue; } else if (i >= NAMEMAX) { pathfree(path); return nil; } if (str[0] == '.') { if (str[1] == '.' && i == 2) { /* Remove current and prev */ if (p == nil) { str += 2; continue; } n = p; if (p == path) { path = p->prev; } p = p->prev; if (p != nil) { p->next = nil; } lock(&pathalloc.lock); n->next = pathalloc.free; pathalloc.free = n; unlock(&pathalloc.lock); str += 2; continue; } else if (i == 1) { /* Remove current */ str += 1; continue; } } lock(&pathalloc.lock); n = pathalloc.free; if (n == nil) { n = malloc(sizeof(struct path)); if (n == nil) { pathfree(path); return nil; } } else { pathalloc.free = n->next; } unlock(&pathalloc.lock); for (j = 0; j < i; j++) n->s[j] = str[j]; n->s[j] = 0; n->next = nil; n->prev = p; if (p != nil) { p->next = n; } else { path = n; } p = n; str += i; } return path; }