// Count the compact walks using brute force. // Enumerate all walks and throw out the ones that not compact. int64_t count_walks_brute(int n) { // Initialize the grid. GRID grid; grid_init(&grid, n); // Define shortcuts for navigating the grid. int delta[4]; delta[LEFT] = -1; delta[RIGHT] = 1; delta[UP] = -grid.ncols; delta[DOWN] = grid.ncols; // Define the grid index corresponding to the anchor point. int grid_index = grid.origin_row * grid.nrows + grid.origin_col; // Index workspace for checking compactness; int index_ws[grid.area]; int direction_histogram[] = {0, 0, 0, 0}; // Count the number of walks. int64_t nwalks = count_continuations_brute(&grid, delta, direction_histogram, index_ws, grid_index, n); // Destroy the grid. grid_destroy(&grid); // Return the number of walks. return nwalks; }
/* * Reflow lines from src grid into dst grid of width new_x. Returns number of * lines fewer in the visible area. The source grid is destroyed. */ u_int grid_reflow(struct grid *dst, struct grid *src, u_int new_x) { u_int py, sy, line; int previous_wrapped; struct grid_line *src_gl; py = 0; sy = src->sy; previous_wrapped = 0; for (line = 0; line < sy + src->hsize; line++) { src_gl = src->linedata + line; if (!previous_wrapped) { /* Wasn't wrapped. If smaller, move to destination. */ if (src_gl->cellsize <= new_x) grid_reflow_move(dst, &py, src_gl); else grid_reflow_split(dst, &py, src_gl, new_x, 0); } else { /* Previous was wrapped. Try to join. */ grid_reflow_join(dst, &py, src_gl, new_x); } previous_wrapped = src_gl->flags & GRID_LINE_WRAPPED; } grid_destroy(src); if (py > sy) return (0); return (sy - py); }
/* Destroy a screen. */ void screen_free(struct screen *s) { if (s->tabs != NULL) xfree(s->tabs); xfree(s->title); grid_destroy(s->grid); }
/* Destroy a screen. */ void screen_free(struct screen *s) { free(s->tabs); free(s->title); free(s->ccolour); grid_destroy(s->grid); }
void preader_destroy(preader* pr) { if (pr->g != NULL) grid_destroy(pr->g); else reader_destroy(pr->r); free(pr); }
static void model_destroygrids(model* m) { int i; for (i = 0; i < m->ngrid; ++i) grid_destroy(m->grids[i]); free(m->grids); }
int main(int argc, char *argv[]) { PetscErrorCode ierr; int i; grid *grd; MPI_Init(&argc,&argv); option options = parse_options(argc, argv); if (options.problem == JUMP) { grd = grid_create(-1, 1, options.nx, -1, 1, options.ny, -1, 1, options.nz); } else { grd = grid_create(0, 1, options.nx, 0, 1, options.ny, 0, 1, options.nz); } if (options.periodic > -1) grd->periodic[options.periodic] = 1; int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) print_intro(&options); map *mp = map_create(options.map); grid_apply_map(grd, mp); problem *pb = problem_create(options.problem, grd->nd, mp->id); solver *sol = solver_create(grd, pb); ierr = solver_init(sol, grd);CHKERRQ(ierr); ierr = solver_run(sol);CHKERRQ(ierr); double *u = (double*) malloc(grd->num_pts*sizeof(double)); double *diff = (double*) malloc(grd->num_pts*sizeof(double)); grid_eval(grd, pb->sol, u); for (i = 0; i < grd->num_pts; i++) diff[i] = sol->state->phi[i] - u[i]; print_norm(diff, grd->num_pts); free(u); free(diff); grid_destroy(grd); free(grd); map_destroy(mp); free(mp); problem_destroy(pb); free(pb); ierr = solver_destroy(sol);CHKERRQ(ierr); free(sol); if (options.eig && rank == 0) { system("./python/plot.py"); } MPI_Finalize(); return 0; }
int pde_problem_destroy(pde_problem **problem){ /* destroy problem structure and all related objects */ if((*problem)->equation) pde_destroy(&((*problem)->equation)); if((*problem)->boundary) boundary_description_destroy(&((*problem)->boundary)); if((*problem)->discretization_grid) grid_destroy(&((*problem)->discretization_grid)); if((*problem)->solver) problem_solver_destroy(&((*problem)->solver)); STANDARD_DESTROY(problem); return OK; }
// deal with all the things that need to be shut down void game_shutdown() { debug_print("Freeing texture resources."); graphics_destroyTexture(block_texture); graphics_destroyTexture(grid_texture); debug_print("Game shutting down..."); font_destroy(); graphics_shutdown(); tetromino_destroy(current_tetromino); grid_destroy(grid); exit(1); }
int64_t count_walks(int n) { // Initialize the grid. GRID grid; grid_init(&grid, n); // Define shortcuts for navigating the grid. int delta[4]; delta[LEFT] = -1; delta[RIGHT] = 1; delta[UP] = -grid.ncols; delta[DOWN] = grid.ncols; // Define the grid index corresponding to the anchor point. int grid_index = grid.origin_row * grid.nrows + grid.origin_col; // Index workspace for checking fillability of void regions. int index_ws[grid.area]; // This flag is true if we have begun filling a void region. bool filling = false; // Initialize neighborhood lookup. int neighborhood_lookup[256]; init_empty_neighbor_group_lookup(neighborhood_lookup); int direction_histogram[] = {0, 0, 0, 0}; // Count the number of walks. int64_t nwalks = count_continuations(&grid, delta, neighborhood_lookup, direction_histogram, index_ws, grid_index, n, filling); // Destroy the grid. grid_destroy(&grid); // Return the number of walks. return nwalks; }
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); }
static LRESULT CALLBACK grid_proc(HWND win, UINT msg, WPARAM wp, LPARAM lp) { grid_t* grid = (grid_t*) GetWindowLongPtr(win, 0); switch(msg) { case WM_PAINT: return generic_paint(win, grid->no_redraw, (grid->style & MC_GS_DOUBLEBUFFER), grid_paint, grid); case WM_PRINTCLIENT: return generic_printclient(win, (HDC) wp, grid_paint, grid); case WM_NCPAINT: return generic_ncpaint(win, grid->theme_listview, (HRGN) wp); case WM_ERASEBKGND: return generic_erasebkgnd(win, grid->theme_listview, (HDC) wp); case MC_GM_GETTABLE: return (LRESULT) grid->table; case MC_GM_SETTABLE: return (grid_set_table(grid, (table_t*) lp) == 0 ? TRUE : FALSE); case MC_GM_GETCOLUMNCOUNT: return grid->col_count; case MC_GM_GETROWCOUNT: return grid->row_count; case MC_GM_RESIZE: return (grid_resize_table(grid, LOWORD(wp), HIWORD(wp)) == 0 ? TRUE : FALSE); case MC_GM_CLEAR: return (grid_clear(grid, wp) == 0 ? TRUE : FALSE); case MC_GM_SETCELLW: case MC_GM_SETCELLA: return (grid_set_cell(grid, LOWORD(wp), HIWORD(wp), (MC_TABLECELL*)lp, (msg == MC_GM_SETCELLW)) == 0 ? TRUE : FALSE); case MC_GM_GETCELLW: case MC_GM_GETCELLA: return (grid_get_cell(grid, LOWORD(wp), HIWORD(wp), (MC_TABLECELL*)lp, (msg == MC_GM_GETCELLW)) == 0 ? TRUE : FALSE); case MC_GM_SETGEOMETRY: return (grid_set_geometry(grid, (MC_GGEOMETRY*)lp, TRUE) == 0 ? TRUE : FALSE); case MC_GM_GETGEOMETRY: return (grid_get_geometry(grid, (MC_GGEOMETRY*)lp) == 0 ? TRUE : FALSE); case MC_GM_REDRAWCELLS: return (grid_redraw_cells(grid, LOWORD(wp), HIWORD(wp), LOWORD(lp), LOWORD(lp)) == 0 ? TRUE : FALSE); case MC_GM_SETCOLUMNWIDTH: return (grid_set_col_width(grid, wp, LOWORD(lp)) == 0 ? TRUE : FALSE); case MC_GM_GETCOLUMNWIDTH: return grid_get_col_width(grid, wp); case MC_GM_SETROWHEIGHT: return (grid_set_row_height(grid, wp, LOWORD(lp)) == 0 ? TRUE : FALSE); case MC_GM_GETROWHEIGHT: return grid_get_row_height(grid, wp); case WM_SETREDRAW: grid->no_redraw = !wp; return 0; case WM_VSCROLL: case WM_HSCROLL: grid_scroll(grid, (msg == WM_VSCROLL), LOWORD(wp), 1); return 0; case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: grid_mouse_wheel(grid, (msg == WM_MOUSEWHEEL), (int)(SHORT)HIWORD(wp)); return 0; case WM_SIZE: if(!grid->no_redraw) { int old_scroll_x = grid->scroll_x; int old_scroll_y = grid->scroll_y; grid_setup_scrollbars(grid, FALSE); if(grid->scroll_x != old_scroll_x || grid->scroll_y != old_scroll_y) InvalidateRect(win, NULL, TRUE); } return 0; case WM_GETFONT: return (LRESULT) grid->font; case WM_SETFONT: grid->font = (HFONT) wp; if((BOOL) lp && !grid->no_redraw) InvalidateRect(win, NULL, TRUE); return 0; case WM_STYLECHANGED: if(wp == GWL_STYLE) grid_style_changed(grid, (STYLESTRUCT*) lp); break; case WM_THEMECHANGED: grid_close_theme(grid); grid_open_theme(grid); if(!grid->no_redraw) RedrawWindow(win, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); return 0; case WM_SYSCOLORCHANGE: if(!grid->no_redraw) RedrawWindow(win, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); return 0; case WM_NOTIFYFORMAT: if(lp == NF_REQUERY) grid_notify_format(grid); return (grid->unicode_notifications ? NFR_UNICODE : NFR_ANSI); case CCM_SETUNICODEFORMAT: { BOOL old = grid->unicode_notifications; grid->unicode_notifications = (wp != 0); return old; } case CCM_GETUNICODEFORMAT: return grid->unicode_notifications; case CCM_SETNOTIFYWINDOW: { HWND old = grid->notify_win; grid->notify_win = (wp ? (HWND) wp : GetAncestor(win, GA_PARENT)); return (LRESULT) old; } case CCM_SETWINDOWTHEME: mcSetWindowTheme(win, (const WCHAR*) lp, NULL); return 0; case WM_NCCREATE: grid = grid_nccreate(win, (CREATESTRUCT*)lp); if(MC_ERR(grid == NULL)) return FALSE; SetWindowLongPtr(win, 0, (LONG_PTR)grid); return TRUE; case WM_CREATE: return (grid_create(grid) == 0 ? 0 : -1); case WM_DESTROY: grid_destroy(grid); return 0; case WM_NCDESTROY: if(grid) grid_ncdestroy(grid); return 0; } return DefWindowProc(win, msg, wp, lp); }
int test_compactness_1() { printf("test 1\n"); // Initialize the test grid. int nrows = 7; int ncols = 7; int area = nrows * ncols; int original_grid[] = { -5, -5, -5, -5, -5, -5, -5, -5, -1, 10, 10, 10, 10, -5, -5, 10, 10, -1, -1, 10, -5, -5, 10, -1, -1, -1, 10, -5, -5, 10, -1, -1, 10, 10, -5, -5, 10, 20, 30, 10, -1, -5, -5, -5, -5, -5, -5, -5, -5, }; // Initialize the grid structure. GRID grid; grid_init(&grid, 2); // Compare the dimensions to the test grid. assert(grid.nrows == nrows); assert(grid.ncols == ncols); assert(grid.area == area); // Copy the test grid data into the grid structure. memcpy(grid.data, original_grid, sizeof original_grid); // Run some tests. int nfails = 0; // Declare variables. int query_row; int query_col; int void_row; int void_col; int query_index; int void_index; int nremaining; int expected_fillability; // Setup for vertex 20 stepping upwards. query_row = 5; query_col = 2; void_row = 4; void_col = 2; query_index = query_row*ncols + query_col; void_index = void_row*ncols + void_col; // This step should not work regardless of the number of vertices remaining, // because the parity is wrong. nremaining = 6; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 7; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 8; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // Setup for vertex 30 stepping in the up direction. query_row = 5; query_col = 3; void_row = 4; void_col = 3; query_index = query_row*ncols + query_col; void_index = void_row*ncols + void_col; // This step works when the number of remaining vertices is correct. nremaining = 6; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 7; expected_fillability = true; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 8; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // Destroy the grid. grid_destroy(&grid); return nfails; }
int find_boundary(int n, double *x, double *y, double r, double (*r_function)(double, double), int n_contour, int *contour) { /* * Find the boundary of the `n` 2-dimensional points located at `x` and `y` using a ballpivot approach. * The indices of the contour points are stored in the `contour` array. There are several possibilities * to provide the ball radius used in the ballpivot algorithm: * - As a callback function (`r_function`) that returns the ball radius for the current position. * - As a constant ball radius `r` * - Automatically calculated / estimated from the data points * * If `r_function` is different from NULL it will be used to calculate the ball radius for each position. * In that case the parameter `r` is only used to set the cell size of the internal grid data structure storing * the points if it has a value greater 0. * If `r_function` is NULL and `r` is greater 0 it is used as a constant ball radius and determines the cell * size of the internal grid. Otherwise a (constant) ball radius is automatically calculated as 1.2 times the * the largest distance from a point to its nearest neighbor. * * If the algorithm is successful it returns the number of contour points that were written in `contour`. * Otherwise the return value is less than 0 indicating a too small (`FIND_BOUNDARY_BALL_TOO_SMALL`) or too * large (`FIND_BOUNDARY_BALL_TOO_LARGE`) ball radius, an invalid number of points (`FIND_BOUNDARY_INVALID_POINTS`) * or that the number of contour points exceed the available memory in `contour` given by `n_contour`. */ double2 bb_bottom_left, bb_top_right; double2 *points; double cell_size; neighbor_point_list data; grid *grid_ptr; int i, start_point, current_index; int num_contour_points = 0; if (n < 2) { return FIND_BOUNDARY_INVALID_POINTS; } if (n_contour <= 1) { return FIND_BOUNDARY_MEMORY_EXCEEDED; } points = malloc(n * sizeof(double2)); assert(points); for (i = 0; i < n; i++) { points[i].x = x[i]; points[i].y = y[i]; points[i].index = i; } calculate_bounding_box(n, points, &bb_bottom_left, &bb_top_right); if (r <= 0) { /* If no radius is given, estimate the cell size as 1/10 of the average of width and height of the data's * bounding box. */ cell_size = ((bb_top_right.x - bb_bottom_left.x) + (bb_top_right.y - bb_bottom_left.y)) / 2. / 10.; } else { /* Scale radius by 1.1 to make sure that only direct neighbor cells have to be checked. */ cell_size = r * 1.1; } grid_ptr = grid_create(n, points, cell_size); /* Start from the point closest to the bottom left corner of the bounding box*/ start_point = grid_find_nearest_neighbor(grid_ptr, grid_ptr->bounding_box[0], -1, cell_size).index; contour[num_contour_points] = start_point; if (r <= 0 && r_function == NULL) { /* No radius given, calculate from data */ for (i = 0; i < n; i++) { double nearest_neighbor = grid_find_nearest_neighbor(grid_ptr, grid_get_elem(grid_ptr, i), i, cell_size).x; if (nearest_neighbor > r) { /* Calculate r as the largest distance from one point to its nearest neighbor. This makes sure, that * at least one neighbor can be reached from each point. */ r = nearest_neighbor; } } r = sqrt(r); r *= 1.2; } /* Initialize list structure that stores the possible neighbors in each step. */ data.capacity = 10; data.point_list = malloc(data.capacity * sizeof(int)); assert(data.point_list); current_index = start_point; while (num_contour_points == 0 || contour[num_contour_points] != contour[0]) { double2 current_point; data.current = current_index; data.size = 0; data.num_points_reachable = 0; current_point = grid_get_elem(grid_ptr, current_index); if (num_contour_points >= n_contour) { return FIND_BOUNDARY_MEMORY_EXCEEDED; } if (r_function) { r = r_function(current_point.x, current_point.y); if (r <= 0) { return FIND_BOUNDARY_BALL_TOO_SMALL; } } /* Find the possible neighbors of `current_point` using the grid structure. */ grid_apply_function(grid_ptr, current_point, 2 * r, grid_cb_find_possible_neighbors, (void *)&data, 1, ¤t_index); if (data.size == 1) { /* Only one neighbor is possible */ current_index = data.point_list[0]; contour[++num_contour_points] = current_index; } else if (data.size > 1) { /* More than one point is a possible neighbor */ int best_neighbor = 0; double best_angle = 0; int oldest = num_contour_points + 1; int unvisited_points = 0; /* If at least one possible neighbor is not included in the contour until now use the (unvisited) one * with the smallest angle. Otherwise use the one that was visited first to avoid (infinite) loops. */ for (i = 0; i < (int)data.size; i++) { int contour_point_index = in_contour(data.point_list[i], num_contour_points, contour); if (contour_point_index < 0) { double2 previous_contour_point = grid_get_elem(grid_ptr, contour[num_contour_points - 1]); double2 possible_contour_point = grid_get_elem(grid_ptr, data.point_list[i]); double a = angle(current_point, previous_contour_point, possible_contour_point); if (a > best_angle) { best_angle = a; best_neighbor = i; } unvisited_points++; } else if (!unvisited_points) { if (contour_point_index < oldest) { oldest = contour_point_index; best_neighbor = i; } } } current_index = data.point_list[best_neighbor]; contour[++num_contour_points] = current_index; } else { /* No possible neighbor is found. */ if (data.num_points_reachable == 0) { /* No point was reachable -> ball too small */ return FIND_BOUNDARY_BALL_TOO_SMALL; } else { /* No reachable point resulted in an empty ball -> ball too large */ return FIND_BOUNDARY_BALL_TOO_LARGE; } } } /* The grid data structure reorders the points. Restore original indices of the contour points. */ for (i = 0; i < num_contour_points; i++) { contour[i] = points[contour[i]].index; } free(points); free(data.point_list); grid_destroy(grid_ptr); return num_contour_points; }
// the main game loop which will run until the game is done void game_loop() { SDL_Event event, e; SDL_TimerID timer; int last_game_update = 0; int last_particle_update = 0; int last_render = 0; int previous_level = 0; debug_print("Loading media..."); load_media(); // check if we want to show score increments game.show_score_increments = atoi(config_getValue("show_score_increments")); // setup input input_init(); // create & show menu ui_menuInit(); ui_toggleMenuVisible(); SDL_SetEventFilter(ui_handleEvents); // loop forever debug_print("Entering main game loop..."); while (1) { // see if its time to trigger an update (make sure we're not paused either) if (!game.paused && SDL_GetTicks() - last_game_update > game_getGameUpdateFreq()) { last_game_update = SDL_GetTicks(); // remember time of last update game_update(); } if (game.show_score_increments) { // at the moment we just have the one particle set // see if its time to trigger a particle update if (SDL_GetTicks() - last_particle_update > PARTICLE_UPDATE_INTERVAL) { last_particle_update = SDL_GetTicks(); particle_update(); } } // check for any events waiting while (SDL_PollEvent(&event)) { switch(event.type) { // key presses are handled in input.c case SDL_KEYDOWN: input_onKeyDown(event.key.keysym.sym); break; case LEFT_KEY: tetromino_moveLeft(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveRight(current_tetromino); } break; case RIGHT_KEY: tetromino_moveRight(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveLeft(current_tetromino); } break; case DOWN_KEY: // uses the key repeat interval to accelerate the tetromino down tetromino_moveDown(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveUp(current_tetromino); } break; case UP_KEY: // rotate to a new position tetromino_setNextPosition(current_tetromino); tetromino_setShape(current_tetromino, current_tetromino->type, current_tetromino->position); // make sure the new position doesn't cause any collisions // if it does, reverse the rotation if (grid_checkCollision(grid, current_tetromino)) { tetromino_setPrevPosition(current_tetromino); tetromino_setShape(current_tetromino, current_tetromino->type, current_tetromino->position); } break; case SPACE_KEY: tetromino_moveDown(current_tetromino); // move the tetromino down until it causes a collision while (!grid_checkCollision(grid, current_tetromino)) { tetromino_moveDown(current_tetromino); } // once we have a collision, move it back into place tetromino_moveUp(current_tetromino); break; case PAUSE_KEY: debug_print("Pausing game"); game.paused = !game.paused; // stop the game timer if (game.paused) { SDL_RemoveTimer(timer); timer = NULL; } else { // start it again timer = SDL_AddTimer(1000, game_updateTime, NULL); } break; case ESCAPE_KEY: // pause game updates debug_print("Escape key pressed."); // toggle paused game state if we're in game if (grid && current_tetromino) { game.paused = !game.paused; if (game.paused) { // stop couting time played SDL_RemoveTimer(timer); timer = NULL; } // starting timer again, only if we're still in a game else if (grid && current_tetromino) { timer = SDL_AddTimer(1000, game_updateTime, NULL); } } // show or hide the menu if (grid && current_tetromino) { ui_toggleMenuVisible(); } // enable ui message pump if its visible if (ui_isMenuVisible()) { // if we're in game, show in-game menu if (grid && current_tetromino) { ui_menuPageSetCurrentById(MENU_IN_GAME); } // otherwise show main menu else { ui_menuPageSetCurrentById(MENU_MAIN); } SDL_SetEventFilter(ui_handleEvents); } break; case GAME_START_NEW: // set some game variables game.level = 0; game.score = 0; game.lines = 0; game.paused = 0; // time variables game.hours = 0; game.minutes = 0; game.seconds = 0; // create the grid grid = grid_createNew(GRID_WIDTH, GRID_HEIGHT); // create the first tetromino current_tetromino = tetromino_createNew(); current_tetromino->x = 0; current_tetromino->y = 0; // update time SDL_Init(SDL_INIT_TIMER); if (timer) { SDL_RemoveTimer(timer); timer = NULL; } ui_toggleMenuVisible(); timer = SDL_AddTimer(1000, game_updateTime, NULL); game.paused = 0; break; case GAME_END: // called by either the menu or game over scenario // destroy timer, grid and tetromino SDL_RemoveTimer(timer); timer = NULL; grid_destroy(grid); grid = NULL; tetromino_destroy(current_tetromino); current_tetromino = NULL; // show menu if it isn't already visible ui_menuPageSetCurrentById(MENU_MAIN); if (!ui_isMenuVisible()) { SDL_SetEventFilter(ui_handleEvents); ui_toggleMenuVisible(); } break; case TETROMINO_CREATE: // assumes that the old one has already been discarded current_tetromino = tetromino_createNew(); current_tetromino->x = 0; current_tetromino->y = 0; // check if we have an immediate collision (game over) if (grid_checkCollision(grid, current_tetromino)) { SDL_RemoveTimer(timer); timer = NULL; e.type = GAME_END; SDL_PushEvent(&e); } break; case GRID_REMOVE_LINE: if (game.show_score_increments) { // animated score increment game_showScoreIncrement(event.user.code, (game.level + 1) * 10); } grid_removeLine(grid, event.user.code); // increment number of complete lines game.lines += 1; // +10 per block and x10 per level game.score += (game.level + 1) * 10 * GRID_WIDTH; // increment the game level every 10 lines previous_level = game.level; game.level = game.lines / 10; if (previous_level != game.level) { game_showLevelIncrement(); } break; case GAME_QUIT: SDL_RemoveTimer(timer); // stop gameplay timer timer = NULL; game_shutdown(); break; // unhandled events are ignored default: break; } } // update the display // without this delay gfx card tries to commit suicide by melting if (SDL_GetTicks() - last_render > 3) { display_update(); last_render= SDL_GetTicks(); } } }
static int grid_destroy_lua(lua_State *L) { grid_destroy(*((grid*)lua_touserdata(L, 1))); return 0; }
int test_compactness_0() { printf("test 0\n"); // Initialize the test grid. int nrows = 7; int ncols = 7; int area = nrows * ncols; int original_grid[] = { -5, -5, -5, -5, -5, -5, -5, -5, 14, 13, 12, -1, -1, -5, -5, 15, -1, 11, -1, -1, -5, -5, 16, -1, 10, -1, -1, -5, -5, 17, -1, -1, 24, 23, -5, -5, 18, 19, 20, 21, 22, -5, -5, -5, -5, -5, -5, -5, -5, }; // Initialize the grid structure. GRID grid; grid_init(&grid, 2); // Compare the dimensions to the test grid. assert(grid.nrows == nrows); assert(grid.ncols == ncols); assert(grid.area == area); // Copy the test grid data into the grid structure. memcpy(grid.data, original_grid, sizeof original_grid); // Run some tests. int nfails = 0; // Declare variables. int query_row; int query_col; int void_row; int void_col; int query_index; int void_index; int nremaining; int expected_fillability; // Setup for vertex 24 stepping to the left. query_row = 4; query_col = 4; void_row = 4; void_col = 3; query_index = query_row*ncols + query_col; void_index = void_row*ncols + void_col; // This step should work only when four vertices remain. nremaining = 3; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 4; expected_fillability = true; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 5; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // Setup for vertex 24 stepping in the up direction. query_row = 4; query_col = 4; void_row = 3; void_col = 4; query_index = query_row*ncols + query_col; void_index = void_row*ncols + void_col; // This step should work regardless of how many vertices remain, // because this void region is connected to the border. nremaining = 3; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 4; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 5; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // Destroy the grid. grid_destroy(&grid); return nfails; }
int test_compactness_2() { printf("test 2\n"); printf("neither starting point is blocked by parity\n"); printf("but both are blocked by an excess of degree-1 vertices\n"); // Initialize the test grid. int nrows = 7; int ncols = 7; int area = nrows * ncols; int original_grid[] = { -5, -5, -5, -5, -5, -5, -5, -5, -1, 10, 10, 10, -1, -5, -5, 10, 10, -1, 10, -1, -5, -5, 10, -1, -1, 10, 10, -5, -5, 10, -1, -1, -1, 10, -5, -5, 10, 20, 30, 10, 10, -5, -5, -5, -5, -5, -5, -5, -5, }; // Initialize the grid structure. GRID grid; grid_init(&grid, 2); // Compare the dimensions to the test grid. assert(grid.nrows == nrows); assert(grid.ncols == ncols); assert(grid.area == area); // Copy the test grid data into the grid structure. memcpy(grid.data, original_grid, sizeof original_grid); // Run some tests. int nfails = 0; // Declare variables. int query_row; int query_col; int void_row; int void_col; int query_index; int void_index; int nremaining; int expected_fillability; // Setup for vertex 20 stepping upwards. query_row = 5; query_col = 2; void_row = 4; void_col = 2; query_index = query_row*ncols + query_col; void_index = void_row*ncols + void_col; // Blocked by too many degree-1 vertices. nremaining = 6; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 7; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 8; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // Setup for vertex 30 stepping in the up direction. query_row = 5; query_col = 3; void_row = 4; void_col = 3; query_index = query_row*ncols + query_col; void_index = void_row*ncols + void_col; // Blocked by too many degree-1 vertices. nremaining = 6; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 7; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // nremaining = 8; expected_fillability = false; nfails += _compactness_test_helper(&grid, original_grid, query_index, void_index, nremaining, expected_fillability); // Destroy the grid. grid_destroy(&grid); return nfails; }