Use C99 bool within source modules.

This is the main bulk of this boolification work, but although it's
making the largest actual change, it should also be the least
disruptive to anyone interacting with this code base downstream of me,
because it doesn't modify any interface between modules: all the
inter-module APIs were updated one by one in the previous commits.
This just cleans up the code within each individual source file to use
bool in place of int where I think that makes things clearer.
This commit is contained in:
Simon Tatham
2018-11-13 21:45:44 +00:00
parent a550ea0a47
commit 5f5b284c0b
61 changed files with 2297 additions and 1973 deletions

View File

@ -39,7 +39,7 @@ enum {
struct game_params {
int w, h;
int force_corner_start;
bool force_corner_start;
};
enum { DIR_N = 0, DIR_NE, DIR_E, DIR_SE, DIR_S, DIR_SW, DIR_W, DIR_NW, DIR_MAX };
@ -52,7 +52,7 @@ static const int dys[DIR_MAX] = { -1, -1, 0, 1, 1, 1, 0, -1 };
struct game_state {
int w, h, n;
int completed, used_solve, impossible;
bool completed, used_solve, impossible;
int *dirs; /* direction enums, size n */
int *nums; /* numbers, size n */
unsigned int *flags; /* flags, size n */
@ -92,35 +92,36 @@ static int whichdiri(game_state *state, int fromi, int toi)
return whichdir(fromi%w, fromi/w, toi%w, toi/w);
}
static int ispointing(const game_state *state, int fromx, int fromy,
int tox, int toy)
static bool ispointing(const game_state *state, int fromx, int fromy,
int tox, int toy)
{
int w = state->w, dir = state->dirs[fromy*w+fromx];
/* (by convention) squares do not point to themselves. */
if (fromx == tox && fromy == toy) return 0;
if (fromx == tox && fromy == toy) return false;
/* the final number points to nothing. */
if (state->nums[fromy*w + fromx] == state->n) return 0;
if (state->nums[fromy*w + fromx] == state->n) return false;
while (1) {
if (!INGRID(state, fromx, fromy)) return 0;
if (fromx == tox && fromy == toy) return 1;
if (!INGRID(state, fromx, fromy)) return false;
if (fromx == tox && fromy == toy) return true;
fromx += dxs[dir]; fromy += dys[dir];
}
return 0; /* not reached */
return false; /* not reached */
}
static int ispointingi(game_state *state, int fromi, int toi)
static bool ispointingi(game_state *state, int fromi, int toi)
{
int w = state->w;
return ispointing(state, fromi%w, fromi/w, toi%w, toi/w);
}
/* Taking the number 'num', work out the gap between it and the next
* available number up or down (depending on d). Return 1 if the region
* at (x,y) will fit in that gap, or 0 otherwise. */
static int move_couldfit(const game_state *state, int num, int d, int x, int y)
* available number up or down (depending on d). Return true if the
* region at (x,y) will fit in that gap. */
static bool move_couldfit(
const game_state *state, int num, int d, int x, int y)
{
int n, gap, i = y*state->w+x, sz;
@ -136,54 +137,54 @@ static int move_couldfit(const game_state *state, int num, int d, int x, int y)
/* no gap, so the only allowable move is that that directly
* links the two numbers. */
n = state->nums[i];
return (n == num+d) ? 0 : 1;
return n != num+d;
}
if (state->prev[i] == -1 && state->next[i] == -1)
return 1; /* single unconnected square, always OK */
return true; /* single unconnected square, always OK */
sz = dsf_size(state->dsf, i);
return (sz > gap) ? 0 : 1;
return sz <= gap;
}
static int isvalidmove(const game_state *state, int clever,
int fromx, int fromy, int tox, int toy)
static bool isvalidmove(const game_state *state, bool clever,
int fromx, int fromy, int tox, int toy)
{
int w = state->w, from = fromy*w+fromx, to = toy*w+tox;
int nfrom, nto;
if (!INGRID(state, fromx, fromy) || !INGRID(state, tox, toy))
return 0;
return false;
/* can only move where we point */
if (!ispointing(state, fromx, fromy, tox, toy))
return 0;
return false;
nfrom = state->nums[from]; nto = state->nums[to];
/* can't move _from_ the preset final number, or _to_ the preset 1. */
if (((nfrom == state->n) && (state->flags[from] & FLAG_IMMUTABLE)) ||
((nto == 1) && (state->flags[to] & FLAG_IMMUTABLE)))
return 0;
return false;
/* can't create a new connection between cells in the same region
* as that would create a loop. */
if (dsf_canonify(state->dsf, from) == dsf_canonify(state->dsf, to))
return 0;
return false;
/* if both cells are actual numbers, can't drag if we're not
* one digit apart. */
if (ISREALNUM(state, nfrom) && ISREALNUM(state, nto)) {
if (nfrom != nto-1)
return 0;
return false;
} else if (clever && ISREALNUM(state, nfrom)) {
if (!move_couldfit(state, nfrom, +1, tox, toy))
return 0;
return false;
} else if (clever && ISREALNUM(state, nto)) {
if (!move_couldfit(state, nto, -1, fromx, fromy))
return 0;
return false;
}
return 1;
return true;
}
static void makelink(game_state *state, int from, int to)
@ -199,8 +200,8 @@ static void makelink(game_state *state, int from, int to)
static bool game_can_format_as_text_now(const game_params *params)
{
if (params->w * params->h >= 100) return 0;
return 1;
if (params->w * params->h >= 100) return false;
return true;
}
static char *game_text_format(const game_state *state)
@ -279,9 +280,10 @@ static void strip_nums(game_state *state) {
dsf_init(state->dsf, state->n);
}
static int check_nums(game_state *orig, game_state *copy, int only_immutable)
static bool check_nums(game_state *orig, game_state *copy, bool only_immutable)
{
int i, ret = 1;
int i;
bool ret = true;
assert(copy->n == orig->n);
for (i = 0; i < copy->n; i++) {
if (only_immutable && !(copy->flags[i] & FLAG_IMMUTABLE)) continue;
@ -290,7 +292,7 @@ static int check_nums(game_state *orig, game_state *copy, int only_immutable)
if (copy->nums[i] != orig->nums[i]) {
debug(("check_nums: (%d,%d) copy=%d, orig=%d.",
i%orig->w, i/orig->w, copy->nums[i], orig->nums[i]));
ret = 0;
ret = false;
}
}
return ret;
@ -302,7 +304,7 @@ static game_params *default_params(void)
{
game_params *ret = snew(game_params);
ret->w = ret->h = 4;
ret->force_corner_start = 1;
ret->force_corner_start = true;
return ret;
}
@ -356,10 +358,10 @@ static void decode_params(game_params *ret, char const *string)
ret->h = atoi(string);
while (*string && isdigit((unsigned char)*string)) string++;
}
ret->force_corner_start = 0;
ret->force_corner_start = false;
if (*string == 'c') {
string++;
ret->force_corner_start = 1;
ret->force_corner_start = true;
}
}
@ -549,7 +551,7 @@ done:
}
}
static char *generate_desc(game_state *state, int issolve)
static char *generate_desc(game_state *state, bool issolve)
{
char *ret, buf[80];
int retlen, i, k;
@ -602,10 +604,11 @@ static int cell_adj(game_state *state, int i, int *ai, int *ad)
return n;
}
static int new_game_fill(game_state *state, random_state *rs,
int headi, int taili)
static bool new_game_fill(game_state *state, random_state *rs,
int headi, int taili)
{
int nfilled, an, ret = 0, j;
int nfilled, an, j;
bool ret = false;
int *aidx, *adir;
aidx = snewn(state->n, int);
@ -658,7 +661,7 @@ static int new_game_fill(game_state *state, random_state *rs,
/* it could happen that our last two weren't in line; if that's the
* case, we have to start again. */
if (state->dirs[headi] != -1) ret = 1;
if (state->dirs[headi] != -1) ret = true;
done:
sfree(aidx);
@ -713,11 +716,12 @@ static void debug_desc(const char *what, game_state *state)
/* Expects a fully-numbered game_state on input, and makes sure
* FLAG_IMMUTABLE is only set on those numbers we need to solve
* (as for a real new-game); returns 1 if it managed
* this (such that it could solve it), or 0 if not. */
static int new_game_strip(game_state *state, random_state *rs)
* (as for a real new-game); returns true if it managed
* this (such that it could solve it), or false if not. */
static bool new_game_strip(game_state *state, random_state *rs)
{
int *scratch, i, j, ret = 1;
int *scratch, i, j;
bool ret = true;
game_state *copy = dup_game(state);
debug(("new_game_strip."));
@ -728,7 +732,7 @@ static int new_game_strip(game_state *state, random_state *rs)
if (solve_state(copy) > 0) {
debug(("new_game_strip: soluble immediately after strip."));
free_game(copy);
return 1;
return true;
}
scratch = snewn(state->n, int);
@ -755,9 +759,9 @@ static int new_game_strip(game_state *state, random_state *rs)
debug_state("Copy of state: ", copy);
strip_nums(copy);
if (solve_state(copy) > 0) goto solved;
assert(check_nums(state, copy, 1));
assert(check_nums(state, copy, true));
}
ret = 0;
ret = false;
goto done;
solved:
@ -776,7 +780,7 @@ solved:
dup_game_to(copy, state);
strip_nums(copy);
if (solve_state(copy) > 0) {
assert(check_nums(state, copy, 0));
assert(check_nums(state, copy, false));
debug(("new_game_strip: OK, removing number"));
} else {
assert(state->nums[j] <= state->n);
@ -839,7 +843,7 @@ generate:
assert(solve_state(tosolve) > 0);
free_game(tosolve);
}
ret = generate_desc(state, 0);
ret = generate_desc(state, false);
free_game(state);
return ret;
}
@ -909,7 +913,7 @@ static void head_number(game_state *state, int i, struct head_meta *head)
head->why = "contains cell with immutable number";
} else if (head->start != ss) {
debug(("head_number: chain with non-sequential numbers!"));
state->impossible = 1;
state->impossible = true;
}
}
off++;
@ -1015,7 +1019,7 @@ static void connect_numbers(game_state *state)
dni = dsf_canonify(state->dsf, state->next[i]);
if (di == dni) {
debug(("connect_numbers: chain forms a loop."));
state->impossible = 1;
state->impossible = true;
}
dsf_merge(state->dsf, di, dni);
}
@ -1142,9 +1146,10 @@ static void update_numbers(game_state *state)
sfree(heads);
}
static int check_completion(game_state *state, int mark_errors)
static bool check_completion(game_state *state, bool mark_errors)
{
int n, j, k, error = 0, complete;
int n, j, k;
bool error = false, complete;
/* NB This only marks errors that are possible to perpetrate with
* the current UI in interpret_move. Things like forming loops in
@ -1165,7 +1170,7 @@ static int check_completion(game_state *state, int mark_errors)
state->flags[j] |= FLAG_ERROR;
state->flags[k] |= FLAG_ERROR;
}
error = 1;
error = true;
}
}
}
@ -1173,16 +1178,16 @@ static int check_completion(game_state *state, int mark_errors)
/* Search and mark numbers n not pointing to n+1; if any numbers
* are missing we know we've not completed. */
complete = 1;
complete = true;
for (n = 1; n < state->n; n++) {
if (state->numsi[n] == -1 || state->numsi[n+1] == -1)
complete = 0;
complete = false;
else if (!ispointingi(state, state->numsi[n], state->numsi[n+1])) {
if (mark_errors) {
state->flags[state->numsi[n]] |= FLAG_ERROR;
state->flags[state->numsi[n+1]] |= FLAG_ERROR;
}
error = 1;
error = true;
} else {
/* make sure the link is explicitly made here; for instance, this
* is nice if the user drags from 2 out (making 3) and a 4 is also
@ -1197,13 +1202,13 @@ static int check_completion(game_state *state, int mark_errors)
if ((state->nums[n] < 0) ||
(state->nums[n] == 0 &&
(state->next[n] != -1 || state->prev[n] != -1))) {
error = 1;
error = true;
if (mark_errors)
state->flags[n] |= FLAG_ERROR;
}
}
if (error) return 0;
if (error) return false;
return complete;
}
static game_state *new_game(midend *me, const game_params *params,
@ -1215,7 +1220,7 @@ static game_state *new_game(midend *me, const game_params *params,
if (!state) assert(!"new_game failed to unpick");
update_numbers(state);
check_completion(state, 1); /* update any auto-links */
check_completion(state, true); /* update any auto-links */
return state;
}
@ -1247,7 +1252,7 @@ static int solve_single(game_state *state, game_state *copy, int *from)
while (1) {
x += dxs[d]; y += dys[d];
if (!INGRID(state, x, y)) break;
if (!isvalidmove(state, 1, sx, sy, x, y)) continue;
if (!isvalidmove(state, true, sx, sy, x, y)) continue;
/* can't link to somewhere with a back-link we would have to
* break (the solver just doesn't work like this). */
@ -1276,7 +1281,7 @@ static int solve_single(game_state *state, game_state *copy, int *from)
;
} else if (poss == -1) {
debug(("Solver: nowhere possible for (%d,%d) to link to.", sx, sy));
copy->impossible = 1;
copy->impossible = true;
return -1;
} else {
debug(("Solver: linking (%d,%d) to only possible next (%d,%d).",
@ -1293,7 +1298,7 @@ static int solve_single(game_state *state, game_state *copy, int *from)
x = i%w; y = i/w;
if (from[i] == -1) {
debug(("Solver: nowhere possible to link to (%d,%d)", x, y));
copy->impossible = 1;
copy->impossible = true;
return -1;
} else if (from[i] == -2) {
/*debug(("Solver: (%d,%d) has multiple possible prev squares.", x, y));*/
@ -1330,7 +1335,7 @@ static int solve_state(game_state *state)
sfree(scratch);
update_numbers(state);
ret = state->impossible ? -1 : check_completion(state, 0);
ret = state->impossible ? -1 : check_completion(state, false);
debug(("Solver finished: %s",
ret < 0 ? "impossible" : ret > 0 ? "solved" : "not solved"));
debug_state("After solver: ", state);
@ -1347,7 +1352,7 @@ static char *solve_game(const game_state *state, const game_state *currstate,
tosolve = dup_game(currstate);
result = solve_state(tosolve);
if (result > 0)
ret = generate_desc(tosolve, 1);
ret = generate_desc(tosolve, true);
free_game(tosolve);
if (ret) return ret;
@ -1358,7 +1363,7 @@ static char *solve_game(const game_state *state, const game_state *currstate,
else if (result == 0)
*error = "Unable to solve puzzle.";
else
ret = generate_desc(tosolve, 1);
ret = generate_desc(tosolve, true);
free_game(tosolve);
@ -1369,9 +1374,10 @@ static char *solve_game(const game_state *state, const game_state *currstate,
struct game_ui {
int cx, cy, cshow;
int cx, cy;
bool cshow;
int dragging, drag_is_from;
bool dragging, drag_is_from;
int sx, sy; /* grid coords of start cell */
int dx, dy; /* pixel coords of drag posn */
};
@ -1383,9 +1389,10 @@ static game_ui *new_ui(const game_state *state)
/* NB: if this is ever changed to as to require more than a structure
* copy to clone, there's code that needs fixing in game_redraw too. */
ui->cx = ui->cy = ui->cshow = 0;
ui->cx = ui->cy = 0;
ui->cshow = false;
ui->dragging = 0;
ui->dragging = false;
ui->sx = ui->sy = ui->dx = ui->dy = 0;
return ui;
@ -1408,18 +1415,22 @@ static void decode_ui(game_ui *ui, const char *encoding)
static void game_changed_state(game_ui *ui, const game_state *oldstate,
const game_state *newstate)
{
if (!oldstate->completed && newstate->completed)
ui->cshow = ui->dragging = 0;
if (!oldstate->completed && newstate->completed) {
ui->cshow = false;
ui->dragging = false;
}
}
struct game_drawstate {
int tilesize, started, solved;
int tilesize;
bool started, solved;
int w, h, n;
int *nums, *dirp;
unsigned int *f;
double angle_offset;
int dragging, dx, dy;
bool dragging;
int dx, dy;
blitter *dragb;
};
@ -1431,8 +1442,8 @@ static char *interpret_move(const game_state *state, game_ui *ui,
char buf[80];
if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->cx, &ui->cy, state->w, state->h, 0);
ui->cshow = 1;
move_cursor(button, &ui->cx, &ui->cy, state->w, state->h, false);
ui->cshow = true;
if (ui->dragging) {
ui->dx = COORD(ui->cx) + TILE_SIZE/2;
ui->dy = COORD(ui->cy) + TILE_SIZE/2;
@ -1440,16 +1451,16 @@ static char *interpret_move(const game_state *state, game_ui *ui,
return UI_UPDATE;
} else if (IS_CURSOR_SELECT(button)) {
if (!ui->cshow)
ui->cshow = 1;
ui->cshow = true;
else if (ui->dragging) {
ui->dragging = false;
if (ui->sx == ui->cx && ui->sy == ui->cy) return UI_UPDATE;
if (ui->drag_is_from) {
if (!isvalidmove(state, 0, ui->sx, ui->sy, ui->cx, ui->cy))
if (!isvalidmove(state, false, ui->sx, ui->sy, ui->cx, ui->cy))
return UI_UPDATE;
sprintf(buf, "L%d,%d-%d,%d", ui->sx, ui->sy, ui->cx, ui->cy);
} else {
if (!isvalidmove(state, 0, ui->cx, ui->cy, ui->sx, ui->sy))
if (!isvalidmove(state, false, ui->cx, ui->cy, ui->sx, ui->sy))
return UI_UPDATE;
sprintf(buf, "L%d,%d-%d,%d", ui->cx, ui->cy, ui->sx, ui->sy);
}
@ -1460,13 +1471,14 @@ static char *interpret_move(const game_state *state, game_ui *ui,
ui->sy = ui->cy;
ui->dx = COORD(ui->cx) + TILE_SIZE/2;
ui->dy = COORD(ui->cy) + TILE_SIZE/2;
ui->drag_is_from = (button == CURSOR_SELECT) ? 1 : 0;
ui->drag_is_from = (button == CURSOR_SELECT);
}
return UI_UPDATE;
}
if (IS_MOUSE_DOWN(button)) {
if (ui->cshow) {
ui->cshow = ui->dragging = 0;
ui->cshow = false;
ui->dragging = false;
}
assert(!ui->dragging);
if (!INGRID(state, x, y)) return NULL;
@ -1484,12 +1496,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
}
ui->dragging = true;
ui->drag_is_from = (button == LEFT_BUTTON) ? 1 : 0;
ui->drag_is_from = (button == LEFT_BUTTON);
ui->sx = x;
ui->sy = y;
ui->dx = mx;
ui->dy = my;
ui->cshow = 0;
ui->cshow = false;
return UI_UPDATE;
} else if (IS_MOUSE_DRAG(button) && ui->dragging) {
ui->dx = mx;
@ -1509,11 +1521,11 @@ static char *interpret_move(const game_state *state, game_ui *ui,
}
if (ui->drag_is_from) {
if (!isvalidmove(state, 0, ui->sx, ui->sy, x, y))
if (!isvalidmove(state, false, ui->sx, ui->sy, x, y))
return UI_UPDATE;
sprintf(buf, "L%d,%d-%d,%d", ui->sx, ui->sy, x, y);
} else {
if (!isvalidmove(state, 0, x, y, ui->sx, ui->sy))
if (!isvalidmove(state, false, x, y, ui->sx, ui->sy))
return UI_UPDATE;
sprintf(buf, "L%d,%d-%d,%d", x, y, ui->sx, ui->sy);
}
@ -1576,9 +1588,9 @@ static game_state *execute_move(const game_state *state, const char *move)
ret->next[i] = tmp->next[i];
}
free_game(tmp);
ret->used_solve = 1;
ret->used_solve = true;
} else if (sscanf(move, "L%d,%d-%d,%d", &sx, &sy, &ex, &ey) == 4) {
if (!isvalidmove(state, 0, sx, sy, ex, ey)) return NULL;
if (!isvalidmove(state, false, sx, sy, ex, ey)) return NULL;
ret = dup_game(state);
@ -1618,7 +1630,7 @@ static game_state *execute_move(const game_state *state, const char *move)
}
if (ret) {
update_numbers(ret);
if (check_completion(ret, 1)) ret->completed = 1;
if (check_completion(ret, true)) ret->completed = true;
}
return ret;
@ -1724,7 +1736,9 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
struct game_drawstate *ds = snew(struct game_drawstate);
int i;
ds->tilesize = ds->started = ds->solved = 0;
ds->tilesize = 0;
ds->started = false;
ds->solved = false;
ds->w = state->w;
ds->h = state->h;
ds->n = state->n;
@ -1740,7 +1754,8 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
ds->angle_offset = 0.0F;
ds->dragging = ds->dx = ds->dy = 0;
ds->dragging = false;
ds->dx = ds->dy = 0;
ds->dragb = NULL;
return ds;
@ -1846,10 +1861,11 @@ static void tile_redraw(drawing *dr, game_drawstate *ds, int tx, int ty,
int cb = TILE_SIZE / 16, textsz;
char buf[20];
int arrowcol, sarrowcol, setcol, textcol;
int acx, acy, asz, empty = 0;
int acx, acy, asz;
bool empty = false;
if (num == 0 && !(f & F_ARROW_POINT) && !(f & F_ARROW_INPOINT)) {
empty = 1;
empty = true;
/*
* We don't display text in empty cells: typically these are
* signified by num=0. However, in some cases a cell could
@ -1977,7 +1993,7 @@ static void tile_redraw(drawing *dr, game_drawstate *ds, int tx, int ty,
static void draw_drag_indicator(drawing *dr, game_drawstate *ds,
const game_state *state, const game_ui *ui,
int validdrag)
bool validdrag)
{
int dir, w = ds->w, acol = COL_ARROW;
int fx = FROMCOORD(ui->dx), fy = FROMCOORD(ui->dy);
@ -2026,7 +2042,8 @@ static void game_redraw(drawing *dr, game_drawstate *ds,
int dir, const game_ui *ui,
float animtime, float flashtime)
{
int x, y, i, w = ds->w, dirp, force = 0;
int x, y, i, w = ds->w, dirp;
bool force = false;
unsigned int f;
double angle_offset = 0.0;
game_state *postdrop = NULL;
@ -2035,7 +2052,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds,
angle_offset = 2.0 * PI * (flashtime / FLASH_SPIN);
if (angle_offset != ds->angle_offset) {
ds->angle_offset = angle_offset;
force = 1;
force = true;
}
if (ds->dragging) {
@ -2148,7 +2165,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds,
ds->dy = ui->dy - BLITTER_SIZE/2;
blitter_save(dr, ds->dragb, ds->dx, ds->dy);
draw_drag_indicator(dr, ds, state, ui, postdrop ? 1 : 0);
draw_drag_indicator(dr, ds, state, ui, postdrop != NULL);
}
if (postdrop) free_game(postdrop);
if (!ds->started) ds->started = true;
@ -2377,7 +2394,8 @@ int main(int argc, const char *argv[])
{
char *id = NULL, *desc, *aux = NULL;
const char *err;
int soak = 0, verbose = 0, stdin_desc = 0, n = 1, i;
bool soak = false, verbose = false, stdin_desc = false;
int n = 1, i;
char *seedstr = NULL, newseed[16];
setvbuf(stdout, NULL, _IONBF, 0);
@ -2386,9 +2404,9 @@ int main(int argc, const char *argv[])
while (--argc > 0) {
char *p = (char*)(*++argv);
if (!strcmp(p, "-v") || !strcmp(p, "--verbose"))
verbose = 1;
verbose = true;
else if (!strcmp(p, "--stdin"))
stdin_desc = 1;
stdin_desc = true;
else if (!strcmp(p, "-e") || !strcmp(p, "--seed")) {
seedstr = dupstr(*++argv);
argc--;
@ -2396,7 +2414,7 @@ int main(int argc, const char *argv[])
n = atoi(*++argv);
argc--;
} else if (!strcmp(p, "-s") || !strcmp(p, "--soak")) {
soak = 1;
soak = true;
} else if (*p == '-') {
fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0], p);
usage(stderr);