Beispiel #1
0
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);
}
Beispiel #2
0
void grid_assign_grid(grid *g1, grid *g2) {
    int x0 = clamp(g2->x0, g1->x0, g1->x0 + g1->width);
    int y0 = clamp(g2->y0, g1->y0, g1->y0 + g1->height);
    int x1 = clamp(g2->x0 + g2->width, g1->x0, g1->x0 + g1->width);
    int y1 = clamp(g2->y0 + g2->height, g1->y0, g1->y0 + g1->height);
    for(int x = x0;x<x1;++x)
        for(int y = y0;y<y1;++y)
            grid_set(g1, x, y, grid_get(g2, x, y));
}
Beispiel #3
0
void grid_mul_number(grid *g1, double value) {
    int x0 = g1->x0;
    int y0 = g1->y0;
    int x1 = g1->x0 + g1->width;
    int y1 = g1->y0 + g1->height;
    for(int x = x0;x<x1;++x)
        for(int y = y0;y<y1;++y)
            grid_set(g1, x, y, grid_get(g1, x, y)*value);
}
Beispiel #4
0
void grid_step(grid *g1, double threshold) {
    int x0 = g1->x0;
    int y0 = g1->y0;
    int x1 = g1->x0 + g1->width;
    int y1 = g1->y0 + g1->height;
    for(int x = x0;x<x1;++x)
        for(int y = y0;y<y1;++y)
            grid_set(g1, x, y, grid_get(g1, x, y)>threshold?1.0:0.0);
}
Beispiel #5
0
void grid_clamp(grid *g1, double low, double high) {
    int x0 = g1->x0;
    int y0 = g1->y0;
    int x1 = g1->x0 + g1->width;
    int y1 = g1->y0 + g1->height;
    for(int x = x0;x<x1;++x)
        for(int y = y0;y<y1;++y)
            grid_set(g1, x, y, clampd(grid_get(g1, x, y), low, high));
}
Beispiel #6
0
// Advance a specified cell using the rules of Game of Life.
static void advance_cell(struct grid *in, struct grid *out, int row, int col)
{
    // Count alive neighbors.
    int count = 0;
    if (ALIVE == grid_get(in, row - 1, col - 1)) count += 1;
    if (ALIVE == grid_get(in, row - 1, col    )) count += 1;
    if (ALIVE == grid_get(in, row - 1, col + 1)) count += 1;
    if (ALIVE == grid_get(in, row    , col - 1)) count += 1;
    if (ALIVE == grid_get(in, row    , col + 1)) count += 1;
    if (ALIVE == grid_get(in, row + 1, col - 1)) count += 1;
    if (ALIVE == grid_get(in, row + 1, col    )) count += 1;
    if (ALIVE == grid_get(in, row + 1, col + 1)) count += 1;

    // Apply the rules (rule source: Wikipedia).

    // Copy cell from input to output.
    grid_set(out, row, col, grid_get(in, row, col));

    // Rule 1: Any live cell with fewer than two live neighbours dies, as if caused by under-population.
    if (ALIVE == grid_get(in, row, col) && count < 2)
    {
        grid_set(out, row, col, EMPTY);
    }

    // Rule 2: Any live cell with two or three live neighbours lives on to the next generation.
    if (ALIVE == grid_get(in, row, col) && 2 <= count && count <= 3)
    {
        grid_set(out, row, col, ALIVE);
    }

    // Rule 3: Any live cell with more than three live neighbours dies, as if by overcrowding.
    if (ALIVE == grid_get(in, row, col) && count > 3)
    {
        grid_set(out, row, col, EMPTY);
    }

    // Rule 4: Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
    if (EMPTY == grid_get(in, row, col) && count == 3)
    {
        grid_set(out, row, col, ALIVE);
    }
}
Beispiel #7
0
// Randomize the state of all cells.
static void randomize_grid(struct grid *grid)
{
    int stride = grid_stride(grid);
    for (int col = 0; col < grid->width; ++col)
    {
        for (int row = 0; row < grid->height; ++row)
        {
            grid_set(grid, row, col, rand() % 2);
        }
    }
}
Beispiel #8
0
/**
 * Randomly place bombs on a grid.
 *
 * @param grid Grid to place bombs on
 * @param bombs Number of bombs to place
 */
