void dijkstra_distance_target(grid *distances, grid *target, const pos *targets, int count, int neighbors, cost_function_t cost_function, void *userdata){ grid_fill(distances, distances->x0, distances->y0, distances->width, distances->height, DBL_MAX); if(target != NULL) grid_fill(target, target->x0, target->y0, target->width, target->height, -1); queue open_set = queue_create(sizeof(pos)); for(int i = 0;i<count;++i) { grid_set(distances, targets[i].x, targets[i].y, 0.0); if(target != NULL) grid_set(target, targets[i].x, targets[i].y, i); queue_push(&open_set, targets+i); } while(!queue_empty(&open_set)) { pos cur = *(pos*)queue_front(&open_set); double curdist = grid_get(distances, cur.x, cur.y); queue_pop(&open_set); for(int i = 0;i<neighbors;++i) { pos neigh = {cur.x+offsets[i].x, cur.y+offsets[i].y}; if(!grid_contains(distances, neigh.x, neigh.y)) continue; double neighdist = grid_get(distances, neigh.x, neigh.y); double cost = cost_function(cur.x, cur.y, neigh.x, neigh.y, userdata); if(neighdist > curdist + cost) { grid_set(distances, neigh.x, neigh.y, curdist + cost); if(target != NULL) grid_set(target, neigh.x, neigh.y, grid_get(target, cur.x, cur.y)); queue_push(&open_set, &neigh); } } } queue_destroy(open_set); }
struct grid_t *init_grid_from_random() { struct grid_t *grid; int cols, rows, i, j; srandom(time(NULL)); /* TODO range */ cols = random() % 21 + 40; rows = random() % 21 + 40; grid = grid_init(rows, cols); grid_fill(grid, 0); for (i = 0;i < rows;i++) for (j = 0;j < cols;j++) grid_set(grid, i, j, random() % 2); return grid; }
static int grid_fill_lua(lua_State *L) { int top = lua_gettop(L); if(top<1) return typerror(L, 1, "grid"); if(top<2 || !lua_isnumber(L, 2)) return typerror(L, 2, "number"); if(top>2) { if(top<3 || !lua_isnumber(L, 3)) return typerror(L, 3, "number"); if(top<4 || !lua_isnumber(L, 4)) return typerror(L, 4, "number"); if(top<5 || !lua_isnumber(L, 5)) return typerror(L, 5, "number"); if(top<6 || !lua_isnumber(L, 6)) return typerror(L, 6, "number"); } grid *g = lua_touserdata(L, 1); int x = top==2?g->x0:lua_tointeger(L, 2); int y = top==2?g->y0:lua_tointeger(L, 3); int width = top==2?g->width:lua_tointeger(L, 4); int height = top==2?g->height:lua_tointeger(L, 5); double value = top==2?lua_tonumber(L, 2):lua_tonumber(L, 6); grid_fill(g, x, y, width, height, value); return 0; }
struct grid_t *init_grid_from_file(char *fname, int max_cols, \ char comment, char alive, char dead) { struct grid_t *grid; FILE *stream; int cols, rows, counter; char *line, *c; stream = fopen(fname, "r"); assert(stream != NULL); line = malloc(sizeof(char) * max_cols); cols = -1; rows = -1; counter = 0; for(;getline(&line, (size_t *) &max_cols, stream) != -1;) { if (line[0] != comment) { if (rows == -1) { rows = atoi(line); assert(rows != -1); } else if (cols == -1) { cols = atoi(line); assert(cols != -1); grid = grid_init(rows, cols); grid_fill(grid, 0); } else if (counter < rows * cols) { /* read the grid */ assert(rows != -1 && cols != -1); for (c = line;*c != '\n' && *c != EOF;c++, counter++) grid_set(grid, counter / cols, counter % cols,\ (*c == alive) ? (1) : (0)); } } } assert(rows != -1 && cols != -1 && grid != NULL); fclose(stream); return grid; }