aboutsummaryrefslogtreecommitdiff
path: root/galaxies.c
diff options
context:
space:
mode:
Diffstat (limited to 'galaxies.c')
-rw-r--r--galaxies.c193
1 files changed, 102 insertions, 91 deletions
diff --git a/galaxies.c b/galaxies.c
index f167242..e871e21 100644
--- a/galaxies.c
+++ b/galaxies.c
@@ -49,7 +49,7 @@
#ifdef DEBUGGING
#define solvep debug
#else
-int solver_show_working;
+bool solver_show_working;
#define solvep(x) do { if (solver_show_working) { printf x; } } while(0)
#endif
@@ -139,7 +139,7 @@ struct game_state {
int w, h; /* size from params */
int sx, sy; /* allocated size, (2x-1)*(2y-1) */
space *grid;
- int completed, used_solve;
+ bool completed, used_solve;
int ndots;
space **dots;
@@ -148,7 +148,7 @@ struct game_state {
or -1 if stale. */
};
-static int check_complete(const game_state *state, int *dsf, int *colours);
+static bool check_complete(const game_state *state, int *dsf, int *colours);
static int solver_state(game_state *state, int maxdiff);
static int solver_obvious(game_state *state);
static int solver_obvious_dot(game_state *state, space *dot);
@@ -464,7 +464,8 @@ typedef int (*space_cb)(game_state *state, space *sp, void *ctx);
static int foreach_sub(game_state *state, space_cb cb, unsigned int f,
void *ctx, int startx, int starty)
{
- int x, y, progress = 0, impossible = 0, ret;
+ int x, y, ret;
+ bool progress = false, impossible = false;
space *sp;
for (y = starty; y < state->sy; y += 2) {
@@ -473,14 +474,14 @@ static int foreach_sub(game_state *state, space_cb cb, unsigned int f,
ret = cb(state, sp, ctx);
if (ret == -1) {
if (f & IMPOSSIBLE_QUITS) return -1;
- impossible = -1;
+ impossible = true;
} else if (ret == 1) {
- progress = 1;
+ progress = true;
}
sp += 2;
}
}
- return impossible ? -1 : progress;
+ return impossible ? -1 : progress ? 1 : 0;
}
static int foreach_tile(game_state *state, space_cb cb, unsigned int f,
@@ -577,15 +578,15 @@ static space *tile_opposite(const game_state *state, const space *sp)
return space_opposite_dot(state, sp, dot);
}
-static int dotfortile(game_state *state, space *tile, space *dot)
+static bool dotfortile(game_state *state, space *tile, space *dot)
{
space *tile_opp = space_opposite_dot(state, tile, dot);
- if (!tile_opp) return 0; /* opposite would be off grid */
+ if (!tile_opp) return false; /* opposite would be off grid */
if (tile_opp->flags & F_TILE_ASSOC &&
(tile_opp->dotx != dot->x || tile_opp->doty != dot->y))
- return 0; /* opposite already associated with diff. dot */
- return 1;
+ return false; /* opposite already associated with diff. dot */
+ return true;
}
static void adjacencies(game_state *state, space *sp, space **a1s, space **a2s)
@@ -614,33 +615,34 @@ static void adjacencies(game_state *state, space *sp, space **a1s, space **a2s)
}
}
-static int outline_tile_fordot(game_state *state, space *tile, int mark)
+static bool outline_tile_fordot(game_state *state, space *tile, bool mark)
{
space *tadj[4], *eadj[4];
- int i, didsth = 0, edge, same;
+ int i;
+ bool didsth = false, edge, same;
assert(tile->type == s_tile);
adjacencies(state, tile, eadj, tadj);
for (i = 0; i < 4; i++) {
if (!eadj[i]) continue;
- edge = (eadj[i]->flags & F_EDGE_SET) ? 1 : 0;
+ edge = eadj[i]->flags & F_EDGE_SET;
if (tadj[i]) {
if (!(tile->flags & F_TILE_ASSOC))
- same = (tadj[i]->flags & F_TILE_ASSOC) ? 0 : 1;
+ same = !(tadj[i]->flags & F_TILE_ASSOC);
else
same = ((tadj[i]->flags & F_TILE_ASSOC) &&
tile->dotx == tadj[i]->dotx &&
- tile->doty == tadj[i]->doty) ? 1 : 0;
+ tile->doty == tadj[i]->doty);
} else
- same = 0;
+ same = false;
if (!edge && !same) {
if (mark) eadj[i]->flags |= F_EDGE_SET;
- didsth = 1;
+ didsth = true;
} else if (edge && same) {
if (mark) eadj[i]->flags &= ~F_EDGE_SET;
- didsth = 1;
+ didsth = true;
}
}
return didsth;
@@ -664,7 +666,7 @@ static void tiles_from_edge(game_state *state, space *sp, space **ts)
/* Returns a move string for use by 'solve', including the initial
* 'S' if issolve is true. */
static char *diff_game(const game_state *src, const game_state *dest,
- int issolve)
+ bool issolve)
{
int movelen = 0, movesize = 256, x, y, len;
char *move = snewn(movesize, char), buf[80];
@@ -725,9 +727,9 @@ static char *diff_game(const game_state *src, const game_state *dest,
return move;
}
-/* Returns 1 if a dot here would not be too close to any other dots
+/* Returns true if a dot here would not be too close to any other dots
* (and would avoid other game furniture). */
-static int dot_is_possible(game_state *state, space *sp, int allow_assoc)
+static bool dot_is_possible(game_state *state, space *sp, bool allow_assoc)
{
int bx = 0, by = 0, dx, dy;
space *adj;
@@ -766,28 +768,28 @@ static int dot_is_possible(game_state *state, space *sp, int allow_assoc)
if (col < 0)
col = c;
if (c != col)
- return 0; /* colour mismatch */
+ return false; /* colour mismatch */
}
}
#endif
if (!allow_assoc && (adj->flags & F_TILE_ASSOC))
- return 0;
+ return false;
if (dx != 0 || dy != 0) {
/* Other than our own square, no dots nearby. */
if (adj->flags & (F_DOT))
- return 0;
+ return false;
}
/* We don't want edges within our rectangle
* (but don't care about edges on the edge) */
if (abs(dx) < bx && abs(dy) < by &&
adj->flags & F_EDGE_SET)
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
/* ----------------------------------------------------------
@@ -805,7 +807,8 @@ static game_state *blank_game(int w, int h)
state->sx = (w*2)+1;
state->sy = (h*2)+1;
state->grid = snewn(state->sx * state->sy, space);
- state->completed = state->used_solve = 0;
+ state->completed = false;
+ state->used_solve = false;
for (x = 0; x < state->sx; x++) {
for (y = 0; y < state->sy; y++) {
@@ -851,7 +854,7 @@ static void game_update_dots(game_state *state)
}
}
-static void clear_game(game_state *state, int cleardots)
+static void clear_game(game_state *state, bool cleardots)
{
int x, y;
@@ -1004,8 +1007,8 @@ static int movedot_cb(game_state *state, space *tile, void *vctx)
* extra spaces (by checking for empty spaces on the far side), and then
* see if we can move the dot to shift the CoG to include the new spaces.
*/
-static int dot_expand_or_move(game_state *state, space *dot,
- space **toadd, int nadd)
+static bool dot_expand_or_move(game_state *state, space *dot,
+ space **toadd, int nadd)
{
space *tileopp;
int i, ret, nnew, cx, cy;
@@ -1027,7 +1030,7 @@ static int dot_expand_or_move(game_state *state, space *dot,
for (i = 0; i < nadd; i++) {
if (!(picture[(toadd[i]->y/2) * state->w + (toadd[i]->x/2)]) ^
!(dot->flags & F_DOT_BLACK))
- return 0;
+ return false;
}
}
#endif
@@ -1061,7 +1064,7 @@ static int dot_expand_or_move(game_state *state, space *dot,
dot->x, dot->y));
dbg_state(state);
}
- return 1;
+ return true;
noexpand:
/* Otherwise, try to move dot so as to encompass given spaces: */
@@ -1077,7 +1080,7 @@ noexpand:
if ((cx % nnew) != 0 || (cy % nnew) != 0) {
debug(("Unable to move dot %d,%d, CoG not whole number.\n",
dot->x, dot->y));
- return 0;
+ return false;
}
cx /= nnew; cy /= nnew;
@@ -1090,7 +1093,7 @@ noexpand:
if (ret == -1) {
debug(("Unable to move dot %d,%d, new dot not symmetrical.\n",
dot->x, dot->y));
- return 0;
+ return false;
}
/* Also check whether all spaces we're adding would have a good
* opposite wrt the new dot. */
@@ -1103,13 +1106,13 @@ noexpand:
if (!tileopp) {
debug(("Unable to move dot %d,%d, new dot not symmetrical.\n",
dot->x, dot->y));
- return 0;
+ return false;
}
#ifdef STANDALONE_PICTURE_GENERATOR
if (picture) {
if (!(picture[(tileopp->y/2) * state->w + (tileopp->x/2)]) ^
!(dot->flags & F_DOT_BLACK))
- return 0;
+ return false;
}
#endif
}
@@ -1142,7 +1145,7 @@ noexpand:
assert(ret == 1);
dbg_state(state);
- return 1;
+ return true;
}
/* Hard-code to a max. of 2x2 squares, for speed (less malloc) */
@@ -1151,13 +1154,13 @@ noexpand:
#define MAX_TILE_PERC 20
-static int generate_try_block(game_state *state, random_state *rs,
- int x1, int y1, int x2, int y2)
+static bool generate_try_block(game_state *state, random_state *rs,
+ int x1, int y1, int x2, int y2)
{
int x, y, nadd = 0, nout = 0, i, maxsz;
space *sp, *toadd[MAX_TOADD], *outside[MAX_OUTSIDE], *dot;
- if (!INGRID(state, x1, y1) || !INGRID(state, x2, y2)) return 0;
+ if (!INGRID(state, x1, y1) || !INGRID(state, x2, y2)) return false;
/* We limit the maximum size of tiles to be ~2*sqrt(area); so,
* a 5x5 grid shouldn't have anything >10 tiles, a 20x20 grid
@@ -1172,7 +1175,7 @@ static int generate_try_block(game_state *state, random_state *rs,
assert(nadd < MAX_TOADD);
sp = &SPACE(state, x, y);
assert(sp->type == s_tile);
- if (sp->flags & F_TILE_ASSOC) return 0;
+ if (sp->flags & F_TILE_ASSOC) return false;
toadd[nadd++] = sp;
}
}
@@ -1202,9 +1205,9 @@ static int generate_try_block(game_state *state, random_state *rs,
dot->x, dot->y, dot->nassoc));
continue;
}
- if (dot_expand_or_move(state, dot, toadd, nadd)) return 1;
+ if (dot_expand_or_move(state, dot, toadd, nadd)) return true;
}
- return 0;
+ return false;
}
#ifdef STANDALONE_SOLVER
@@ -1258,7 +1261,7 @@ static void generate_pass(game_state *state, random_state *rs, int *scratch,
/* If we've got here we might want to put a dot down. Check
* if we can, and add one if so. */
- if (dot_is_possible(state, sp, 0)) {
+ if (dot_is_possible(state, sp, false)) {
add_dot(sp);
#ifdef STANDALONE_PICTURE_GENERATOR
if (picture) {
@@ -1282,14 +1285,15 @@ static char *new_game_desc(const game_params *params, random_state *rs,
game_state *state = blank_game(params->w, params->h), *copy;
char *desc;
int *scratch, sz = state->sx*state->sy, i;
- int diff, ntries = 0, cc;
+ int diff, ntries = 0;
+ bool cc;
/* Random list of squares to try and process, one-by-one. */
scratch = snewn(sz, int);
for (i = 0; i < sz; i++) scratch[i] = i;
generate:
- clear_game(state, 1);
+ clear_game(state, true);
ntries++;
/* generate_pass(state, rs, scratch, 10, GP_DOTS); */
@@ -1315,7 +1319,7 @@ generate:
assert(cc);
copy = dup_game(state);
- clear_game(copy, 0);
+ clear_game(copy, false);
dbg_state(copy);
diff = solver_state(copy, params->diff);
free_game(copy);
@@ -1363,7 +1367,7 @@ generate:
for (i = 0; i < nposns; i++) {
int x, y, x0, y0, x1, y1, cx, cy, cn, cx0, cy0, cx1, cy1, tx, ty;
space *s0, *s1, *ts, *d0, *d1, *dn;
- int ok;
+ bool ok;
/* Coordinates of edge space */
x = posns[i] % state->sx;
@@ -1482,7 +1486,7 @@ generate:
}
copy = dup_game(state);
- clear_game(copy, 0);
+ clear_game(copy, false);
dbg_state(copy);
newdiff = solver_state(copy, params->diff);
free_game(copy);
@@ -1511,7 +1515,7 @@ generate:
return desc;
}
-static int dots_too_close(game_state *state)
+static bool dots_too_close(game_state *state)
{
/* Quick-and-dirty check, using half the solver:
* solver_obvious will only fail if the dots are
@@ -1520,7 +1524,7 @@ static int dots_too_close(game_state *state)
game_state *tmp = dup_game(state);
int ret = solver_obvious(tmp);
free_game(tmp);
- return (ret == -1) ? 1 : 0;
+ return ret == -1;
}
static game_state *load_game(const game_params *params, const char *desc,
@@ -1919,13 +1923,13 @@ static int solver_spaces_oneposs_cb(game_state *state, space *tile, void *ctx)
*
*/
-/* Returns 1 if this tile is either already associated with this dot,
+/* Returns true if this tile is either already associated with this dot,
* or blank. */
-static int solver_expand_checkdot(space *tile, space *dot)
+static bool solver_expand_checkdot(space *tile, space *dot)
{
- if (!(tile->flags & F_TILE_ASSOC)) return 1;
- if (tile->dotx == dot->x && tile->doty == dot->y) return 1;
- return 0;
+ if (!(tile->flags & F_TILE_ASSOC)) return true;
+ if (tile->dotx == dot->x && tile->doty == dot->y) return true;
+ return false;
}
static void solver_expand_fromdot(game_state *state, space *dot, solver_ctx *sctx)
@@ -2287,7 +2291,7 @@ solved:
*/
for (i = 0; i < tosolve->sx*tosolve->sy; i++)
tosolve->grid[i].flags &= ~F_TILE_ASSOC;
- ret = diff_game(currstate, tosolve, 1);
+ ret = diff_game(currstate, tosolve, true);
free_game(tosolve);
return ret;
}
@@ -2298,11 +2302,12 @@ solved:
*/
struct game_ui {
- int dragging;
+ bool dragging;
int dx, dy; /* pixel coords of drag pos. */
int dotx, doty; /* grid coords of dot we're dragging from. */
int srcx, srcy; /* grid coords of drag start */
- int cur_x, cur_y, cur_visible;
+ int cur_x, cur_y;
+ bool cur_visible;
};
static game_ui *new_ui(const game_state *state)
@@ -2310,7 +2315,7 @@ static game_ui *new_ui(const game_state *state)
game_ui *ui = snew(game_ui);
ui->dragging = false;
ui->cur_x = ui->cur_y = 1;
- ui->cur_visible = 0;
+ ui->cur_visible = false;
return ui;
}
@@ -2351,7 +2356,7 @@ static void game_changed_state(game_ui *ui, const game_state *oldstate,
#define CURSOR_SIZE DOT_SIZE
struct game_drawstate {
- int started;
+ bool started;
int w, h;
int tilesize;
unsigned long *grid;
@@ -2359,11 +2364,13 @@ struct game_drawstate {
blitter *bl;
blitter *blmirror;
- int dragging, dragx, dragy;
+ bool dragging;
+ int dragx, dragy;
int *colour_scratch;
- int cx, cy, cur_visible;
+ int cx, cy;
+ bool cur_visible;
blitter *cur_bl;
};
@@ -2474,13 +2481,13 @@ static char *interpret_move(const game_state *state, game_ui *ui,
char *ret;
game_state *tmp = dup_game(state);
solver_obvious(tmp);
- ret = diff_game(state, tmp, 0);
+ ret = diff_game(state, tmp, false);
free_game(tmp);
return ret;
}
if (button == LEFT_BUTTON) {
- ui->cur_visible = 0;
+ ui->cur_visible = false;
coord_round_to_edge(FROMCOORD((float)x), FROMCOORD((float)y),
&px, &py);
@@ -2495,7 +2502,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
} else if (button == RIGHT_BUTTON) {
int px1, py1;
- ui->cur_visible = 0;
+ ui->cur_visible = false;
px = (int)(2*FROMCOORD((float)x) + 0.5);
py = (int)(2*FROMCOORD((float)y) + 0.5);
@@ -2600,10 +2607,10 @@ static char *interpret_move(const game_state *state, game_ui *ui,
else
return UI_UPDATE;
} else if (IS_CURSOR_MOVE(button)) {
- move_cursor(button, &ui->cur_x, &ui->cur_y, state->sx-1, state->sy-1, 0);
+ move_cursor(button, &ui->cur_x, &ui->cur_y, state->sx-1, state->sy-1, false);
if (ui->cur_x < 1) ui->cur_x = 1;
if (ui->cur_y < 1) ui->cur_y = 1;
- ui->cur_visible = 1;
+ ui->cur_visible = true;
if (ui->dragging) {
ui->dx = SCOORD(ui->cur_x);
ui->dy = SCOORD(ui->cur_y);
@@ -2611,7 +2618,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
return UI_UPDATE;
} else if (IS_CURSOR_SELECT(button)) {
if (!ui->cur_visible) {
- ui->cur_visible = 1;
+ ui->cur_visible = true;
return UI_UPDATE;
}
sp = &SPACE(state, ui->cur_x, ui->cur_y);
@@ -2655,16 +2662,18 @@ static char *interpret_move(const game_state *state, game_ui *ui,
}
#endif
-static int check_complete(const game_state *state, int *dsf, int *colours)
+static bool check_complete(const game_state *state, int *dsf, int *colours)
{
int w = state->w, h = state->h;
- int x, y, i, ret;
+ int x, y, i;
+ bool ret;
- int free_dsf;
+ bool free_dsf;
struct sqdata {
int minx, miny, maxx, maxy;
int cx, cy;
- int valid, colour;
+ bool valid;
+ int colour;
} *sqdata;
if (!dsf) {
@@ -2819,7 +2828,7 @@ static int check_complete(const game_state *state, int *dsf, int *colours)
ret = true;
for (i = 0; i < w*h; i++) {
int ci = dsf_canonify(dsf, i);
- int thisok = sqdata[ci].valid;
+ bool thisok = sqdata[ci].valid;
if (colours)
colours[i] = thisok ? sqdata[ci].colour : 0;
ret = ret && thisok;
@@ -2837,7 +2846,7 @@ static game_state *execute_move(const game_state *state, const char *move)
int x, y, ax, ay, n, dx, dy;
game_state *ret = dup_game(state);
space *sp, *dot;
- int currently_solving = false;
+ bool currently_solving = false;
debug(("%s\n", move));
@@ -2924,11 +2933,11 @@ static game_state *execute_move(const game_state *state, const char *move)
#ifdef EDITOR
} else if (c == 'C') {
move++;
- clear_game(ret, 1);
+ clear_game(ret, true);
#endif
} else if (c == 'S') {
move++;
- ret->used_solve = 1;
+ ret->used_solve = true;
currently_solving = true;
} else
goto badmove;
@@ -2939,7 +2948,7 @@ static game_state *execute_move(const game_state *state, const char *move)
goto badmove;
}
if (check_complete(ret, NULL, NULL))
- ret->completed = 1;
+ ret->completed = true;
return ret;
badmove:
@@ -3051,7 +3060,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
struct game_drawstate *ds = snew(struct game_drawstate);
int i;
- ds->started = 0;
+ ds->started = false;
ds->w = state->w;
ds->h = state->h;
@@ -3070,7 +3079,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
ds->cur_bl = NULL;
ds->cx = ds->cy = 0;
- ds->cur_visible = 0;
+ ds->cur_visible = false;
return ds;
}
@@ -3221,7 +3230,8 @@ static void game_redraw(drawing *dr, game_drawstate *ds,
float animtime, float flashtime)
{
int w = ds->w, h = ds->h;
- int x, y, flashing = false;
+ int x, y;
+ bool flashing = false;
int oppx, oppy;
if (flashtime > 0) {
@@ -3696,7 +3706,7 @@ static void dump_state(game_state *state)
sfree(temp);
}
-static int gen(game_params *p, random_state *rs, int debug)
+static int gen(game_params *p, random_state *rs, bool debug)
{
char *desc;
int diff;
@@ -3708,7 +3718,7 @@ static int gen(game_params *p, random_state *rs, int debug)
printf("Generating a %dx%d %s puzzle.\n",
p->w, p->h, galaxies_diffnames[p->diff]);
- desc = new_game_desc(p, rs, NULL, 0);
+ desc = new_game_desc(p, rs, NULL, false);
state = new_game(NULL, p, desc);
dump_state(state);
@@ -3731,7 +3741,7 @@ static void soak(game_params *p, random_state *rs)
int diff, n = 0, i, diffs[DIFF_MAX], ndots = 0, nspaces = 0;
#ifndef DEBUGGING
- solver_show_working = 0;
+ solver_show_working = false;
#endif
tt_start = tt_now = time(NULL);
for (i = 0; i < DIFF_MAX; i++) diffs[i] = 0;
@@ -3745,7 +3755,7 @@ static void soak(game_params *p, random_state *rs)
printf("]\n");
while (1) {
- desc = new_game_desc(p, rs, NULL, 0);
+ desc = new_game_desc(p, rs, NULL, false);
st = new_game(NULL, p, desc);
diff = solver_state(st, p->diff);
nspaces += st->w*st->h;
@@ -3776,7 +3786,8 @@ int main(int argc, char **argv)
char *id = NULL, *desc;
const char *err;
game_state *s;
- int diff, do_soak = 0, verbose = 0;
+ int diff;
+ bool do_soak = false, verbose = false;
random_state *rs;
time_t seed = time(NULL);
@@ -3784,13 +3795,13 @@ int main(int argc, char **argv)
while (--argc > 0) {
char *p = *++argv;
if (!strcmp(p, "-v")) {
- verbose = 1;
+ verbose = true;
} else if (!strcmp(p, "--seed")) {
if (argc == 0) usage_exit("--seed needs an argument");
seed = (time_t)atoi(*++argv);
argc--;
} else if (!strcmp(p, "--soak")) {
- do_soak = 1;
+ do_soak = true;
} else if (*p == '-') {
usage_exit("unrecognised option");
} else {
@@ -3815,7 +3826,7 @@ int main(int argc, char **argv)
p->w = random_upto(rs, 15) + 3;
p->h = random_upto(rs, 15) + 3;
p->diff = random_upto(rs, DIFF_UNREASONABLE);
- diff = gen(p, rs, 0);
+ diff = gen(p, rs, false);
}
return 0;
}
@@ -3826,7 +3837,7 @@ int main(int argc, char **argv)
gen(p, rs, verbose);
} else {
#ifndef DEBUGGING
- solver_show_working = 1;
+ solver_show_working = true;
#endif
*desc++ = '\0';
decode_params(p, id);