void grid_add_bombs(grid_t *grid, unsigned int bombs) {
	int x, y;
	while (bombs != 0) {
		do {
			x = (random() % grid->width) + 1;
			y = (random() % grid->height) + 1;
		} while (square_is_bomb(*cell_at(x, y)));

		grid_set(grid, x, y, SQUARE_BOMB);
		bombs--;
	}
}
Beispiel #9
0
static int grid_set_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<3 || !lua_isnumber(L, 3)) return typerror(L, 3, "number");
    if(top<4 || !lua_isnumber(L, 4)) return typerror(L, 4, "number");
    grid *g = lua_touserdata(L, 1);
    int x = lua_tointeger(L, 2);
    int y = lua_tointeger(L, 3);
    double value = lua_tonumber(L, 4);
    grid_set(g, x, y, value);
    return 0;
}
Beispiel #10
0
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;
}
Beispiel #11
0
void mpi_get_row(struct grid *grid, int col, int rank, int tag, int pos) {
    int size = grid->height;
    int column_cells[size];

    for(int i = 0; i < size; i++) {
        column_cells[i] = grid_get(grid, i, col-1);
    }
    
    MPI_Request request;
    MPI_Status status;
    
    MPI_Isend(column_cells, size, MPI_UNSIGNED_CHAR, pos, rank, MPI_COMM_WORLD, &request);

    MPI_Irecv(column_cells, size, MPI_UNSIGNED_CHAR, pos, tag, MPI_COMM_WORLD, &request);
    MPI_Wait(&request, &status);
    
    for(int i = 0; i < size; i++) {
        grid_set(grid, i, col, column_cells[i]);
    }   
}
Beispiel #12
0
void grid_dilate(grid *g1) {
    grid tmp = grid_clone(g1);
    int x0 = g1->x0;
    int y0 = g1->y0;
    int x1 = g1->x0 + g1->width;
    int y1 = g1->y0 + g1->height;
    for(int x = x0;x<x1;++x) {
        for(int y = y0;y<y1;++y) {
            double value = 0.0;
            for(int xoffset = -1;xoffset<=1;++xoffset) {
                for(int yoffset = -1;yoffset<=1;++yoffset) {
                    int xn = x + xoffset;
                    int yn = y + yoffset;
                    if(grid_contains(&tmp, xn, yn) && grid_get(&tmp, xn, yn) != 0)
                        value = 1.0;
                }
            }
            grid_set(g1, x, y, value);
        }
    }
    grid_destroy(tmp);
}
Beispiel #13
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;
}
Beispiel #14
0
// Print the global grid to stdout from rank 0.
void gol_print(int height, int width)
{
    // TODO This function only works sequentially (one process).  Need
    // to communicate remote cells to rank 0.
    int rank = 0, num_procs = 0;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num_procs);


    int *grid_sizes, *offset;
    if(rank == 0) {
        grid_sizes = calloc(num_procs, sizeof(int));
        offset = calloc(num_procs, sizeof(int));
    }

    int grid_length = grids[0]->height * grids[0]->width;
    MPI_Gather(&grid_length, 1, MPI_INT, grid_sizes, 1, MPI_INT, 0, MPI_COMM_WORLD);

    char grid_cells[grids[0]->height * grids[0]->width];
    char old_cells[grids[1]->height * grids[1]->width];

    int index = 0;
    for(int row = 0; row < grids[0]->height; row++) {
        for(int col = 0; col < grids[0]->width; col++) {
            grid_cells[index] = grid_get(grids[0], row, col);
            old_cells[index] = grid_get(grids[1], row, col);
            index++;
        }
    }

    char *whole_grids_cells[2];
    struct grid *whole_grids[2];

    if(rank == 0) {
        whole_grids_cells[cur_grid] = calloc(height*width, sizeof(char));
        whole_grids_cells[1-cur_grid] = calloc(height*width, sizeof(char));

        whole_grids[0] = new_grid(height, width);
        whole_grids[1] = new_grid(height, width);

        offset[0] = 0;
        for(int i = 1; i < num_procs; i++) {
            offset[i] = grid_sizes[i-1] + offset[i-1];
        }
    }

    MPI_Gatherv(grid_cells, grid_length, MPI_CHAR, whole_grids_cells[cur_grid], grid_sizes, offset, MPI_CHAR, 0, MPI_COMM_WORLD);
    MPI_Gatherv(old_cells, grid_length, MPI_CHAR, whole_grids_cells[1-cur_grid], grid_sizes, offset, MPI_CHAR, 0, MPI_COMM_WORLD);

    if(rank == 0) {
        index = 0;
        for(int row = 0; row < whole_grids[0]->height; row++) {
            for(int col = 0; col < whole_grids[1]->width; col++) {
                grid_set(whole_grids[0], row, col, whole_grids_cells[cur_grid][index]);
                grid_set(whole_grids[1], row, col, whole_grids_cells[1-cur_grid][index]);
                index++;
            }
        }

        struct grid *grid = whole_grids[cur_grid];
        struct grid *old = whole_grids[1-cur_grid];

        for (int row = 0; row < grid->height; ++row)
        {
            for (int col = 0; col < grid->width; ++col)
            {
                if (ALIVE == grid_get(grid, row, col))
                {
                    // Live cell.
                    printf("o ");
                }
                else if (ALIVE == grid_get(old, row, col))
                {
                    // Dying cell (empty now but alive in the previous generation).
                    printf("+ ");
                }
                else
                {
                    // Dead cell.
                    printf(". ");
                }
            }
            printf("\n");
        }
        free(grid_sizes);
        free(offset);
        free(whole_grids_cells[0]);
        free(whole_grids_cells[1]);
    }
}
Beispiel #15
0
thing_th *Set(thing_th *grid, const char *kw, thing_th *val) {
    if(!grid || th_kind(grid)!=grid_k)
        return NULL;
    return grid_set((grid_th *)grid, kw, val);
}