diff options
Diffstat (limited to 'lightup.c')
| -rw-r--r-- | lightup.c | 217 |
1 files changed, 114 insertions, 103 deletions
@@ -117,7 +117,7 @@ struct game_state { of surrounding lights. For non-black squares, the number of times it's lit. size h*w*/ unsigned int *flags; /* size h*w */ - int completed, used_solve; + bool completed, used_solve; }; #define GRID(gs,grid,x,y) (gs->grid[(y)*((gs)->w) + (x)]) @@ -129,7 +129,7 @@ struct game_state { typedef struct { int ox,oy; int minx, maxx, miny, maxy; - int include_origin; + bool include_origin; } ll_data; /* Macro that executes 'block' once per light in lld, including @@ -374,7 +374,8 @@ static game_state *new_state(const game_params *params) memset(ret->lights, 0, ret->w * ret->h * sizeof(int)); ret->flags = snewn(ret->w * ret->h, unsigned int); memset(ret->flags, 0, ret->w * ret->h * sizeof(unsigned int)); - ret->completed = ret->used_solve = 0; + ret->completed = false; + ret->used_solve = false; return ret; } @@ -445,8 +446,8 @@ static void debug_state(game_state *state) /* These are split up because occasionally functions are only * interested in one particular aspect. */ -/* Returns non-zero if all grid spaces are lit. */ -static int grid_lit(game_state *state) +/* Returns true if all grid spaces are lit. */ +static bool grid_lit(game_state *state) { int x, y; @@ -454,14 +455,14 @@ static int grid_lit(game_state *state) for (y = 0; y < state->h; y++) { if (GRID(state,flags,x,y) & F_BLACK) continue; if (GRID(state,lights,x,y) == 0) - return 0; + return false; } } - return 1; + return true; } /* Returns non-zero if any lights are lit by other lights. */ -static int grid_overlap(game_state *state) +static bool grid_overlap(game_state *state) { int x, y; @@ -469,13 +470,13 @@ static int grid_overlap(game_state *state) for (y = 0; y < state->h; y++) { if (!(GRID(state, flags, x, y) & F_LIGHT)) continue; if (GRID(state, lights, x, y) > 1) - return 1; + return true; } } - return 0; + return false; } -static int number_wrong(const game_state *state, int x, int y) +static bool number_wrong(const game_state *state, int x, int y) { surrounds s; int i, n, empty, lights = GRID(state, lights, x, y); @@ -511,7 +512,7 @@ static int number_wrong(const game_state *state, int x, int y) return (n > lights || (n + empty < lights)); } -static int number_correct(game_state *state, int x, int y) +static bool number_correct(game_state *state, int x, int y) { surrounds s; int n = 0, i, lights = GRID(state, lights, x, y); @@ -522,34 +523,34 @@ static int number_correct(game_state *state, int x, int y) if (GRID(state,flags,s.points[i].x,s.points[i].y) & F_LIGHT) n++; } - return (n == lights) ? 1 : 0; + return n == lights; } -/* Returns non-zero if any numbers add up incorrectly. */ -static int grid_addsup(game_state *state) +/* Returns true if any numbers add up incorrectly. */ +static bool grid_addsup(game_state *state) { int x, y; for (x = 0; x < state->w; x++) { for (y = 0; y < state->h; y++) { if (!(GRID(state, flags, x, y) & F_NUMBERED)) continue; - if (!number_correct(state, x, y)) return 0; + if (!number_correct(state, x, y)) return false; } } - return 1; + return true; } -static int grid_correct(game_state *state) +static bool grid_correct(game_state *state) { if (grid_lit(state) && !grid_overlap(state) && - grid_addsup(state)) return 1; - return 0; + grid_addsup(state)) return true; + return false; } /* --- Board initial setup (blacks, lights, numbers) --- */ -static void clean_board(game_state *state, int leave_blacks) +static void clean_board(game_state *state, bool leave_blacks) { int x,y; for (x = 0; x < state->w; x++) { @@ -567,18 +568,19 @@ static void clean_board(game_state *state, int leave_blacks) static void set_blacks(game_state *state, const game_params *params, random_state *rs) { - int x, y, degree = 0, rotate = 0, nblack; + int x, y, degree = 0, nblack; + bool rotate = false; int rh, rw, i; int wodd = (state->w % 2) ? 1 : 0; int hodd = (state->h % 2) ? 1 : 0; int xs[4], ys[4]; switch (params->symm) { - case SYMM_NONE: degree = 1; rotate = 0; break; - case SYMM_ROT2: degree = 2; rotate = 1; break; - case SYMM_REF2: degree = 2; rotate = 0; break; - case SYMM_ROT4: degree = 4; rotate = 1; break; - case SYMM_REF4: degree = 4; rotate = 0; break; + case SYMM_NONE: degree = 1; rotate = false; break; + case SYMM_ROT2: degree = 2; rotate = true; break; + case SYMM_REF2: degree = 2; rotate = false; break; + case SYMM_ROT4: degree = 4; rotate = true; break; + case SYMM_REF4: degree = 4; rotate = false; break; default: assert(!"Unknown symmetry type"); } if (params->symm == SYMM_ROT4 && (state->h != state->w)) @@ -599,7 +601,7 @@ static void set_blacks(game_state *state, const game_params *params, } /* clear, then randomise, required region. */ - clean_board(state, 0); + clean_board(state, false); nblack = (rw * rh * params->blackpc) / 100; for (i = 0; i < nblack; i++) { do { @@ -647,9 +649,9 @@ static void set_blacks(game_state *state, const game_params *params, } /* Fills in (does not allocate) a ll_data with all the tiles that would - * be illuminated by a light at point (ox,oy). If origin=1 then the + * be illuminated by a light at point (ox,oy). If origin is true then the * origin is included in this list. */ -static void list_lights(game_state *state, int ox, int oy, int origin, +static void list_lights(game_state *state, int ox, int oy, bool origin, ll_data *lld) { int x,y; @@ -681,7 +683,7 @@ static void list_lights(game_state *state, int ox, int oy, int origin, /* Makes sure a light is the given state, editing the lights table to suit the * new state if necessary. */ -static void set_light(game_state *state, int ox, int oy, int on) +static void set_light(game_state *state, int ox, int oy, bool on) { ll_data lld; int diff = 0; @@ -699,7 +701,7 @@ static void set_light(game_state *state, int ox, int oy, int on) } if (diff != 0) { - list_lights(state,ox,oy,1,&lld); + list_lights(state,ox,oy,true,&lld); FOREACHLIT(&lld, GRID(state,lights,lx,ly) += diff; ); } } @@ -709,7 +711,7 @@ static int check_dark(game_state *state, int x, int y) { ll_data lld; - list_lights(state, x, y, 1, &lld); + list_lights(state, x, y, true, &lld); FOREACHLIT(&lld, if (GRID(state,lights,lx,ly) == 1) { return 1; } ); return 0; } @@ -731,7 +733,7 @@ static void place_lights(game_state *state, random_state *rs) for (y = 0; y < state->h; y++) { GRID(state, flags, x, y) &= ~F_MARK; /* we use this later. */ if (GRID(state, flags, x, y) & F_BLACK) continue; - set_light(state, x, y, 1); + set_light(state, x, y, true); } } @@ -740,7 +742,7 @@ static void place_lights(game_state *state, random_state *rs) x = numindices[i] % state->w; if (!(GRID(state, flags, x, y) & F_LIGHT)) continue; if (GRID(state, flags, x, y) & F_MARK) continue; - list_lights(state, x, y, 0, &lld); + list_lights(state, x, y, false, &lld); /* If we're not lighting any lights ourself, don't remove anything. */ n = 0; @@ -753,7 +755,7 @@ static void place_lights(game_state *state, random_state *rs) FOREACHLIT(&lld, if (GRID(state,flags,lx,ly) & F_LIGHT) { n += check_dark(state,lx,ly); } ); if (n == 0) { /* No, it wouldn't, so we can remove them all. */ - FOREACHLIT(&lld, set_light(state,lx,ly, 0); ); + FOREACHLIT(&lld, set_light(state,lx,ly, false); ); GRID(state,flags,x,y) |= F_MARK; } @@ -802,57 +804,58 @@ static void tsl_callback(game_state *state, *x = lx; *y = ly; (*n)++; } -static int try_solve_light(game_state *state, int ox, int oy, - unsigned int flags, int lights) +static bool try_solve_light(game_state *state, int ox, int oy, + unsigned int flags, int lights) { ll_data lld; int sx = 0, sy = 0, n = 0; - if (lights > 0) return 0; - if (flags & F_BLACK) return 0; + if (lights > 0) return false; + if (flags & F_BLACK) return false; /* We have an unlit square; count how many ways there are left to * place a light that lights us (including this square); if only * one, we must put a light there. Squares that could light us * are, of course, the same as the squares we would light... */ - list_lights(state, ox, oy, 1, &lld); + list_lights(state, ox, oy, true, &lld); FOREACHLIT(&lld, { tsl_callback(state, lx, ly, &sx, &sy, &n); }); if (n == 1) { - set_light(state, sx, sy, 1); + set_light(state, sx, sy, true); #ifdef SOLVER_DIAGNOSTICS debug(("(%d,%d) can only be lit from (%d,%d); setting to LIGHT\n", ox,oy,sx,sy)); if (verbose) debug_state(state); #endif - return 1; + return true; } - return 0; + return false; } -static int could_place_light(unsigned int flags, int lights) +static bool could_place_light(unsigned int flags, int lights) { - if (flags & (F_BLACK | F_IMPOSSIBLE)) return 0; - return (lights > 0) ? 0 : 1; + if (flags & (F_BLACK | F_IMPOSSIBLE)) return false; + return !(lights > 0); } -static int could_place_light_xy(game_state *state, int x, int y) +static bool could_place_light_xy(game_state *state, int x, int y) { int lights = GRID(state,lights,x,y); unsigned int flags = GRID(state,flags,x,y); - return (could_place_light(flags, lights)) ? 1 : 0; + return could_place_light(flags, lights); } /* For a given number square, determine whether we have enough info * to unambiguously place its lights. */ -static int try_solve_number(game_state *state, int nx, int ny, - unsigned int nflags, int nlights) +static bool try_solve_number(game_state *state, int nx, int ny, + unsigned int nflags, int nlights) { surrounds s; - int x, y, nl, ns, i, ret = 0, lights; + int x, y, nl, ns, i, lights; + bool ret = false; unsigned int flags; - if (!(nflags & F_NUMBERED)) return 0; + if (!(nflags & F_NUMBERED)) return false; nl = nlights; get_surrounds(state,nx,ny,&s); ns = s.npoints; @@ -873,7 +876,7 @@ static int try_solve_number(game_state *state, int nx, int ny, s.points[i].f |= F_MARK; } } - if (ns == 0) return 0; /* nowhere to put anything. */ + if (ns == 0) return false; /* nowhere to put anything. */ if (nl == 0) { /* we have placed all lights we need to around here; all remaining * surrounds are therefore IMPOSSIBLE. */ @@ -881,7 +884,7 @@ static int try_solve_number(game_state *state, int nx, int ny, for (i = 0; i < s.npoints; i++) { if (!(s.points[i].f & F_MARK)) { GRID(state,flags,s.points[i].x,s.points[i].y) |= F_IMPOSSIBLE; - ret = 1; + ret = true; } } #ifdef SOLVER_DIAGNOSTICS @@ -894,8 +897,8 @@ static int try_solve_number(game_state *state, int nx, int ny, GRID(state,flags,nx,ny) |= F_NUMBERUSED; for (i = 0; i < s.npoints; i++) { if (!(s.points[i].f & F_MARK)) { - set_light(state, s.points[i].x,s.points[i].y, 1); - ret = 1; + set_light(state, s.points[i].x,s.points[i].y, true); + ret = true; } } #ifdef SOLVER_DIAGNOSTICS @@ -992,7 +995,7 @@ static void trl_callback_search(game_state *state, int dx, int dy, static void trl_callback_discount(game_state *state, int dx, int dy, struct setscratch *scratch, int n, void *ctx) { - int *didsth = (int *)ctx; + bool *didsth = (bool *)ctx; int i; if (GRID(state,flags,dx,dy) & F_IMPOSSIBLE) { @@ -1025,7 +1028,7 @@ static void trl_callback_discount(game_state *state, int dx, int dy, if (verbose) debug_state(state); #endif - *didsth = 1; + *didsth = true; } static void trl_callback_incn(game_state *state, int dx, int dy, @@ -1050,7 +1053,7 @@ static void try_rule_out(game_state *state, int x, int y, /* Find all squares that would rule out a light at (x,y) and call trl_cb * with them: anything that would light (x,y)... */ - list_lights(state, x, y, 0, &lld); + list_lights(state, x, y, false, &lld); FOREACHLIT(&lld, { if (could_place_light_xy(state, lx, ly)) { cb(state, lx, ly, scratch, n, ctx); } }); /* ... as well as any empty space (that isn't x,y) next to any clue square @@ -1095,15 +1098,16 @@ static void debug_scratch(const char *msg, struct setscratch *scratch, int n) } #endif -static int discount_set(game_state *state, - struct setscratch *scratch, int n) +static bool discount_set(game_state *state, + struct setscratch *scratch, int n) { - int i, besti, bestn, didsth = 0; + int i, besti, bestn; + bool didsth = false; #ifdef SOLVER_DIAGNOSTICS if (verbose > 1) debug_scratch("discount_set", scratch, n); #endif - if (n == 0) return 0; + if (n == 0) return false; for (i = 0; i < n; i++) { try_rule_out(state, scratch[i].x, scratch[i].y, scratch, n, @@ -1149,11 +1153,12 @@ static void unlit_cb(game_state *state, int lx, int ly, } /* Construct a MAKESLIGHT set from an unlit square. */ -static int discount_unlit(game_state *state, int x, int y, - struct setscratch *scratch) +static bool discount_unlit(game_state *state, int x, int y, + struct setscratch *scratch) { ll_data lld; - int n, didsth; + int n; + bool didsth; #ifdef SOLVER_DIAGNOSTICS if (verbose) debug(("Trying to discount for unlit square at (%d,%d).\n", x, y)); @@ -1162,7 +1167,7 @@ static int discount_unlit(game_state *state, int x, int y, discount_clear(state, scratch, &n); - list_lights(state, x, y, 1, &lld); + list_lights(state, x, y, true, &lld); FOREACHLIT(&lld, { unlit_cb(state, lx, ly, scratch, &n); }); didsth = discount_set(state, scratch, n); #ifdef SOLVER_DIAGNOSTICS @@ -1177,15 +1182,16 @@ static int discount_unlit(game_state *state, int x, int y, * subset of size N-M+1 of those N spaces forms such a set. */ -static int discount_clue(game_state *state, int x, int y, +static bool discount_clue(game_state *state, int x, int y, struct setscratch *scratch) { - int slen, m = GRID(state, lights, x, y), n, i, didsth = 0, lights; + int slen, m = GRID(state, lights, x, y), n, i, lights; + bool didsth = false; unsigned int flags; surrounds s, sempty; combi_ctx *combi; - if (m == 0) return 0; + if (m == 0) return false; #ifdef SOLVER_DIAGNOSTICS if (verbose) debug(("Trying to discount for sets at clue (%d,%d).\n", x, y)); @@ -1213,9 +1219,9 @@ static int discount_clue(game_state *state, int x, int y, } } n = sempty.npoints; /* sempty is now a surrounds of only blank squares. */ - if (n == 0) return 0; /* clue is full already. */ + if (n == 0) return false; /* clue is full already. */ - if (m < 0 || m > n) return 0; /* become impossible. */ + if (m < 0 || m > n) return false; /* become impossible. */ combi = new_combi(n - m + 1, n); while (next_combi(combi)) { @@ -1225,7 +1231,7 @@ static int discount_clue(game_state *state, int x, int y, scratch[slen].y = sempty.points[combi->a[i]].y; slen++; } - if (discount_set(state, scratch, slen)) didsth = 1; + if (discount_set(state, scratch, slen)) didsth = true; } free_combi(combi); #ifdef SOLVER_DIAGNOSTICS @@ -1254,7 +1260,8 @@ static int solve_sub(game_state *state, int *maxdepth) { unsigned int flags; - int x, y, didstuff, ncanplace, lights; + int x, y, ncanplace, lights; + bool didstuff; int bestx, besty, n, bestn, copy_soluble, self_soluble, ret, maxrecurse = 0; game_state *scopy; ll_data lld; @@ -1278,7 +1285,7 @@ static int solve_sub(game_state *state, if (grid_correct(state)) { ret = 1; goto done; } ncanplace = 0; - didstuff = 0; + didstuff = false; /* These 2 loops, and the functions they call, are the critical loops * for timing; any optimisations should look here first. */ for (x = 0; x < state->w; x++) { @@ -1287,8 +1294,10 @@ static int solve_sub(game_state *state, lights = GRID(state,lights,x,y); ncanplace += could_place_light(flags, lights); - if (try_solve_light(state, x, y, flags, lights)) didstuff = 1; - if (try_solve_number(state, x, y, flags, lights)) didstuff = 1; + if (try_solve_light(state, x, y, flags, lights)) + didstuff = true; + if (try_solve_number(state, x, y, flags, lights)) + didstuff = true; } } if (didstuff) continue; @@ -1307,12 +1316,12 @@ static int solve_sub(game_state *state, if (!(flags & F_BLACK) && lights == 0) { if (discount_unlit(state, x, y, sscratch)) { - didstuff = 1; + didstuff = true; goto reduction_success; } } else if (flags & F_NUMBERED) { if (discount_clue(state, x, y, sscratch)) { - didstuff = 1; + didstuff = true; goto reduction_success; } } @@ -1342,7 +1351,7 @@ reduction_success: if (!could_place_light(flags, lights)) continue; n = 0; - list_lights(state, x, y, 1, &lld); + list_lights(state, x, y, true, &lld); FOREACHLIT(&lld, { if (GRID(state,lights,lx,ly) == 0) n++; }); if (n > bestn) { bestn = n; bestx = x; besty = y; @@ -1373,7 +1382,7 @@ reduction_success: #ifdef SOLVER_DIAGNOSTICS debug(("Recursing #2: trying (%d,%d) as LIGHT\n", bestx, besty)); #endif - set_light(scopy, bestx, besty, 1); + set_light(scopy, bestx, besty, true); copy_soluble = solve_sub(scopy, solve_flags, depth+1, maxdepth); /* If we wanted a unique solution but we hit our recursion limit @@ -1453,14 +1462,14 @@ static void unplace_lights(game_state *state) for (x = 0; x < state->w; x++) { for (y = 0; y < state->h; y++) { if (GRID(state,flags,x,y) & F_LIGHT) - set_light(state,x,y,0); + set_light(state,x,y,false); GRID(state,flags,x,y) &= ~F_IMPOSSIBLE; GRID(state,flags,x,y) &= ~F_NUMBERUSED; } } } -static int puzzle_is_good(game_state *state, int difficulty) +static bool puzzle_is_good(game_state *state, int difficulty) { int nsol, mdepth = 0; unsigned int sflags = flags_from_difficulty(difficulty); @@ -1477,13 +1486,13 @@ static int puzzle_is_good(game_state *state, int difficulty) /* if we wanted an easy puzzle, make sure we didn't need recursion. */ if (!(sflags & F_SOLVE_ALLOWRECURSE) && mdepth > 0) { debug(("Ignoring recursive puzzle.\n")); - return 0; + return false; } debug(("%d solutions found.\n", nsol)); - if (nsol <= 0) return 0; - if (nsol > 1) return 0; - return 1; + if (nsol <= 0) return false; + if (nsol > 1) return false; + return true; } /* --- New game creation and user input code. --- */ @@ -1811,13 +1820,15 @@ static char *game_text_format(const game_state *state) } struct game_ui { - int cur_x, cur_y, cur_visible; + int cur_x, cur_y; + bool cur_visible; }; static game_ui *new_ui(const game_state *state) { game_ui *ui = snew(game_ui); - ui->cur_x = ui->cur_y = ui->cur_visible = 0; + ui->cur_x = ui->cur_y = 0; + ui->cur_visible = false; return ui; } @@ -1841,7 +1852,7 @@ static void game_changed_state(game_ui *ui, const game_state *oldstate, const game_state *newstate) { if (newstate->completed) - ui->cur_visible = 0; + ui->cur_visible = false; } #define DF_BLACK 1 /* black square */ @@ -1858,7 +1869,7 @@ struct game_drawstate { int tilesize, crad; int w, h; unsigned int *flags; /* width * height */ - int started; + bool started; }; @@ -1882,7 +1893,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (ui->cur_visible) nullret = empty; - ui->cur_visible = 0; + ui->cur_visible = false; cx = FROMCOORD(x); cy = FROMCOORD(y); action = (button == LEFT_BUTTON) ? FLIP_LIGHT : FLIP_IMPOSSIBLE; @@ -1897,10 +1908,10 @@ static char *interpret_move(const game_state *state, game_ui *ui, action = (button == 'i' || button == 'I' || button == CURSOR_SELECT2) ? FLIP_IMPOSSIBLE : FLIP_LIGHT; } - ui->cur_visible = 1; + ui->cur_visible = true; } else if (IS_CURSOR_MOVE(button)) { - move_cursor(button, &ui->cur_x, &ui->cur_y, state->w, state->h, 0); - ui->cur_visible = 1; + move_cursor(button, &ui->cur_x, &ui->cur_y, state->w, state->h, false); + ui->cur_visible = true; nullret = empty; } else return NULL; @@ -1965,9 +1976,9 @@ static game_state *execute_move(const game_state *state, const char *move) /* LIGHT and IMPOSSIBLE are mutually exclusive. */ if (c == 'L') { GRID(ret, flags, x, y) &= ~F_IMPOSSIBLE; - set_light(ret, x, y, (flags & F_LIGHT) ? 0 : 1); + set_light(ret, x, y, !(flags & F_LIGHT)); } else { - set_light(ret, x, y, 0); + set_light(ret, x, y, false); GRID(ret, flags, x, y) ^= F_IMPOSSIBLE; } move += n; @@ -1977,7 +1988,7 @@ static game_state *execute_move(const game_state *state, const char *move) move++; else if (*move) goto badmove; } - if (grid_correct(ret)) ret->completed = 1; + if (grid_correct(ret)) ret->completed = true; return ret; badmove: @@ -2047,7 +2058,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state) for (i = 0; i < ds->w*ds->h; i++) ds->flags[i] = -1; - ds->started = 0; + ds->started = false; return ds; } @@ -2066,7 +2077,7 @@ static void game_free_drawstate(drawing *dr, game_drawstate *ds) #define HINT_NUMBERS static unsigned int tile_flags(game_drawstate *ds, const game_state *state, - const game_ui *ui, int x, int y, int flashing) + const game_ui *ui, int x, int y, bool flashing) { unsigned int flags = GRID(state, flags, x, y); int lights = GRID(state, lights, x, y); @@ -2159,7 +2170,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, int dir, const game_ui *ui, float animtime, float flashtime) { - int flashing = false; + bool flashing = false; int x,y; if (flashtime) flashing = (int)(flashtime * 3 / FLASH_TIME) != 1; @@ -2177,7 +2188,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, draw_update(dr, 0, 0, TILE_SIZE * ds->w + 2 * BORDER, TILE_SIZE * ds->h + 2 * BORDER); - ds->started = 1; + ds->started = true; } for (x = 0; x < ds->w; x++) { |