예제 #1
0
파일: grid.c 프로젝트: progschj/TLDR
static int grid_get_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");
    grid *g = lua_touserdata(L, 1);
    int x = lua_tointeger(L, 2);
    int y = lua_tointeger(L, 3);
    lua_pushnumber(L, grid_get(g, x, y));
    return 1;
}
예제 #2
0
int grid_neighbors() {
	int x, y;
	grid_get(&x, &y);
	
	int n = -1;
	for (int dx = -1; dx <= 1; ++dx) {
		for (int dy = -1; dy <= 1; ++dy) {
			if (x+dx >= 0 && x+dx < grid_width &&
				y+dy >= 0 && y+dy < grid_height)
			{
				++n;
			}
		}
	}
	
	return n;
}
예제 #3
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]);
    }   
}
예제 #4
0
void kernel(int x, int y, int z, grid3d_real g,
            REAL ce, REAL cw, REAL cn, REAL cs, REAL ct, REAL cb, REAL cc)
{
    int nx, ny, nz;
    nx = grid_dimx(g);
    ny = grid_dimy(g);
    nz = grid_dimz(g);

    REAL c, w, e, n, s, b, t;
    c = grid_get(g, 0, 0, 0);
    w = (x == 0)    ? c : grid_get(g, -1, 0, 0);
    e = (x == nx-1) ? c : grid_get(g, 1, 0, 0);
    n = (y == 0)    ? c : grid_get(g, 0, -1, 0);
    s = (y == ny-1) ? c : grid_get(g, 0, 1, 0);
    b = (z == 0)    ? c : grid_get(g, 0, 0, -1);
    t = (z == nz-1) ? c : grid_get(g, 0, 0, 1);
    grid_emit(g, cc*c + cw*w + ce*e + cs*s
              + cn*n + cb*b + ct*t);
    return;
}
예제 #5
0
파일: grid.c 프로젝트: progschj/TLDR
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);
}
예제 #6
0
// Count the number of live cells and return the count on rank 0.
int gol_count_alive(void)
{
    struct grid *grid = grids[cur_grid];

    // Count the number of live cells in the local grid.
    int count = 0;
    for (int col = 0; col < grid->width; ++col)
    {
        for (int row = 0; row < grid->height; ++row)
        {
            if (ALIVE == grid_get(grid, row, col))
            {
                count += 1;
            }
        }
    }

    // TODO Reduce the local counts to a global count on rank 0.
    int global_count = 0;
    MPI_Reduce(&count, &global_count, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);

    return global_count;
}
예제 #7
0
int grid_dir2id(int dir) {
	int x, y;
	grid_get(&x, &y);
	
	switch (dir) {
		case GRID_TOP:                  y -= 1; break;
		case GRID_BOTTOM:               y += 1; break;
		case GRID_LEFT:         x -= 1;         break;
		case GRID_RIGHT:        x += 1;         break;
		case GRID_TOP_LEFT:     x -= 1; y -= 1; break;
		case GRID_TOP_RIGHT:    x += 1; y -= 1; break;
		case GRID_BOTTOM_LEFT:  x -= 1; y += 1; break;
		case GRID_BOTTOM_RIGHT: x += 1; y += 1; break;
	}
	
	if (x < 0 || x >= grid_width ||
		y < 0 || y >= grid_height)
	{
		return -1;
	}
	
	return grid_grid2id(x, y);
}
예제 #8
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]);
    }
}
예제 #9
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);
    }
}
예제 #10
0
파일: funky_data.c 프로젝트: gregghz/funky
thing_th *Get(thing_th *grid, const char *kw) {
    if(!grid || th_kind(grid)!=grid_k)
        return NULL;
    return grid_get((grid_th *)grid, kw);
}