shithub: puzzles

Download patch

ref: 5f5b284c0bddbe67de14b2d2bfb596bc7ba1298a
parent: a550ea0a47374705a37f36b0f05ffe9e4c8161fb
author: Simon Tatham <anakin@pobox.com>
date: Tue Nov 13 16:45:44 EST 2018

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.

--- a/blackbox.c
+++ b/blackbox.c
@@ -297,9 +297,10 @@
     int w, h, minballs, maxballs, nballs, nlasers;
     unsigned int *grid; /* (w+2)x(h+2), to allow for laser firing range */
     unsigned int *exits; /* one per laser */
-    int done;           /* user has finished placing his own balls. */
+    bool done;          /* user has finished placing his own balls. */
     int laserno;        /* number of next laser to be fired. */
-    int nguesses, reveal, justwrong, nright, nwrong, nmissed;
+    int nguesses, nright, nwrong, nmissed;
+    bool reveal, justwrong;
 };
 
 #define GRID(s,x,y) ((s)->grid[(y)*((s)->w+2) + (x)])
@@ -324,11 +325,11 @@
 };
 #endif
 
-static int range2grid(const game_state *state, int rangeno, int *x, int *y,
-                      int *direction)
+static bool range2grid(const game_state *state, int rangeno, int *x, int *y,
+                       int *direction)
 {
     if (rangeno < 0)
-        return 0;
+        return false;
 
     if (rangeno < state->w) {
         /* top row; from (1,0) to (w,0) */
@@ -335,7 +336,7 @@
         *x = rangeno + 1;
         *y = 0;
         *direction = DIR_DOWN;
-        return 1;
+        return true;
     }
     rangeno -= state->w;
     if (rangeno < state->h) {
@@ -343,7 +344,7 @@
         *x = state->w+1;
         *y = rangeno + 1;
         *direction = DIR_LEFT;
-        return 1;
+        return true;
     }
     rangeno -= state->h;
     if (rangeno < state->w) {
@@ -351,7 +352,7 @@
         *x = (state->w - rangeno);
         *y = state->h+1;
         *direction = DIR_UP;
-        return 1;
+        return true;
     }
     rangeno -= state->w;
     if (rangeno < state->h) {
@@ -359,20 +360,20 @@
         *x = 0;
         *y = (state->h - rangeno);
         *direction = DIR_RIGHT;
-        return 1;
+        return true;
     }
-    return 0;
+    return false;
 }
 
-static int grid2range(const game_state *state, int x, int y, int *rangeno)
+static bool grid2range(const game_state *state, int x, int y, int *rangeno)
 {
     int ret, x1 = state->w+1, y1 = state->h+1;
 
-    if (x > 0 && x < x1 && y > 0 && y < y1) return 0; /* in arena */
-    if (x < 0 || x > x1 || y < 0 || y > y1) return 0; /* outside grid */
+    if (x > 0 && x < x1 && y > 0 && y < y1) return false; /* in arena */
+    if (x < 0 || x > x1 || y < 0 || y > y1) return false; /* outside grid */
 
     if ((x == 0 || x == x1) && (y == 0 || y == y1))
-        return 0; /* one of 4 corners */
+        return false; /* one of 4 corners */
 
     if (y == 0) {               /* top line */
         ret = x - 1;
@@ -385,7 +386,7 @@
     }
     *rangeno = ret;
     debug(("grid2range: (%d,%d) rangeno = %d\n", x, y, ret));
-    return 1;
+    return true;
 }
 
 static game_state *new_game(midend *me, const game_params *params,
@@ -416,8 +417,10 @@
     }
     sfree(bmp);
 
-    state->done = state->nguesses = state->reveal = state->justwrong =
-        state->nright = state->nwrong = state->nmissed = 0;
+    state->done = false;
+    state->justwrong = false;
+    state->reveal = false;
+    state->nguesses = state->nright = state->nwrong = state->nmissed = 0;
     state->laserno = 1;
 
     return state;
@@ -475,8 +478,10 @@
 
 struct game_ui {
     int flash_laserno;
-    int errors, newmove;
-    int cur_x, cur_y, cur_visible;
+    int errors;
+    bool newmove;
+    int cur_x, cur_y;
+    bool cur_visible;
     int flash_laser; /* 0 = never, 1 = always, 2 = if anim. */
 };
 
@@ -488,7 +493,7 @@
     ui->newmove = false;
 
     ui->cur_x = ui->cur_y = 1;
-    ui->cur_visible = 0;
+    ui->cur_visible = false;
 
     ui->flash_laser = 0;
 
@@ -537,7 +542,7 @@
 
 /* Given a position and a direction, check whether we can see a ball in front
  * of us, or to our front-left or front-right. */
-static int isball(game_state *state, int gx, int gy, int direction, int lookwhere)
+static bool isball(game_state *state, int gx, int gy, int direction, int lookwhere)
 {
     debug(("isball, (%d, %d), dir %s, lookwhere %s\n", gx, gy, dirstrs[direction],
            lookwhere == LOOK_LEFT ? "LEFT" :
@@ -554,17 +559,18 @@
 
     /* if we're off the grid (into the firing range) there's never a ball. */
     if (gx < 1 || gy < 1 || gx > state->w || gy > state->h)
-        return 0;
+        return false;
 
     if (GRID(state, gx,gy) & BALL_CORRECT)
-        return 1;
+        return true;
 
-    return 0;
+    return false;
 }
 
 static int fire_laser_internal(game_state *state, int x, int y, int direction)
 {
-    int unused, lno, tmp;
+    int unused, lno;
+    bool tmp;
 
     tmp = grid2range(state, x, y, &lno);
     assert(tmp);
@@ -627,7 +633,8 @@
 
 static int laser_exit(game_state *state, int entryno)
 {
-    int tmp, x, y, direction;
+    int x, y, direction;
+    bool tmp;
 
     tmp = range2grid(state, entryno, &x, &y, &direction);
     assert(tmp);
@@ -637,7 +644,8 @@
 
 static void fire_laser(game_state *state, int entryno)
 {
-    int tmp, exitno, x, y, direction;
+    int exitno, x, y, direction;
+    bool tmp;
 
     tmp = range2grid(state, entryno, &x, &y, &direction);
     assert(tmp);
@@ -662,10 +670,11 @@
  * have already guessed). This is required because any layout with >4 balls
  * might have multiple valid solutions. Returns non-zero for a 'correct'
  * (i.e. consistent) layout. */
-static int check_guesses(game_state *state, int cagey)
+static int check_guesses(game_state *state, bool cagey)
 {
     game_state *solution, *guesses;
     int i, x, y, n, unused, tmp;
+    bool tmpb;
     int ret = 0;
 
     if (cagey) {
@@ -768,8 +777,8 @@
 
     /* clear out the lasers of solution */
     for (i = 0; i < solution->nlasers; i++) {
-        tmp = range2grid(solution, i, &x, &y, &unused);
-        assert(tmp);
+        tmpb = range2grid(solution, i, &x, &y, &unused);
+        assert(tmpb);
         GRID(solution, x, y) = 0;
         solution->exits[i] = LASER_EMPTY;
     }
@@ -799,8 +808,8 @@
     /* check each game_state's laser against the other; if any differ, return 0 */
     ret = 1;
     for (i = 0; i < solution->nlasers; i++) {
-        tmp = range2grid(solution, i, &x, &y, &unused);
-        assert(tmp);
+        tmpb = range2grid(solution, i, &x, &y, &unused);
+        assert(tmpb);
 
         if (solution->exits[i] != guesses->exits[i]) {
             /* If the original state didn't have this shot fired,
@@ -814,8 +823,8 @@
                 else {
                     /* add a new shot, incrementing state's laser count. */
                     int ex, ey, newno = state->laserno++;
-                    tmp = range2grid(state, state->exits[i], &ex, &ey, &unused);
-                    assert(tmp);
+                    tmpb = range2grid(state, state->exits[i], &ex, &ey, &unused);
+                    assert(tmpb);
                     GRID(state, x, y) = newno;
                     GRID(state, ex, ey) = newno;
                 }
@@ -857,7 +866,7 @@
     }
     free_game(solution);
     free_game(guesses);
-    state->reveal = 1;
+    state->reveal = true;
     return ret;
 }
 
@@ -873,8 +882,8 @@
 struct game_drawstate {
     int tilesize, crad, rrad, w, h; /* w and h to make macros work... */
     unsigned int *grid;          /* as the game_state grid */
-    int started, reveal;
-    int flash_laserno, isflash;
+    bool started, reveal, isflash;
+    int flash_laserno;
 };
 
 static char *interpret_move(const game_state *state, game_ui *ui,
@@ -889,7 +898,7 @@
     if (IS_CURSOR_MOVE(button)) {
         int cx = ui->cur_x, cy = ui->cur_y;
 
-        move_cursor(button, &cx, &cy, state->w+2, state->h+2, 0);
+        move_cursor(button, &cx, &cy, state->w+2, state->h+2, false);
         if ((cx == 0 && cy == 0 && !CAN_REVEAL(state)) ||
             (cx == 0 && cy == state->h+1) ||
             (cx == state->w+1 && cy == 0) ||
@@ -897,7 +906,7 @@
             return NULL; /* disallow moving cursor to corners. */
         ui->cur_x = cx;
         ui->cur_y = cy;
-        ui->cur_visible = 1;
+        ui->cur_visible = true;
         return UI_UPDATE;
     }
 
@@ -904,7 +913,7 @@
     if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
         gx = FROMDRAW(x);
         gy = FROMDRAW(y);
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
         wouldflash = 1;
     } else if (button == LEFT_RELEASE) {
         ui->flash_laser = 0;
@@ -916,7 +925,7 @@
             ui->flash_laser = 0;
             wouldflash = 2;
         } else {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
         /* Fix up 'button' for the below logic. */
@@ -974,7 +983,7 @@
 
     case REVEAL:
         if (!CAN_REVEAL(state)) return nullret;
-        if (ui->cur_visible == 1) ui->cur_x = ui->cur_y = 1;
+        if (ui->cur_visible) ui->cur_x = ui->cur_y = 1;
         sprintf(buf, "R");
         break;
 
@@ -1157,9 +1166,10 @@
     ds->w = state->w; ds->h = state->h;
     ds->grid = snewn((state->w+2)*(state->h+2), unsigned int);
     memset(ds->grid, 0, (state->w+2)*(state->h+2)*sizeof(unsigned int));
-    ds->started = ds->reveal = 0;
+    ds->started = false;
+    ds->reveal = false;
     ds->flash_laserno = LASER_EMPTY;
-    ds->isflash = 0;
+    ds->isflash = false;
 
     return ds;
 }
@@ -1182,7 +1192,7 @@
 
 static void draw_arena_tile(drawing *dr, const game_state *gs,
                             game_drawstate *ds, const game_ui *ui,
-                            int ax, int ay, int force, int isflash)
+                            int ax, int ay, bool force, bool isflash)
 {
     int gx = ax+1, gy = ay+1;
     int gs_tile = GRID(gs, gx, gy), ds_tile = GRID(ds, gx, gy);
@@ -1264,10 +1274,11 @@
 
 static void draw_laser_tile(drawing *dr, const game_state *gs,
                             game_drawstate *ds, const game_ui *ui,
-                            int lno, int force)
+                            int lno, bool force)
 {
     int gx, gy, dx, dy, unused;
-    int wrong, omitted, reflect, hit, laserval, flash = 0, tmp;
+    int wrong, omitted, laserval;
+    bool tmp, reflect, hit, flash = false;
     unsigned int gs_tile, ds_tile, exitno;
 
     tmp = range2grid(gs, lno, &gx, &gy, &unused);
@@ -1291,7 +1302,7 @@
         if (exitno == ds->flash_laserno)
             gs_tile |= LASER_FLASHED;
     }
-    if (gs_tile & LASER_FLASHED) flash = 1;
+    if (gs_tile & LASER_FLASHED) flash = true;
 
     gs_tile |= wrong | omitted;
 
@@ -1339,7 +1350,8 @@
                         int dir, const game_ui *ui,
                         float animtime, float flashtime)
 {
-    int i, x, y, ts = TILE_SIZE, isflash = 0, force = 0;
+    int i, x, y, ts = TILE_SIZE;
+    bool isflash = false, force = false;
 
     if (flashtime > 0) {
         int frame = (int)(flashtime / FLASH_FRAME);
@@ -1372,11 +1384,11 @@
 
         draw_update(dr, 0, 0,
                     TILE_SIZE * (state->w+3), TILE_SIZE * (state->h+3));
-        force = 1;
-        ds->started = 1;
+        force = true;
+        ds->started = true;
     }
 
-    if (isflash != ds->isflash) force = 1;
+    if (isflash != ds->isflash) force = true;
 
     /* draw the arena */
     for (x = 0; x < state->w; x++) {
--- a/bridges.c
+++ b/bridges.c
@@ -106,7 +106,8 @@
 struct game_params {
     int w, h, maxb;
     int islands, expansion;     /* %age of island squares, %age chance of expansion */
-    int allowloops, difficulty;
+    bool allowloops;
+    int difficulty;
 };
 
 /* general flags used by all structs */
@@ -155,7 +156,9 @@
 };
 
 struct game_state {
-    int w, h, completed, solved, allowloops, maxb;
+    int w, h, maxb;
+    bool completed, solved;
+    bool allowloops;
     grid_type *grid;
     struct island *islands;
     int n_islands, n_islands_alloc;
@@ -180,7 +183,7 @@
 
 #define GRIDCOUNT(s,x,y,f) ((GRID(s,x,y) & (f)) ? (INDEX(s,lines,x,y)) : 0)
 
-#define WITHIN2(x,min,max) (((x) < (min)) ? 0 : (((x) > (max)) ? 0 : 1))
+#define WITHIN2(x,min,max) ((x) >= (min) && (x) < (max))
 #define WITHIN(x,min,max) ((min) > (max) ? \
                            WITHIN2(x,max,min) : WITHIN2(x,min,max))
 
@@ -327,14 +330,14 @@
     }
 }
 
-static int island_hasbridge(struct island *is, int direction)
+static bool island_hasbridge(struct island *is, int direction)
 {
     int x = is->adj.points[direction].x;
     int y = is->adj.points[direction].y;
     grid_type gline = is->adj.points[direction].dx ? G_LINEH : G_LINEV;
 
-    if (GRID(is->state, x, y) & gline) return 1;
-    return 0;
+    if (GRID(is->state, x, y) & gline) return true;
+    return false;
 }
 
 static struct island *island_find_connection(struct island *is, int adjpt)
@@ -355,7 +358,7 @@
 static struct island *island_add(game_state *state, int x, int y, int count)
 {
     struct island *is;
-    int realloced = 0;
+    bool realloced = false;
 
     assert(!(GRID(state,x,y) & G_ISLAND));
     GRID(state,x,y) |= G_ISLAND;
@@ -365,7 +368,7 @@
         state->n_islands_alloc = state->n_islands * 2;
         state->islands =
             sresize(state->islands, state->n_islands_alloc, struct island);
-        realloced = 1;
+        realloced = true;
     }
     is = &state->islands[state->n_islands-1];
 
@@ -386,7 +389,7 @@
 
 
 /* n = -1 means 'flip NOLINE flags [and set line to 0].' */
-static void island_join(struct island *i1, struct island *i2, int n, int is_max)
+static void island_join(struct island *i1, struct island *i2, int n, bool is_max)
 {
     game_state *state = i1->state;
     int s, e, x, y;
@@ -455,7 +458,7 @@
     return c;
 }
 
-static int island_adjspace(struct island *is, int marks, int missing,
+static int island_adjspace(struct island *is, bool marks, int missing,
                            int direction)
 {
     int x, y, poss, curr, dx;
@@ -481,7 +484,7 @@
 
 /* Counts the number of bridge spaces left around the island;
  * expects the possibles to be up-to-date. */
-static int island_countspaces(struct island *is, int marks)
+static int island_countspaces(struct island *is, bool marks)
 {
     int i, c = 0, missing;
 
@@ -494,6 +497,7 @@
     return c;
 }
 
+/* Returns a bridge count rather than a boolean */
 static int island_isadj(struct island *is, int direction)
 {
     int x, y;
@@ -565,7 +569,7 @@
     }
 }
 
-static int island_impossible(struct island *is, int strict)
+static bool island_impossible(struct island *is, bool strict)
 {
     int curr = island_countbridges(is), nspc = is->count - curr, nsurrspc;
     int i, poss;
@@ -573,13 +577,13 @@
 
     if (nspc < 0) {
         debug(("island at (%d,%d) impossible because full.\n", is->x, is->y));
-        return 1;        /* too many bridges */
-    } else if ((curr + island_countspaces(is, 0)) < is->count) {
+        return true;        /* too many bridges */
+    } else if ((curr + island_countspaces(is, false)) < is->count) {
         debug(("island at (%d,%d) impossible because not enough spaces.\n", is->x, is->y));
-        return 1;        /* impossible to create enough bridges */
+        return true;        /* impossible to create enough bridges */
     } else if (strict && curr < is->count) {
         debug(("island at (%d,%d) impossible because locked.\n", is->x, is->y));
-        return 1;        /* not enough bridges and island is locked */
+        return true;        /* not enough bridges and island is locked */
     }
 
     /* Count spaces in surrounding islands. */
@@ -618,10 +622,10 @@
     if (nsurrspc < nspc) {
         debug(("island at (%d,%d) impossible: surr. islands %d spc, need %d.\n",
                is->x, is->y, nsurrspc, nspc));
-        return 1;       /* not enough spaces around surrounding islands to fill this one. */
+        return true;       /* not enough spaces around surrounding islands to fill this one. */
     }
 
-    return 0;
+    return false;
 }
 
 /* --- Game parameter functions --- */
@@ -705,10 +709,10 @@
         string++;
         EATNUM(params->maxb);
     }
-    params->allowloops = 1;
+    params->allowloops = true;
     if (*string == 'L') {
         string++;
-        params->allowloops = 0;
+        params->allowloops = false;
     }
     if (*string == 'd') {
         string++;
@@ -922,7 +926,8 @@
 
 static void map_update_possibles(game_state *state)
 {
-    int x, y, s, e, bl, i, np, maxb, w = state->w, idx;
+    int x, y, s, e, i, np, maxb, w = state->w, idx;
+    bool bl;
     struct island *is_s = NULL, *is_f = NULL;
 
     /* Run down vertical stripes [un]setting possv... */
@@ -929,7 +934,7 @@
     for (x = 0; x < state->w; x++) {
         idx = x;
         s = e = -1;
-        bl = 0;
+        bl = false;
         maxb = state->params.maxb;     /* placate optimiser */
         /* Unset possible flags until we find an island. */
         for (y = 0; y < state->h; y++) {
@@ -955,12 +960,12 @@
                     }
                 }
                 s = y+1;
-                bl = 0;
+                bl = false;
                 is_s = is_f;
                 maxb = is_s->count;
             } else {
                 e = y;
-                if (IDX(state,grid,idx) & (G_LINEH|G_NOLINEV)) bl = 1;
+                if (IDX(state,grid,idx) & (G_LINEH|G_NOLINEV)) bl = true;
             }
             idx += w;
         }
@@ -975,7 +980,7 @@
     for (y = 0; y < state->h; y++) {
         idx = y*w;
         s = e = -1;
-        bl = 0;
+        bl = false;
         maxb = state->params.maxb;     /* placate optimiser */
         for (x = 0; x < state->w; x++) {
             is_s = IDX(state, gridi, idx);
@@ -1000,12 +1005,12 @@
                     }
                 }
                 s = x+1;
-                bl = 0;
+                bl = false;
                 is_s = is_f;
                 maxb = is_s->count;
             } else {
                 e = x;
-                if (IDX(state,grid,idx) & (G_LINEV|G_NOLINEH)) bl = 1;
+                if (IDX(state,grid,idx) & (G_LINEV|G_NOLINEH)) bl = true;
             }
             idx += 1;
         }
@@ -1097,12 +1102,12 @@
         return -1;
 }
 
-static int map_hasloops(game_state *state, int mark)
+static bool map_hasloops(game_state *state, bool mark)
 {
     int x, y;
     struct findloopstate *fls;
     struct bridges_neighbour_ctx ctx;
-    int ret;
+    bool ret;
 
     fls = findloop_new_state(state->w * state->h);
     ctx.state = state;
@@ -1172,11 +1177,12 @@
     }
 }
 
-static int map_group_check(game_state *state, int canon, int warn,
-                           int *nislands_r)
+static bool map_group_check(game_state *state, int canon, bool warn,
+                            int *nislands_r)
 {
     int *dsf = state->solver->dsf, nislands = 0;
-    int x, y, i, allfull = 1;
+    int x, y, i;
+    bool allfull = true;
     struct island *is;
 
     for (i = 0; i < state->n_islands; i++) {
@@ -1186,7 +1192,7 @@
         GRID(state, is->x, is->y) |= G_SWEEP;
         nislands++;
         if (island_countbridges(is) != is->count)
-            allfull = 0;
+            allfull = false;
     }
     if (warn && allfull && nislands != state->n_islands) {
         /* we're full and this island group isn't the whole set.
@@ -1204,10 +1210,11 @@
     return allfull;
 }
 
-static int map_group_full(game_state *state, int *ngroups_r)
+static bool map_group_full(game_state *state, int *ngroups_r)
 {
     int *dsf = state->solver->dsf, ngroups = 0;
-    int i, anyfull = 0;
+    int i;
+    bool anyfull = false;
     struct island *is;
 
     /* NB this assumes map_group (or sth else) has cleared G_SWEEP. */
@@ -1218,8 +1225,8 @@
 
         ngroups++;
         if (map_group_check(state, dsf_canonify(dsf, DINDEX(is->x,is->y)),
-                            1, NULL))
-            anyfull = 1;
+                            true, NULL))
+            anyfull = true;
     }
 
     *ngroups_r = ngroups;
@@ -1226,14 +1233,14 @@
     return anyfull;
 }
 
-static int map_check(game_state *state)
+static bool map_check(game_state *state)
 {
     int ngroups;
 
     /* Check for loops, if necessary. */
     if (!state->allowloops) {
-        if (map_hasloops(state, 1))
-            return 0;
+        if (map_hasloops(state, true))
+            return false;
     }
 
     /* Place islands into island groups and check for early
@@ -1240,9 +1247,9 @@
      * satisfied-groups. */
     map_group(state); /* clears WARN and SWEEP */
     if (map_group_full(state, &ngroups)) {
-        if (ngroups == 1) return 1;
+        if (ngroups == 1) return true;
     }
-    return 0;
+    return false;
 }
 
 static void map_clear(game_state *state)
@@ -1257,7 +1264,7 @@
     }
 }
 
-static void solve_join(struct island *is, int direction, int n, int is_max)
+static void solve_join(struct island *is, int direction, int n, bool is_max)
 {
     struct island *is_orth;
     int d1, d2, *dsf = is->state->solver->dsf;
@@ -1290,7 +1297,7 @@
             if (island_hasbridge(is, i)) {
                 /* already attached; do nothing. */;
             } else {
-                solve_join(is, i, 1, 0);
+                solve_join(is, i, 1, false);
                 nadded++;
             }
         }
@@ -1311,13 +1318,13 @@
 
     /* very like island_countspaces. */
     for (i = 0; i < is->adj.npoints; i++) {
-        nnew = island_adjspace(is, 1, missing, i);
+        nnew = island_adjspace(is, true, missing, i);
         if (nnew) {
             ncurr = GRIDCOUNT(is->state,
                               is->adj.points[i].x, is->adj.points[i].y,
                               is->adj.points[i].dx ? G_LINEH : G_LINEV);
 
-            solve_join(is, i, nnew + ncurr, 0);
+            solve_join(is, i, nnew + ncurr, false);
             nadded += nnew;
         }
     }
@@ -1324,12 +1331,12 @@
     return nadded;
 }
 
-static int solve_island_stage1(struct island *is, int *didsth_r)
+static bool solve_island_stage1(struct island *is, bool *didsth_r)
 {
     int bridges = island_countbridges(is);
-    int nspaces = island_countspaces(is, 1);
+    int nspaces = island_countspaces(is, true);
     int nadj = island_countadj(is);
-    int didsth = 0;
+    bool didsth = false;
 
     assert(didsth_r);
 
@@ -1341,7 +1348,7 @@
          * another island has become wrong, the puzzle must not have had
          * a solution. */
         debug(("...island at (%d,%d) is overpopulated!\n", is->x, is->y));
-        return 0;
+        return false;
     } else if (bridges == is->count) {
         /* This island is full. Make sure it's marked (and update
          * possibles if we did). */
@@ -1348,57 +1355,61 @@
         if (!(GRID(is->state, is->x, is->y) & G_MARK)) {
             debug(("...marking island (%d,%d) as full.\n", is->x, is->y));
             island_togglemark(is);
-            didsth = 1;
+            didsth = true;
         }
     } else if (GRID(is->state, is->x, is->y) & G_MARK) {
         debug(("...island (%d,%d) is marked but unfinished!\n",
                is->x, is->y));
-        return 0; /* island has been marked unfinished; no solution from here. */
+        return false; /* island has been marked unfinished; no solution from here. */
     } else {
         /* This is the interesting bit; we try and fill in more information
          * about this island. */
         if (is->count == bridges + nspaces) {
-            if (solve_fill(is) > 0) didsth = 1;
+            if (solve_fill(is) > 0) didsth = true;
         } else if (is->count > ((nadj-1) * is->state->maxb)) {
             /* must have at least one bridge in each possible direction. */
-            if (solve_fillone(is) > 0) didsth = 1;
+            if (solve_fillone(is) > 0) didsth = true;
         }
     }
     if (didsth) {
         map_update_possibles(is->state);
-        *didsth_r = 1;
+        *didsth_r = true;
     }
-    return 1;
+    return true;
 }
 
-/* returns non-zero if a new line here would cause a loop. */
-static int solve_island_checkloop(struct island *is, int direction)
+/* returns true if a new line here would cause a loop. */
+static bool solve_island_checkloop(struct island *is, int direction)
 {
     struct island *is_orth;
     int *dsf = is->state->solver->dsf, d1, d2;
     game_state *state = is->state;
 
-    if (is->state->allowloops) return 0; /* don't care anyway */
-    if (island_hasbridge(is, direction)) return 0; /* already has a bridge */
-    if (island_isadj(is, direction) == 0) return 0; /* no adj island */
+    if (is->state->allowloops)
+        return false; /* don't care anyway */
+    if (island_hasbridge(is, direction))
+        return false; /* already has a bridge */
+    if (island_isadj(is, direction) == 0)
+        return false; /* no adj island */
 
     is_orth = INDEX(is->state, gridi,
                     ISLAND_ORTHX(is,direction),
                     ISLAND_ORTHY(is,direction));
-    if (!is_orth) return 0;
+    if (!is_orth) return false;
 
     d1 = DINDEX(is->x, is->y);
     d2 = DINDEX(is_orth->x, is_orth->y);
     if (dsf_canonify(dsf, d1) == dsf_canonify(dsf, d2)) {
         /* two islands are connected already; don't join them. */
-        return 1;
+        return true;
     }
-    return 0;
+    return false;
 }
 
-static int solve_island_stage2(struct island *is, int *didsth_r)
+static bool solve_island_stage2(struct island *is, bool *didsth_r)
 {
-    int added = 0, removed = 0, navail = 0, nadj, i;
+    int navail = 0, nadj, i;
+    bool added = false, removed = false;
 
     assert(didsth_r);
 
@@ -1406,9 +1417,9 @@
         if (solve_island_checkloop(is, i)) {
             debug(("removing possible loop at (%d,%d) direction %d.\n",
                    is->x, is->y, i));
-            solve_join(is, i, -1, 0);
+            solve_join(is, i, -1, false);
             map_update_possibles(is->state);
-            removed = 1;
+            removed = true;
         } else {
             navail += island_isadj(is, i);
             /*debug(("stage2: navail for (%d,%d) direction (%d,%d) is %d.\n",
@@ -1431,8 +1442,8 @@
                 debug(("island at (%d,%d) direction (%d,%d) must have 1 bridge\n",
                        is->x, is->y,
                        is->adj.points[i].dx, is->adj.points[i].dy));
-                solve_join(is, i, 1, 0);
-                added = 1;
+                solve_join(is, i, 1, false);
+                added = true;
                 /*debug_state(is->state);
                 debug_possibles(is->state);*/
             }
@@ -1439,11 +1450,11 @@
         }
     }
     if (added) map_update_possibles(is->state);
-    if (added || removed) *didsth_r = 1;
-    return 1;
+    if (added || removed) *didsth_r = true;
+    return true;
 }
 
-static int solve_island_subgroup(struct island *is, int direction)
+static bool solve_island_subgroup(struct island *is, int direction)
 {
     struct island *is_join;
     int nislands, *dsf = is->state->solver->dsf;
@@ -1454,7 +1465,7 @@
     /* if is isn't full, return 0. */
     if (island_countbridges(is) < is->count) {
         debug(("...orig island (%d,%d) not full.\n", is->x, is->y));
-        return 0;
+        return false;
     }
 
     if (direction >= 0) {
@@ -1467,27 +1478,27 @@
         if (island_countbridges(is_join) < is_join->count) {
             debug(("...dest island (%d,%d) not full.\n",
                    is_join->x, is_join->y));
-            return 0;
+            return false;
         }
     }
 
     /* Check group membership for is->dsf; if it's full return 1. */
     if (map_group_check(state, dsf_canonify(dsf, DINDEX(is->x,is->y)),
-                        0, &nislands)) {
+                        false, &nislands)) {
         if (nislands < state->n_islands) {
             /* we have a full subgroup that isn't the whole set.
              * This isn't allowed. */
             debug(("island at (%d,%d) makes full subgroup, disallowing.\n",
                    is->x, is->y));
-            return 1;
+            return true;
         } else {
             debug(("...has finished puzzle.\n"));
         }
     }
-    return 0;
+    return false;
 }
 
-static int solve_island_impossible(game_state *state)
+static bool solve_island_impossible(game_state *state)
 {
     struct island *is;
     int i;
@@ -1495,19 +1506,20 @@
     /* If any islands are impossible, return 1. */
     for (i = 0; i < state->n_islands; i++) {
         is = &state->islands[i];
-        if (island_impossible(is, 0)) {
+        if (island_impossible(is, false)) {
             debug(("island at (%d,%d) has become impossible, disallowing.\n",
                    is->x, is->y));
-            return 1;
+            return true;
         }
     }
-    return 0;
+    return false;
 }
 
 /* Bear in mind that this function is really rather inefficient. */
-static int solve_island_stage3(struct island *is, int *didsth_r)
+static bool solve_island_stage3(struct island *is, bool *didsth_r)
 {
-    int i, n, x, y, missing, spc, curr, maxb, didsth = 0;
+    int i, n, x, y, missing, spc, curr, maxb;
+    bool didsth = false;
     int wh = is->state->w * is->state->h;
     struct solver_state *ss = is->state->solver;
 
@@ -1514,12 +1526,12 @@
     assert(didsth_r);
 
     missing = is->count - island_countbridges(is);
-    if (missing <= 0) return 1;
+    if (missing <= 0) return true;
 
     for (i = 0; i < is->adj.npoints; i++) {
         x = is->adj.points[i].x;
         y = is->adj.points[i].y;
-        spc = island_adjspace(is, 1, missing, i);
+        spc = island_adjspace(is, true, missing, i);
         if (spc == 0) continue;
 
         curr = GRIDCOUNT(is->state, x, y,
@@ -1534,7 +1546,7 @@
          * it is additive only, and can't be removed from. */
         memcpy(ss->tmpdsf, ss->dsf, wh*sizeof(int));
         for (n = curr+1; n <= curr+spc; n++) {
-            solve_join(is, i, n, 0);
+            solve_join(is, i, n, false);
             map_update_possibles(is->state);
 
             if (solve_island_subgroup(is, i) ||
@@ -1547,7 +1559,7 @@
                 break;
             }
         }
-        solve_join(is, i, curr, 0); /* put back to before. */
+        solve_join(is, i, curr, false); /* put back to before. */
         memcpy(ss->dsf, ss->tmpdsf, wh*sizeof(int));
 
         if (maxb != -1) {
@@ -1554,12 +1566,12 @@
             /*debug_state(is->state);*/
             if (maxb == 0) {
                 debug(("...adding NOLINE.\n"));
-                solve_join(is, i, -1, 0); /* we can't have any bridges here. */
+                solve_join(is, i, -1, false); /* we can't have any bridges here. */
             } else {
                 debug(("...setting maximum\n"));
-                solve_join(is, i, maxb, 1);
+                solve_join(is, i, maxb, true);
             }
-            didsth = 1;
+            didsth = true;
         }
         map_update_possibles(is->state);
     }
@@ -1603,11 +1615,11 @@
          * recording the idea that at least one of two edges must have
          * a bridge.
          */
-        int got = 0;
+        bool got = false;
         int before[4];
         int j;
 
-        spc = island_adjspace(is, 1, missing, i);
+        spc = island_adjspace(is, true, missing, i);
         if (spc == 0) continue;
 
         for (j = 0; j < is->adj.npoints; j++)
@@ -1620,18 +1632,18 @@
         memcpy(ss->tmpdsf, ss->dsf, wh*sizeof(int));
 
         for (j = 0; j < is->adj.npoints; j++) {
-            spc = island_adjspace(is, 1, missing, j);
+            spc = island_adjspace(is, true, missing, j);
             if (spc == 0) continue;
             if (j == i) continue;
-            solve_join(is, j, before[j] + spc, 0);
+            solve_join(is, j, before[j] + spc, false);
         }
         map_update_possibles(is->state);
 
         if (solve_island_subgroup(is, -1))
-            got = 1;
+            got = true;
 
         for (j = 0; j < is->adj.npoints; j++)
-            solve_join(is, j, before[j], 0);
+            solve_join(is, j, before[j], false);
         memcpy(ss->dsf, ss->tmpdsf, wh*sizeof(int));
 
         if (got) {
@@ -1638,8 +1650,8 @@
             debug(("island at (%d,%d) must connect in direction (%d,%d) to"
                    " avoid full subgroup.\n",
                    is->x, is->y, is->adj.points[i].dx, is->adj.points[i].dy));
-            solve_join(is, i, 1, 0);
-            didsth = 1;
+            solve_join(is, i, 1, false);
+            didsth = true;
         }
 
         map_update_possibles(is->state);
@@ -1646,7 +1658,7 @@
     }
 
     if (didsth) *didsth_r = didsth;
-    return 1;
+    return true;
 }
 
 #define CONTINUE_IF_FULL do {                           \
@@ -1658,10 +1670,10 @@
 static int solve_sub(game_state *state, int difficulty, int depth)
 {
     struct island *is;
-    int i, didsth;
+    int i;
 
     while (1) {
-        didsth = 0;
+        bool didsth = false;
 
         /* First island iteration: things we can work out by looking at
          * properties of the island as a whole. */
@@ -1747,7 +1759,8 @@
     ret->gridi = snewn(wh, struct island *);
     for (i = 0; i < wh; i++) ret->gridi[i] = NULL;
 
-    ret->solved = ret->completed = 0;
+    ret->solved = false;
+    ret->completed = false;
 
     ret->solver = snew(struct solver_state);
     ret->solver->dsf = snew_dsf(wh);
@@ -1920,7 +1933,7 @@
 
         ni_curr++; ni_bad = 0;
 join:
-        island_join(is, is2, random_upto(rs, tobuild->maxb)+1, 0);
+        island_join(is, is2, random_upto(rs, tobuild->maxb)+1, false);
         debug_state(tobuild);
         continue;
 
@@ -2079,10 +2092,12 @@
     int dragx_src, dragy_src;   /* source; -1 means no drag */
     int dragx_dst, dragy_dst;   /* src's closest orth island. */
     grid_type todraw;
-    int dragging, drag_is_noline, nlines;
+    bool dragging, drag_is_noline;
+    int nlines;
 
-    int cur_x, cur_y, cur_visible;      /* cursor position */
-    int show_hints;
+    int cur_x, cur_y;           /* cursor position */
+    bool cur_visible;
+    bool show_hints;
 };
 
 static char *ui_cancel_drag(game_ui *ui)
@@ -2089,7 +2104,7 @@
 {
     ui->dragx_src = ui->dragy_src = -1;
     ui->dragx_dst = ui->dragy_dst = -1;
-    ui->dragging = 0;
+    ui->dragging = false;
     return UI_UPDATE;
 }
 
@@ -2099,8 +2114,8 @@
     ui_cancel_drag(ui);
     ui->cur_x = state->islands[0].x;
     ui->cur_y = state->islands[0].y;
-    ui->cur_visible = 0;
-    ui->show_hints = 0;
+    ui->cur_visible = false;
+    ui->show_hints = false;
     return ui;
 }
 
@@ -2128,7 +2143,7 @@
     int w, h;
     unsigned long *grid, *newgrid;
     int *lv, *lh;
-    int started, dragging;
+    bool started, dragging;
 };
 
 /*
@@ -2312,12 +2327,12 @@
     int gx = FROMCOORD(x), gy = FROMCOORD(y);
     char buf[80], *ret;
     grid_type ggrid = INGRID(state,gx,gy) ? GRID(state,gx,gy) : 0;
-    int shift = button & MOD_SHFT, control = button & MOD_CTRL;
+    bool shift = button & MOD_SHFT, control = button & MOD_CTRL;
     button &= ~MOD_MASK;
 
     if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
         if (!INGRID(state, gx, gy)) return NULL;
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
         if (ggrid & G_ISLAND) {
             ui->dragx_src = gx;
             ui->dragy_src = gy;
@@ -2328,8 +2343,8 @@
         if (INGRID(state, ui->dragx_src, ui->dragy_src)
                 && (gx != ui->dragx_src || gy != ui->dragy_src)
                 && !(GRID(state,ui->dragx_src,ui->dragy_src) & G_MARK)) {
-            ui->dragging = 1;
-            ui->drag_is_noline = (button == RIGHT_DRAG) ? 1 : 0;
+            ui->dragging = true;
+            ui->drag_is_noline = (button == RIGHT_DRAG);
             return update_drag_dst(state, ui, ds, x, y);
         } else {
             /* cancel a drag when we go back to the starting point */
@@ -2358,7 +2373,7 @@
         free_game(solved);
         return ret;
     } else if (IS_CURSOR_MOVE(button)) {
-        ui->cur_visible = 1;
+        ui->cur_visible = true;
         if (control || shift) {
             ui->dragx_src = ui->cur_x;
             ui->dragy_src = ui->cur_y;
@@ -2368,7 +2383,7 @@
         if (ui->dragging) {
             int nx = ui->cur_x, ny = ui->cur_y;
 
-            move_cursor(button, &nx, &ny, state->w, state->h, 0);
+            move_cursor(button, &nx, &ny, state->w, state->h, false);
             if (nx == ui->cur_x && ny == ui->cur_y)
                 return NULL;
             update_drag_dst(state, ui, ds,
@@ -2398,9 +2413,9 @@
              * before closer islands slightly offset). Swap the order of
              * these two loops to change to breadth-first search. */
             for (orth = 0; ; orth++) {
-                int oingrid = 0;
+                bool oingrid = false;
                 for (dir = 1; ; dir++) {
-                    int dingrid = 0;
+                    bool dingrid = false;
 
                     if (orth > dir) continue; /* only search in cone outwards. */
 
@@ -2407,7 +2422,8 @@
                     nx = ui->cur_x + dir*dx + orth*dorthx*orthorder;
                     ny = ui->cur_y + dir*dy + orth*dorthy*orthorder;
                     if (INGRID(state, nx, ny)) {
-                        dingrid = oingrid = 1;
+                        dingrid = true;
+                        oingrid = true;
                         if (GRID(state, nx, ny) & G_ISLAND) goto found;
                     }
 
@@ -2414,7 +2430,8 @@
                     nx = ui->cur_x + dir*dx - orth*dorthx*orthorder;
                     ny = ui->cur_y + dir*dy - orth*dorthy*orthorder;
                     if (INGRID(state, nx, ny)) {
-                        dingrid = oingrid = 1;
+                        dingrid = true;
+                        oingrid = true;
                         if (GRID(state, nx, ny) & G_ISLAND) goto found;
                     }
 
@@ -2431,7 +2448,7 @@
         }
     } else if (IS_CURSOR_SELECT(button)) {
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
         if (ui->dragging || button == CURSOR_SELECT2) {
@@ -2444,11 +2461,11 @@
         } else {
             grid_type v = GRID(state, ui->cur_x, ui->cur_y);
             if (v & G_ISLAND) {
-                ui->dragging = 1;
+                ui->dragging = true;
                 ui->dragx_src = ui->cur_x;
                 ui->dragy_src = ui->cur_y;
                 ui->dragx_dst = ui->dragy_dst = -1;
-                ui->drag_is_noline = (button == CURSOR_SELECT2) ? 1 : 0;
+                ui->drag_is_noline = (button == CURSOR_SELECT2);
                 return UI_UPDATE;
             }
         }
@@ -2466,7 +2483,7 @@
             number = 10 + button - 'A';
 
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
 
@@ -2498,7 +2515,7 @@
         } else
             return NULL;
     } else if (button == 'g' || button == 'G') {
-        ui->show_hints = 1 - ui->show_hints;
+        ui->show_hints = !ui->show_hints;
         return UI_UPDATE;
     }
 
@@ -2530,7 +2547,7 @@
             is2 = INDEX(ret, gridi, x2, y2);
             if (!is1 || !is2) goto badmove;
             if (nl < 0 || nl > state->maxb) goto badmove;
-            island_join(is1, is2, nl, 0);
+            island_join(is1, is2, nl, false);
         } else if (c == 'N') {
             if (sscanf(move, "%d,%d,%d,%d%n",
                        &x1, &y1, &x2, &y2, &n) != 4)
@@ -2540,7 +2557,7 @@
             is1 = INDEX(ret, gridi, x1, y1);
             is2 = INDEX(ret, gridi, x2, y2);
             if (!is1 || !is2) goto badmove;
-            island_join(is1, is2, -1, 0);
+            island_join(is1, is2, -1, false);
         } else if (c == 'M') {
             if (sscanf(move, "%d,%d%n",
                        &x1, &y1, &n) != 2)
@@ -2562,7 +2579,7 @@
     map_update_possibles(ret);
     if (map_check(ret)) {
         debug(("Game completed.\n"));
-        ret->completed = 1;
+        ret->completed = true;
     }
     return ret;
 
@@ -2660,8 +2677,8 @@
     ds->tilesize = 0;
     ds->w = state->w;
     ds->h = state->h;
-    ds->started = 0;
-    ds->dragging = 0;
+    ds->started = false;
+    ds->dragging = false;
     ds->grid = snewn(wh, unsigned long);
     for (i = 0; i < wh; i++)
         ds->grid[i] = ~0UL;
@@ -2688,8 +2705,8 @@
 
 #define OFFSET(thing) ((TILE_SIZE/2) - ((thing)/2))
 
-static int between_island(const game_state *state, int sx, int sy,
-                          int dx, int dy)
+static bool between_island(const game_state *state, int sx, int sy,
+                           int dx, int dy)
 {
     int x = sx - dx, y = sy - dy;
 
@@ -2697,14 +2714,14 @@
         if (GRID(state, x, y) & G_ISLAND) goto found;
         x -= dx; y -= dy;
     }
-    return 0;
+    return false;
 found:
     x = sx + dx, y = sy + dy;
     while (INGRID(state, x, y)) {
-        if (GRID(state, x, y) & G_ISLAND) return 1;
+        if (GRID(state, x, y) & G_ISLAND) return true;
         x += dx; y += dy;
     }
-    return 0;
+    return false;
 }
 
 static void lines_lvlh(const game_state *state, const game_ui *ui,
@@ -2945,7 +2962,8 @@
                         float animtime, float flashtime)
 {
     int x, y, lv, lh;
-    grid_type v, flash = 0;
+    grid_type v;
+    bool flash = false;
     struct island *is, *is_drag_src = NULL, *is_drag_dst = NULL;
 
     if (flashtime) {
@@ -2967,11 +2985,11 @@
         draw_update(dr, 0, 0,
                     TILE_SIZE * ds->w + 2 * BORDER,
                     TILE_SIZE * ds->h + 2 * BORDER);
-        ds->started = 1;
+        ds->started = true;
     }
 
     if (ui->dragx_src != -1 && ui->dragy_src != -1) {
-        ds->dragging = 1;
+        ds->dragging = true;
         is_drag_src = INDEX(state, gridi, ui->dragx_src, ui->dragy_src);
         assert(is_drag_src);
         if (ui->dragx_dst != -1 && ui->dragy_dst != -1) {
@@ -2979,7 +2997,7 @@
             assert(is_drag_dst);
         }
     } else
-        ds->dragging = 0;
+        ds->dragging = false;
 
     /*
      * Set up ds->newgrid with the current grid contents.
@@ -3031,7 +3049,7 @@
                     INDEX(ds,newgrid,x,y+1) |= idata << D_L_ISLAND_SHIFT_U;
             } else {
                 unsigned long hdata, vdata;
-                int selh = false, selv = false;
+                bool selh = false, selv = false;
 
                 /*
                  * A line (non-island) square. Compute the drawing
--- a/cube.c
+++ b/cube.c
@@ -178,7 +178,7 @@
     int npoints;
     float points[8];                   /* maximum */
     int directions[8];                 /* bit masks showing point pairs */
-    int flip;
+    bool flip;
     int tetra_class;
 };
 
@@ -220,7 +220,7 @@
     int dpkey[2];                      /* key-point indices into polyhedron */
     int previous;
     float angle;
-    int completed;
+    int completed;                     /* stores move count at completion */
     int movecount;
 };
 
@@ -599,7 +599,7 @@
 {
     struct grid_data data;
     int i, j, k, m, area, facesperclass;
-    int *flags;
+    bool *flags;
     char *desc, *p;
 
     /*
@@ -634,7 +634,7 @@
      * So now we know how many faces to allocate in each class. Get
      * on with it.
      */
-    flags = snewn(area, int);
+    flags = snewn(area, bool);
     for (i = 0; i < area; i++)
 	flags[i] = false;
 
@@ -727,8 +727,8 @@
     return best;
 }
 
-static int align_poly(const struct solid *solid, struct grid_square *sq,
-                      int *pkey)
+static bool align_poly(const struct solid *solid, struct grid_square *sq,
+                       int *pkey)
 {
     float zmin;
     int i, j;
@@ -775,7 +775,7 @@
     return true;
 }
 
-static void flip_poly(struct solid *solid, int flip)
+static void flip_poly(struct solid *solid, bool flip)
 {
     int i;
 
@@ -791,7 +791,7 @@
     }
 }
 
-static struct solid *transform_poly(const struct solid *solid, int flip,
+static struct solid *transform_poly(const struct solid *solid, bool flip,
                                     int key0, int key1, float angle)
 {
     struct solid *ret = snew(struct solid);
@@ -938,7 +938,7 @@
      */
     {
         int pkey[4];
-        int ret;
+        bool ret;
 
         ret = align_poly(state->solid, &state->grid->squares[state->current], pkey);
         assert(ret);
@@ -1312,7 +1312,7 @@
      */
     {
         int all_pkey[4];
-        int success;
+        bool success;
 
         if (from->solid->order == 4 && direction == UP)
             angle = -angle;            /* HACK */
@@ -1418,7 +1418,7 @@
      */
     {
         int pkey[4];
-        int success;
+        bool success;
 
         success = align_poly(ret->solid, &ret->grid->squares[ret->current], pkey);
         assert(success);
--- a/divvy.c
+++ b/divvy.c
@@ -212,7 +212,7 @@
  * (This only works _because_ we've ensured the omino is simply
  * connected.)
  */
-static int addremcommon(int w, int h, int x, int y, int *own, int val)
+static bool addremcommon(int w, int h, int x, int y, int *own, int val)
 {
     int neighbours[8];
     int dir, count;
@@ -239,8 +239,8 @@
 
     for (dir = 0; dir < 8; dir++) {
 	int next = (dir + 1) & 7;
-	int gotthis = (neighbours[dir] == val);
-	int gotnext = (neighbours[next] == val);
+        bool gotthis = (neighbours[dir] == val);
+	bool gotnext = (neighbours[next] == val);
 
 	if (gotthis != gotnext)
 	    count++;
@@ -262,7 +262,8 @@
  */
 static int *divvy_internal(int w, int h, int k, random_state *rs)
 {
-    int *order, *queue, *tmp, *own, *sizes, *addable, *removable, *retdsf;
+    int *order, *queue, *tmp, *own, *sizes, *addable, *retdsf;
+    bool *removable;
     int wh = w*h;
     int i, j, n, x, y, qhead, qtail;
 
@@ -275,7 +276,7 @@
     sizes = snewn(n, int);
     queue = snewn(n, int);
     addable = snewn(wh*4, int);
-    removable = snewn(wh, int);
+    removable = snewn(wh, bool);
 
     /*
      * Permute the grid squares into a random order, which will be
--- a/dominosa.c
+++ b/dominosa.c
@@ -98,7 +98,7 @@
 
 struct game_params {
     int n;
-    int unique;
+    bool unique;
 };
 
 struct game_numbers {
@@ -117,7 +117,7 @@
     struct game_numbers *numbers;
     int *grid;
     unsigned short *edges;             /* h x w */
-    int completed, cheated;
+    bool completed, cheated;
 };
 
 static game_params *default_params(void)
@@ -352,7 +352,7 @@
 #endif
 
     while (1) {
-        int done_something = false;
+        bool done_something = false;
 
         /*
          * For each domino, look at its possible placements, and
@@ -861,7 +861,8 @@
         state->numbers->numbers[i] = j;
     }
 
-    state->completed = state->cheated = false;
+    state->completed = false;
+    state->cheated = false;
 
     return state;
 }
@@ -1040,7 +1041,8 @@
 }
 
 struct game_ui {
-    int cur_x, cur_y, cur_visible, highlight_1, highlight_2;
+    int cur_x, cur_y, highlight_1, highlight_2;
+    bool cur_visible;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1047,7 +1049,7 @@
 {
     game_ui *ui = snew(game_ui);
     ui->cur_x = ui->cur_y = 0;
-    ui->cur_visible = 0;
+    ui->cur_visible = false;
     ui->highlight_1 = ui->highlight_2 = -1;
     return ui;
 }
@@ -1070,7 +1072,7 @@
                                const game_state *newstate)
 {
     if (!oldstate->completed && newstate->completed)
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
 }
 
 #define PREFERRED_TILESIZE 32
@@ -1085,7 +1087,7 @@
 #define FROMCOORD(x) ( ((x) - BORDER + TILESIZE) / TILESIZE - 1 )
 
 struct game_drawstate {
-    int started;
+    bool started;
     int w, h, tilesize;
     unsigned long *visible;
 };
@@ -1134,13 +1136,13 @@
             (state->grid[d1] != d1 || state->grid[d2] != d2))
             return NULL;
 
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
         sprintf(buf, "%c%d,%d", (int)(button == RIGHT_BUTTON ? 'E' : 'D'), d1, d2);
         return dupstr(buf);
     } else if (IS_CURSOR_MOVE(button)) {
-	ui->cur_visible = 1;
+	ui->cur_visible = true;
 
-        move_cursor(button, &ui->cur_x, &ui->cur_y, 2*w-1, 2*h-1, 0);
+        move_cursor(button, &ui->cur_x, &ui->cur_y, 2*w-1, 2*h-1, false);
 
 	return UI_UPDATE;
     } else if (IS_CURSOR_SELECT(button)) {
@@ -1305,7 +1307,7 @@
      */
     if (!ret->completed) {
         int i, ok = 0;
-        unsigned char *used = snewn(TRI(n+1), unsigned char);
+        bool *used = snewn(TRI(n+1), bool);
 
         memset(used, 0, TRI(n+1));
         for (i = 0; i < wh; i++)
@@ -1319,7 +1321,7 @@
                 assert(di >= 0 && di < TRI(n+1));
 
                 if (!used[di]) {
-                    used[di] = 1;
+                    used[di] = true;
                     ok++;
                 }
             }
--- a/dsf.c
+++ b/dsf.c
@@ -129,13 +129,13 @@
     index = start_index;
     while (index != canonical_index) {
 	int nextindex = dsf[index] >> 2;
-        int nextinverse = inverse ^ (dsf[index] & 1);
+        bool nextinverse = inverse ^ (dsf[index] & 1);
 	dsf[index] = (canonical_index << 2) | inverse;
         inverse = nextinverse;
 	index = nextindex;
     }
 
-    assert(inverse == 0);
+    assert(!inverse);
 
 /*    fprintf(stderr, "Return %2d\n", index); */
     
@@ -161,7 +161,6 @@
     if (v1 == v2)
         assert(!inverse);
     else {
-	assert(inverse == 0 || inverse == 1);
 	/*
 	 * We always make the smaller of v1 and v2 the new canonical
 	 * element. This ensures that the canonical element of any
@@ -182,7 +181,7 @@
 	    v2 = v3;
 	}
 	dsf[v1] += (dsf[v2] >> 2) << 2;
-	dsf[v2] = (v1 << 2) | !!inverse;
+	dsf[v2] = (v1 << 2) | inverse;
     }
     
     v2 = edsf_canonify(dsf, v2, &i2);
--- a/emcc.c
+++ b/emcc.c
@@ -67,7 +67,7 @@
 extern void js_select_preset(int n);
 extern void js_get_date_64(unsigned *p);
 extern void js_update_permalinks(const char *desc, const char *seed);
-extern void js_enable_undo_redo(int undo, int redo);
+extern void js_enable_undo_redo(bool undo, bool redo);
 extern void js_activate_timer();
 extern void js_deactivate_timer();
 extern void js_canvas_start_draw(void);
@@ -101,7 +101,7 @@
 extern void js_dialog_string(int i, const char *title, const char *initvalue);
 extern void js_dialog_choices(int i, const char *title, const char *choicelist,
                               int initvalue);
-extern void js_dialog_boolean(int i, const char *title, int initvalue);
+extern void js_dialog_boolean(int i, const char *title, bool initvalue);
 extern void js_dialog_launch(void);
 extern void js_dialog_cleanup(void);
 extern void js_focus_canvas(void);
@@ -171,7 +171,7 @@
 /* ----------------------------------------------------------------------
  * Timing functions.
  */
-int timer_active = false;
+bool timer_active = false;
 void deactivate_timer(frontend *fe)
 {
     js_deactivate_timer();
@@ -277,7 +277,7 @@
  * Keyboard handler called from JS.
  */
 void key(int keycode, int charcode, const char *key, const char *chr,
-         int shift, int ctrl)
+         bool shift, bool ctrl)
 {
     int keyevent = -1;
 
@@ -554,7 +554,7 @@
  */
 static game_params **presets;
 static int npresets;
-int have_presets_dropdown;
+bool have_presets_dropdown;
 
 void populate_js_preset_menu(int menuid, struct preset_menu *menu)
 {
@@ -651,7 +651,7 @@
  * or false respectively, in those cases. We terminate the dialog box,
  * unless the user selected an invalid combination of parameters.
  */
-static void cfg_end(int use_results)
+static void cfg_end(bool use_results)
 {
     if (use_results) {
         /*
--- a/fifteen.c
+++ b/fifteen.c
@@ -46,8 +46,8 @@
     int w, h, n;
     int *tiles;
     int gap_pos;
-    int completed;
-    int used_solve;		       /* used to suppress completion flash */
+    int completed;             /* move count at time of completion */
+    bool used_solve;           /* used to suppress completion flash */
     int movecount;
 };
 
@@ -161,7 +161,8 @@
 {
     int gap, n, i, x;
     int x1, x2, p1, p2, parity;
-    int *tiles, *used;
+    int *tiles;
+    bool *used;
     char *ret;
     int retlen;
 
@@ -168,7 +169,7 @@
     n = params->w * params->h;
 
     tiles = snewn(n, int);
-    used = snewn(n, int);
+    used = snewn(n, bool);
 
     for (i = 0; i < n; i++) {
         tiles[i] = -1;
@@ -275,13 +276,13 @@
     const char *p;
     const char *err;
     int i, area;
-    int *used;
+    bool *used;
 
     area = params->w * params->h;
     p = desc;
     err = NULL;
 
-    used = snewn(area, int);
+    used = snewn(area, bool);
     for (i = 0; i < area; i++)
 	used[i] = false;
 
@@ -455,7 +456,7 @@
 }
 
 struct game_drawstate {
-    int started;
+    bool started;
     int w, h, bgcolour;
     int *tiles;
     int tilesize;
@@ -521,7 +522,7 @@
 {
     const int to_tile_x = (gx < nx ? +1 : -1);
     const int to_goal_x = (gx < tx ? +1 : -1);
-    const int gap_x_on_goal_side = ((nx-tx) * (nx-gx) > 0);
+    const bool gap_x_on_goal_side = ((nx-tx) * (nx-gx) > 0);
 
     assert (nx != tx || ny != ty); /* not already in place */
     assert (nx != gx || ny != gy); /* not placing the gap */
@@ -608,7 +609,7 @@
         *dx = to_tile_x;
 }
 
-static int compute_hint(const game_state *state, int *out_x, int *out_y)
+static bool compute_hint(const game_state *state, int *out_x, int *out_y)
 {
     /* The overall solving process is this:
      * 1. Find the next piece to be put in its place
@@ -1129,11 +1130,12 @@
     game_state *state;
     char *id = NULL, *desc;
     const char *err;
-    int grade = false;
+    bool grade = false;
     char *progname = argv[0];
 
     char buf[80];
-    int limit, x, y, solvable;
+    int limit, x, y;
+    bool solvable;
 
     while (--argc > 0) {
         char *p = *++argv;
--- a/filling.c
+++ b/filling.c
@@ -66,7 +66,7 @@
 
 #include "puzzles.h"
 
-static unsigned char verbose;
+static bool verbose;
 
 static void printv(const char *fmt, ...) {
 #ifndef PALM
@@ -96,7 +96,7 @@
 struct game_state {
     int *board;
     struct shared_state *shared;
-    int completed, cheated;
+    bool completed, cheated;
 };
 
 static const struct game_params filling_defaults[3] = {
@@ -312,7 +312,7 @@
 
 #define SENTINEL sz
 
-static int mark_region(int *board, int w, int h, int i, int n, int m) {
+static bool mark_region(int *board, int w, int h, int i, int n, int m) {
     int j;
 
     board[i] = -1;
@@ -345,7 +345,8 @@
 {
     const int sz = w * h;
     const int maxsize = min(max(max(w, h), 3), 9);
-    int i, j, k, change;
+    int i, j, k;
+    bool change;
     do {
         change = false;
         for (i = 0; i < sz; ++i) {
@@ -353,7 +354,9 @@
 
             for (j = 0; j < 4; ++j, board[i] = 1) {
                 const int x = (i % w) + dx[j], y = (i / w) + dy[j];
-                int oldsize, newsize, ok, ii = w*y + x;
+                int oldsize, newsize, ii = w*y + x;
+		bool ok;
+
                 if (x < 0 || x >= w || y < 0 || y >= h) continue;
                 if (board[ii] == maxsize) continue;
 
@@ -387,7 +390,8 @@
     /* Note that if 1 in {w, h} then it's impossible to have a region
      * of size > w*h, so the special case only affects w=h=2. */
 
-    int i, change, *dsf;
+    int i, *dsf;
+    bool change;
 
     assert(w >= 1);
     assert(h >= 1);
@@ -407,7 +411,8 @@
         for (i = 0; i < sz; ++i) {
             const int square = dsf_canonify(dsf, board[i]);
             const int size = dsf_size(dsf, square);
-            int merge = SENTINEL, min = maxsize - size + 1, error = false;
+            int merge = SENTINEL, min = maxsize - size + 1;
+	    bool error = false;
             int neighbour, neighbour_size, j;
 
             for (j = 0; j < 4; ++j) {
@@ -520,7 +525,7 @@
     }
 }
 
-static int check_capacity(int *board, int w, int h, int i) {
+static bool check_capacity(int *board, int w, int h, int i) {
     int n = board[i];
     flood_count(board, w, h, i, board[i], &n);
     clear_count(board, w * h);
@@ -625,16 +630,16 @@
         else filled_square(s, w, h, i);
 }
 
-static int learn_expand_or_one(struct solver_state *s, int w, int h) {
+static bool learn_expand_or_one(struct solver_state *s, int w, int h) {
     const int sz = w * h;
     int i;
-    int learn = false;
+    bool learn = false;
 
     assert(s);
 
     for (i = 0; i < sz; ++i) {
 	int j;
-	int one = true;
+	bool one = true;
 
 	if (s->board[i] != EMPTY) continue;
 
@@ -675,10 +680,10 @@
     return learn;
 }
 
-static int learn_blocked_expansion(struct solver_state *s, int w, int h) {
+static bool learn_blocked_expansion(struct solver_state *s, int w, int h) {
     const int sz = w * h;
     int i;
-    int learn = false;
+    bool learn = false;
 
     assert(s);
     /* for every connected component */
@@ -767,10 +772,10 @@
     return learn;
 }
 
-static int learn_critical_square(struct solver_state *s, int w, int h) {
+static bool learn_critical_square(struct solver_state *s, int w, int h) {
     const int sz = w * h;
     int i;
-    int learn = false;
+    bool learn = false;
     assert(s);
 
     /* for each connected component */
@@ -824,7 +829,7 @@
 }
 #endif
 
-static int learn_bitmap_deductions(struct solver_state *s, int w, int h)
+static bool learn_bitmap_deductions(struct solver_state *s, int w, int h)
 {
     const int sz = w * h;
     int *bm = s->bm;
@@ -831,7 +836,7 @@
     int *dsf = s->bmdsf;
     int *minsize = s->bmminsize;
     int x, y, i, j, n;
-    int learn = false;
+    bool learn = false;
 
     /*
      * This function does deductions based on building up a bitmap
@@ -1066,7 +1071,7 @@
     return learn;
 }
 
-static int solver(const int *orig, int w, int h, char **solution) {
+static bool solver(const int *orig, int w, int h, char **solution) {
     const int sz = w * h;
 
     struct solver_state ss;
@@ -1312,7 +1317,8 @@
     int sz = params->w * params->h;
     int i;
 
-    state->cheated = state->completed = false;
+    state->cheated = false;
+    state->completed = false;
     state->shared = snew(struct shared_state);
     state->shared->refcnt = 1;
     state->shared->params = *params; /* struct copy */
@@ -1374,8 +1380,9 @@
  *****************************************************************************/
 
 struct game_ui {
-    int *sel; /* w*h highlighted squares, or NULL */
-    int cur_x, cur_y, cur_visible, keydragging;
+    bool *sel; /* w*h highlighted squares, or NULL */
+    int cur_x, cur_y;
+    bool cur_visible, keydragging;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1383,7 +1390,9 @@
     game_ui *ui = snew(game_ui);
 
     ui->sel = NULL;
-    ui->cur_x = ui->cur_y = ui->cur_visible = ui->keydragging = 0;
+    ui->cur_x = ui->cur_y = 0;
+    ui->cur_visible = false;
+    ui->keydragging = false;
 
     return ui;
 }
@@ -1423,7 +1432,7 @@
 struct game_drawstate {
     struct game_params params;
     int tilesize;
-    int started;
+    bool started;
     int *v, *flags;
     int *dsf_scratch, *border_scratch;
 };
@@ -1456,25 +1465,25 @@
         }
         if (tx >= 0 && tx < w && ty >= 0 && ty < h) {
             if (!ui->sel) {
-                ui->sel = snewn(w*h, int);
-                memset(ui->sel, 0, w*h*sizeof(int));
+                ui->sel = snewn(w*h, bool);
+                memset(ui->sel, 0, w*h*sizeof(bool));
             }
             if (!state->shared->clues[w*ty+tx])
-                ui->sel[w*ty+tx] = 1;
+                ui->sel[w*ty+tx] = true;
         }
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
         return UI_UPDATE;
     }
 
     if (IS_CURSOR_MOVE(button)) {
-        ui->cur_visible = 1;
-        move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, 0);
+        ui->cur_visible = true;
+        move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, false);
 	if (ui->keydragging) goto select_square;
         return UI_UPDATE;
     }
     if (button == CURSOR_SELECT) {
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
 	ui->keydragging = !ui->keydragging;
@@ -1482,21 +1491,21 @@
 
       select_square:
         if (!ui->sel) {
-            ui->sel = snewn(w*h, int);
-            memset(ui->sel, 0, w*h*sizeof(int));
+            ui->sel = snewn(w*h, bool);
+            memset(ui->sel, 0, w*h*sizeof(bool));
         }
 	if (!state->shared->clues[w*ui->cur_y + ui->cur_x])
-	    ui->sel[w*ui->cur_y + ui->cur_x] = 1;
+	    ui->sel[w*ui->cur_y + ui->cur_x] = true;
 	return UI_UPDATE;
     }
     if (button == CURSOR_SELECT2) {
 	if (!ui->cur_visible) {
-	    ui->cur_visible = 1;
+	    ui->cur_visible = true;
 	    return UI_UPDATE;
 	}
         if (!ui->sel) {
-            ui->sel = snewn(w*h, int);
-            memset(ui->sel, 0, w*h*sizeof(int));
+            ui->sel = snewn(w*h, bool);
+            memset(ui->sel, 0, w*h*sizeof(bool));
         }
 	ui->keydragging = false;
 	if (!state->shared->clues[w*ui->cur_y + ui->cur_x])
@@ -1673,7 +1682,7 @@
     int i;
 
     ds->tilesize = PREFERRED_TILE_SIZE;
-    ds->started = 0;
+    ds->started = false;
     ds->params = state->shared->params;
     ds->v = snewn(ds->params.w * ds->params.h, int);
     ds->flags = snewn(ds->params.w * ds->params.h, int);
@@ -1836,8 +1845,9 @@
 		TILE_SIZE);
 }
 
-static void draw_grid(drawing *dr, game_drawstate *ds, const game_state *state,
-                      const game_ui *ui, int flashy, int borders, int shading)
+static void draw_grid(
+    drawing *dr, game_drawstate *ds, const game_state *state,
+    const game_ui *ui, bool flashy, bool borders, bool shading)
 {
     const int w = state->shared->params.w;
     const int h = state->shared->params.h;
@@ -1862,7 +1872,7 @@
             int v1, s1, v2, s2;
 
             for (dx = 0; dx <= 1; dx++) {
-                int border = false;
+                bool border = false;
 
                 dy = 1 - dx;
 
@@ -2001,7 +2011,7 @@
     const int w = state->shared->params.w;
     const int h = state->shared->params.h;
 
-    const int flashy =
+    const bool flashy =
         flashtime > 0 &&
         (flashtime <= FLASH_TIME/3 || flashtime >= FLASH_TIME*2/3);
 
@@ -2076,7 +2086,8 @@
 {
     const int w = state->shared->params.w;
     const int h = state->shared->params.h;
-    int c, i, borders;
+    int c, i;
+    bool borders;
 
     /* Ick: fake up `ds->tilesize' for macro expansion purposes */
     game_drawstate *ds = game_new_drawstate(dr, state);
--- a/findloop.c
+++ b/findloop.c
@@ -14,7 +14,8 @@
 #include "puzzles.h"
 
 struct findloopstate {
-    int parent, child, sibling, visited;
+    int parent, child, sibling;
+    bool visited;
     int index, minindex, maxindex;
     int minreachable, maxreachable;
     int bridge;
--- a/flip.c
+++ b/flip.c
@@ -58,7 +58,8 @@
 
 struct game_state {
     int w, h;
-    int moves, completed, cheated, hints_active;
+    int moves;
+    bool completed, cheated, hints_active;
     unsigned char *grid;               /* array of w*h */
     struct matrix *matrix;
 };
@@ -896,13 +897,15 @@
 #undef DOWN
 
 struct game_ui {
-    int cx, cy, cdraw;
+    int cx, cy;
+    bool cdraw;
 };
 
 static game_ui *new_ui(const game_state *state)
 {
     game_ui *ui = snew(game_ui);
-    ui->cx = ui->cy = ui->cdraw = 0;
+    ui->cx = ui->cy = 0;
+    ui->cdraw = false;
     return ui;
 }
 
@@ -926,7 +929,8 @@
 }
 
 struct game_drawstate {
-    int w, h, started;
+    int w, h;
+    bool started;
     unsigned char *tiles;
     int tilesize;
 };
@@ -942,10 +946,10 @@
         int tx, ty;
         if (button == LEFT_BUTTON) {
             tx = FROMCOORD(x), ty = FROMCOORD(y);
-            ui->cdraw = 0;
+            ui->cdraw = false;
         } else {
             tx = ui->cx; ty = ui->cy;
-            ui->cdraw = 1;
+            ui->cdraw = true;
         }
         nullret = UI_UPDATE;
 
@@ -955,7 +959,8 @@
              * will have at least one square do nothing whatsoever.
              * If so, we avoid encoding a move at all.
              */
-            int i = ty*w+tx, j, makemove = false;
+            int i = ty*w+tx, j;
+            bool makemove = false;
             for (j = 0; j < wh; j++) {
                 if (state->matrix->matrix[i*wh+j])
                     makemove = true;
@@ -980,7 +985,7 @@
         ui->cx += dx; ui->cy += dy;
         ui->cx = min(max(ui->cx, 0), state->w - 1);
         ui->cy = min(max(ui->cy, 0), state->h - 1);
-        ui->cdraw = 1;
+        ui->cdraw = true;
         nullret = UI_UPDATE;
     }
 
@@ -1008,7 +1013,8 @@
     } else if (move[0] == 'M' &&
 	       sscanf(move+1, "%d,%d", &x, &y) == 2 &&
 	x >= 0 && x < w && y >= 0 && y < h) {
-	int i, j, done;
+	int i, j;
+        bool done;
 
 	ret = dup_game(from);
 
@@ -1112,7 +1118,7 @@
 }
 
 static void draw_tile(drawing *dr, game_drawstate *ds, const game_state *state,
-                      int x, int y, int tile, int anim, float animtime)
+                      int x, int y, int tile, bool anim, float animtime)
 {
     int w = ds->w, h = ds->h, wh = w * h;
     int bx = x * TILE_SIZE + BORDER, by = y * TILE_SIZE + BORDER;
--- a/flood.c
+++ b/flood.c
@@ -63,9 +63,9 @@
 struct game_state {
     int w, h, colours;
     int moves, movelimit;
-    int complete;
+    bool complete;
     char *grid;
-    int cheated;
+    bool cheated;
     int solnpos;
     soln *soln;
 };
@@ -441,7 +441,7 @@
 /*
  * Detect a completed grid.
  */
-static int completed(int w, int h, char *grid)
+static bool completed(int w, int h, char *grid)
 {
     int wh = w*h;
     int i;
@@ -760,7 +760,7 @@
 }
 
 struct game_ui {
-    int cursor_visible;
+    bool cursor_visible;
     int cx, cy;
     enum { VICTORY, DEFEAT } flash_type;
 };
@@ -794,7 +794,7 @@
 }
 
 struct game_drawstate {
-    int started;
+    bool started;
     int tilesize;
     int *grid;
 };
@@ -1158,7 +1158,7 @@
                   TILESIZE * w + 2 * SEP_WIDTH, TILESIZE * h + 2 * SEP_WIDTH,
                   COL_SEPARATOR);
 
-	ds->started = 1;
+	ds->started = true;
     }
 
     if (flashtime > 0) {
--- 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 @@
     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 @@
                            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 @@
 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 @@
             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 @@
     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,10 +615,11 @@
     }
 }
 
-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);
@@ -624,23 +626,23 @@
     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 @@
 /* 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 @@
     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,18 +768,18 @@
 		    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
@@ -784,10 +786,10 @@
              * (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 @@
     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 clear_game(game_state *state, int cleardots)
+static void clear_game(game_state *state, bool cleardots)
 {
     int x, y;
 
@@ -1004,8 +1007,8 @@
  * 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 @@
 	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 @@
                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 @@
     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 @@
     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 @@
         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 @@
     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 @@
 
 #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 @@
             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 @@
                    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 @@
 
         /* 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,7 +1285,8 @@
     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);
@@ -1289,7 +1293,7 @@
     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 @@
     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 @@
 	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 @@
 	    }
 
 	    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 @@
     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 @@
     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 @@
  *
  */
 
-/* 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 @@
      */
     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 @@
  */
 
 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 @@
     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 @@
 #define CURSOR_SIZE DOT_SIZE
 
 struct game_drawstate {
-    int started;
+    bool started;
     int w, h;
     int tilesize;
     unsigned long *grid;
@@ -2359,11 +2364,13 @@
     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 @@
         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 @@
     } 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 @@
 	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 @@
         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 @@
 }
 #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 @@
     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 @@
     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 @@
 #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 @@
             goto badmove;
     }
     if (check_complete(ret, NULL, NULL))
-        ret->completed = 1;
+        ret->completed = true;
     return ret;
 
 badmove:
@@ -3051,7 +3060,7 @@
     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 @@
 
     ds->cur_bl = NULL;
     ds->cx = ds->cy = 0;
-    ds->cur_visible = 0;
+    ds->cur_visible = false;
 
     return ds;
 }
@@ -3221,7 +3230,8 @@
                         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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
             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 @@
         gen(p, rs, verbose);
     } else {
 #ifndef DEBUGGING
-        solver_show_working = 1;
+        solver_show_working = true;
 #endif
         *desc++ = '\0';
         decode_params(p, id);
--- a/grid.c
+++ b/grid.c
@@ -386,11 +386,11 @@
      */
     dots = snewn(g->num_dots, int);
     for (i = 0; i < g->num_dots; i++) {
-        dots[i] = true;
+        dots[i] = 1;
         for (j = 0; j < g->num_dots; j++) {
             if ((dotpairs[i*g->num_dots+j] >= 0) ^
                 (dotpairs[j*g->num_dots+i] >= 0))
-                dots[i] = false;    /* non-duplicated edge: coastal dot */
+                dots[i] = 0;    /* non-duplicated edge: coastal dot */
         }
     }
 
@@ -435,14 +435,14 @@
         dots[i] = 0;
     for (i = 0; i < g->num_faces; i++) {
         grid_face *f = g->faces + i;
-        int keep = false;
+        bool keep = false;
         for (k = 0; k < f->order; k++)
             if (dsf_canonify(dsf, f->dots[k] - g->dots) == j)
                 keep = true;
         if (keep) {
-            faces[i] = true;
+            faces[i] = 1;
             for (k = 0; k < f->order; k++)
-                dots[f->dots[k]-g->dots] = true;
+                dots[f->dots[k]-g->dots] = 1;
         }
     }
 
@@ -862,7 +862,7 @@
 /*
  * Helper routines for grid_find_incentre.
  */
-static int solve_2x2_matrix(double mx[4], double vin[2], double vout[2])
+static bool solve_2x2_matrix(double mx[4], double vin[2], double vout[2])
 {
     double inv[4];
     double det;
@@ -880,7 +880,7 @@
 
     return true;
 }
-static int solve_3x3_matrix(double mx[9], double vin[3], double vout[3])
+static bool solve_3x3_matrix(double mx[9], double vin[3], double vout[3])
 {
     double inv[9];
     double det;
@@ -1239,7 +1239,8 @@
                      * _positive_ epsilon in both the x- and
                      * y-direction.)
                      */
-                    int e, in = 0;
+                    int e;
+                    bool in = false;
                     for (e = 0; e < f->order; e++) {
                         int xs = f->edges[e]->dot1->x;
                         int xe = f->edges[e]->dot2->x;
@@ -1265,7 +1266,7 @@
                                 denom = -denom;
                             }
                             if ((x - xs) * denom >= (y - ys) * num)
-                                in ^= 1;
+                                in = !in;
                         }
                     }
 
--- a/gtk.c
+++ b/gtk.c
@@ -167,12 +167,14 @@
 #endif
     int ncolours;
     int bbox_l, bbox_r, bbox_u, bbox_d;
-    int timer_active, timer_id;
+    bool timer_active;
+    int timer_id;
     struct timeval last_time;
     struct font *fonts;
     int nfonts, fontsize;
     config_item *cfg;
-    int cfg_which, cfgret;
+    int cfg_which;
+    bool cfgret;
     GtkWidget *cfgbox;
     void *paste_data;
     int paste_data_len;
@@ -182,12 +184,12 @@
     char *filesel_name;
 #endif
     GSList *preset_radio;
-    int preset_threaded;
+    bool preset_threaded;
     GtkWidget *preset_custom;
     GtkWidget *copy_menu_item;
 #if !GTK_CHECK_VERSION(3,0,0)
-    int drawing_area_shrink_pending;
-    int menubar_is_local;
+    bool drawing_area_shrink_pending;
+    bool menubar_is_local;
 #endif
 #if GTK_CHECK_VERSION(3,0,0)
     /*
@@ -219,7 +221,7 @@
      * happen, the window's size_allocate handler does a fallback
      * puzzle resize when it sees this flag still set to true.
      */
-    int awaiting_resize_ack;
+    bool awaiting_resize_ack;
 #endif
 };
 
@@ -494,8 +496,8 @@
 }
 
 static void wipe_and_maybe_destroy_cairo(frontend *fe, cairo_t *cr,
-                                         int destroy)
-{
+                                         bool destroy)
+{
     cairo_set_source_rgb(cr, fe->colours[0], fe->colours[1], fe->colours[2]);
     cairo_paint(cr);
     if (destroy)
@@ -536,9 +538,9 @@
 #endif
 }
 
-static int backing_store_ok(frontend *fe)
+static bool backing_store_ok(frontend *fe)
 {
-    return (!!fe->image);
+    return fe->image != NULL;
 }
 
 static void teardown_backing_store(frontend *fe)
@@ -1459,7 +1461,7 @@
     gtk_main_quit();
 }
 
-static int win_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
+static gint win_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
     GObject *cancelbutton = G_OBJECT(data);
 
@@ -1494,8 +1496,8 @@
 }
 
 #if GTK_CHECK_VERSION(3,0,0)
-int message_box(GtkWidget *parent, const char *title, const char *msg,
-                int centre, int type)
+bool message_box(GtkWidget *parent, const char *title, const char *msg,
+                 bool centre, int type)
 {
     GtkWidget *window;
     gint ret;
@@ -1524,8 +1526,8 @@
     gtk_widget_destroy(GTK_WIDGET(data));
 }
 
-int message_box(GtkWidget *parent, const char *title, const char *msg,
-                int centre, int type)
+bool message_box(GtkWidget *parent, const char *title, const char *msg,
+                 bool centre, int type)
 {
     GtkWidget *window, *hbox, *text, *button;
     char *titles;
@@ -1617,7 +1619,7 @@
     gtk_widget_destroy(fe->cfgbox);
 }
 
-static int editbox_key(GtkWidget *widget, GdkEventKey *event, gpointer data)
+static gint editbox_key(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
     /*
      * GtkEntry has a nasty habit of eating the Return key, which
@@ -1664,7 +1666,7 @@
     i->u.choices.selected = gtk_combo_box_get_active(combo);
 }
 
-static int get_config(frontend *fe, int which)
+static bool get_config(frontend *fe, int which)
 {
     GtkWidget *w, *table, *cancel;
     GtkBox *content_box, *button_box;
@@ -1953,13 +1955,13 @@
      * Update the greying on the Copy menu option.
      */
     if (fe->copy_menu_item) {
-	int enabled = midend_can_format_as_text_now(fe->me);
+        bool enabled = midend_can_format_as_text_now(fe->me);
 	gtk_widget_set_sensitive(fe->copy_menu_item, enabled);
     }
 }
 
 #if !GTK_CHECK_VERSION(3,0,0)
-static gboolean not_size_allocated_yet(GtkWidget *w)
+static bool not_size_allocated_yet(GtkWidget *w)
 {
     /*
      * This function tests whether a widget has not yet taken up space
@@ -2084,7 +2086,7 @@
 }
 
 GdkAtom compound_text_atom, utf8_string_atom;
-int paste_initialised = false;
+bool paste_initialised = false;
 
 static void set_selection(frontend *fe, GdkAtom selection)
 {
@@ -2201,7 +2203,7 @@
 
 #else
 
-static char *file_selector(frontend *fe, const char *title, int save)
+static char *file_selector(frontend *fe, const char *title, bool save)
 {
     char *filesel_name = NULL;
 
@@ -2906,9 +2908,10 @@
 {
     char *pname = argv[0];
     char *error;
-    int ngenerate = 0, print = false, px = 1, py = 1;
-    int time_generation = false, test_solve = false, list_presets = false;
-    int soln = false, colour = false;
+    int ngenerate = 0, px = 1, py = 1;
+    bool print = false;
+    bool time_generation = false, test_solve = false, list_presets = false;
+    bool soln = false, colour = false;
     float scale = 1.0F;
     float redo_proportion = 0.0F;
     const char *savefile = NULL, *savesuffix = NULL;
@@ -2915,7 +2918,7 @@
     char *arg = NULL;
     int argtype = ARG_EITHER;
     char *screenshot_file = NULL;
-    int doing_opts = true;
+    bool doing_opts = true;
     int ac = argc;
     char **av = argv;
     char errbuf[500];
--- a/guess.c
+++ b/guess.c
@@ -24,7 +24,7 @@
 
 struct game_params {
     int ncolours, npegs, nguesses;
-    int allow_blank, allow_multiple;
+    bool allow_blank, allow_multiple;
 };
 
 #define FEEDBACK_CORRECTPLACE  1
@@ -39,7 +39,7 @@
 struct game_state {
     game_params params;
     pegrow *guesses;  /* length params->nguesses */
-    int *holds;
+    bool *holds;
     pegrow solution;
     int next_go; /* from 0 to nguesses-1;
                     if next_go == nguesses then they've lost. */
@@ -55,8 +55,8 @@
     ret->npegs = 4;
     ret->nguesses = 10;
 
-    ret->allow_blank = 0;
-    ret->allow_multiple = 1;
+    ret->allow_blank = false;
+    ret->allow_multiple = true;
 
     return ret;
 }
@@ -124,19 +124,19 @@
 	    break;
 
         case 'b':
-            params->allow_blank = 1;
+            params->allow_blank = true;
             break;
 
         case 'B':
-            params->allow_blank = 0;
+            params->allow_blank = false;
             break;
 
         case 'm':
-            params->allow_multiple = 1;
+            params->allow_multiple = true;
             break;
 
         case 'M':
-            params->allow_multiple = 0;
+            params->allow_multiple = false;
             break;
 
 	default:
@@ -314,7 +314,7 @@
     state->guesses = snewn(params->nguesses, pegrow);
     for (i = 0; i < params->nguesses; i++)
 	state->guesses[i] = new_pegrow(params->npegs);
-    state->holds = snewn(params->npegs, int);
+    state->holds = snewn(params->npegs, bool);
     state->solution = new_pegrow(params->npegs);
 
     bmp = hex2bin(desc, params->npegs);
@@ -323,7 +323,7 @@
 	state->solution->pegs[i] = (int)bmp[i];
     sfree(bmp);
 
-    memset(state->holds, 0, sizeof(int) * params->npegs);
+    memset(state->holds, 0, sizeof(bool) * params->npegs);
     state->next_go = state->solved = 0;
 
     return state;
@@ -339,8 +339,8 @@
     ret->guesses = snewn(state->params.nguesses, pegrow);
     for (i = 0; i < state->params.nguesses; i++)
 	ret->guesses[i] = dup_pegrow(state->guesses[i]);
-    ret->holds = snewn(state->params.npegs, int);
-    memcpy(ret->holds, state->holds, sizeof(int) * state->params.npegs);
+    ret->holds = snewn(state->params.npegs, bool);
+    memcpy(ret->holds, state->holds, sizeof(bool) * state->params.npegs);
     ret->solution = dup_pegrow(state->solution);
 
     return ret;
@@ -375,9 +375,10 @@
     return NULL;
 }
 
-static int is_markable(const game_params *params, pegrow pegs)
+static bool is_markable(const game_params *params, pegrow pegs)
 {
-    int i, nset = 0, nrequired, ret = 0;
+    int i, nset = 0, nrequired;
+    bool ret = false;
     pegrow colcount = new_pegrow(params->ncolours);
 
     nrequired = params->allow_blank ? 1 : params->npegs;
@@ -396,7 +397,7 @@
             if (colcount->pegs[i] > 1) goto done;
         }
     }
-    ret = 1;
+    ret = true;
 done:
     free_pegrow(colcount);
     return ret;
@@ -405,15 +406,15 @@
 struct game_ui {
     game_params params;
     pegrow curr_pegs; /* half-finished current move */
-    int *holds;
+    bool *holds;
     int colour_cur;   /* position of up-down colour picker cursor */
     int peg_cur;      /* position of left-right peg picker cursor */
-    int display_cur, markable;
+    bool display_cur, markable;
 
     int drag_col, drag_x, drag_y; /* x and y are *center* of peg! */
     int drag_opeg; /* peg index, if dragged from a peg (from current guess), otherwise -1 */
 
-    int show_labels;                   /* label the colours with letters */
+    bool show_labels;                   /* label the colours with letters */
     pegrow hint;
 };
 
@@ -423,8 +424,8 @@
     memset(ui, 0, sizeof(game_ui));
     ui->params = state->params;        /* structure copy */
     ui->curr_pegs = new_pegrow(state->params.npegs);
-    ui->holds = snewn(state->params.npegs, int);
-    memset(ui->holds, 0, sizeof(int)*state->params.npegs);
+    ui->holds = snewn(state->params.npegs, bool);
+    memset(ui->holds, 0, sizeof(bool)*state->params.npegs);
     ui->drag_opeg = -1;
     return ui;
 }
@@ -470,10 +471,10 @@
         while (*p && isdigit((unsigned char)*p)) p++;
         if (*p == '_') {
             /* NB: old versions didn't store holds */
-            ui->holds[i] = 1;
+            ui->holds[i] = true;
             p++;
         } else
-            ui->holds[i] = 0;
+            ui->holds[i] = false;
         if (*p == ',') p++;
     }
     ui->markable = is_markable(&ui->params, ui->curr_pegs);
@@ -494,7 +495,7 @@
      * for undo. */
     for (i = 0; i < newstate->solution->npegs; i++) {
         if (newstate->solved)
-            ui->holds[i] = 0;
+            ui->holds[i] = false;
         else
             ui->holds[i] = newstate->holds[i];
 	if (newstate->solved || (newstate->next_go == 0) || !ui->holds[i]) {
@@ -559,7 +560,9 @@
     int guessx, guessy; /* origin of guesses */
     int solnx, solny;   /* origin of solution */
     int hintw;          /* no. of hint tiles we're wide per row */
-    int w, h, started, solved;
+    int w, h;
+    bool started;
+    int solved;
 
     int next_go;
 
@@ -731,7 +734,7 @@
 
         ui->markable = true;
         ui->peg_cur = state->params.npegs;
-        ui->display_cur = 1;
+        ui->display_cur = true;
         return;
 
     increment_pegrow:
@@ -747,9 +750,9 @@
      * should it ever happen, update the ui in some trivial way.  This gives
      * the user a sense of broken(ish)ness and futility. */
     if (!ui->display_cur) {
-        ui->display_cur = 1;
+        ui->display_cur = true;
     } else if (state->params.npegs == 1) {
-        ui->display_cur = 0;
+        ui->display_cur = false;
     } else {
         ui->peg_cur = (ui->peg_cur + 1) % state->params.npegs;
     }
@@ -763,7 +766,7 @@
     int over_guess = -1;        /* zero-indexed */
     int over_past_guess_y = -1; /* zero-indexed */
     int over_past_guess_x = -1; /* zero-indexed */
-    int over_hint = 0;          /* zero or one */
+    bool over_hint = false;
     char *ret = NULL;
 
     int guess_ox = GUESS_X(from->next_go, 0);
@@ -789,7 +792,7 @@
             over_guess = (x - guess_ox) / PEGOFF;
             assert(over_guess >= 0 && over_guess < ds->solution->npegs);
         } else {
-            over_hint = 1;
+            over_hint = true;
         }
     } else if (x >= guess_ox && x < (guess_ox + GUESS_W) &&
                y >= GUESS_OY && y < guess_oy) {
@@ -852,7 +855,7 @@
         }
         ui->drag_col = 0;
         ui->drag_opeg = -1;
-        ui->display_cur = 0;
+        ui->display_cur = false;
         debug(("Stop dragging."));
         ret = UI_UPDATE;
     } else if (button == RIGHT_BUTTON) {
@@ -859,7 +862,7 @@
         if (over_guess > -1) {
             /* we use ths feedback in the game_ui to signify
              * 'carry this peg to the next guess as well'. */
-            ui->holds[over_guess] = 1 - ui->holds[over_guess];
+            ui->holds[over_guess] ^= 1;
             ret = UI_UPDATE;
         }
     } else if (button == LEFT_RELEASE && over_hint && ui->markable) {
@@ -870,7 +873,7 @@
 
     /* keyboard input */
     if (button == CURSOR_UP || button == CURSOR_DOWN) {
-        ui->display_cur = 1;
+        ui->display_cur = true;
         if (button == CURSOR_DOWN && (ui->colour_cur+1) < from->params.ncolours)
             ui->colour_cur++;
         if (button == CURSOR_UP && ui->colour_cur > 0)
@@ -883,7 +886,7 @@
         int maxcur = from->params.npegs;
         if (ui->markable) maxcur++;
 
-        ui->display_cur = 1;
+        ui->display_cur = true;
         if (button == CURSOR_RIGHT && (ui->peg_cur+1) < maxcur)
             ui->peg_cur++;
         if (button == CURSOR_LEFT && ui->peg_cur > 0)
@@ -890,7 +893,7 @@
             ui->peg_cur--;
         ret = UI_UPDATE;
     } else if (IS_CURSOR_SELECT(button)) {
-        ui->display_cur = 1;
+        ui->display_cur = true;
         if (ui->peg_cur == from->params.npegs) {
             ret = encode_move(from, ui);
         } else {
@@ -898,14 +901,14 @@
             ret = UI_UPDATE;
         }
     } else if (button == 'D' || button == 'd' || button == '\b') {
-        ui->display_cur = 1;
+        ui->display_cur = true;
         set_peg(&from->params, ui, ui->peg_cur, 0);
         ret = UI_UPDATE;
     } else if (button == CURSOR_SELECT2) {
         if (ui->peg_cur == from->params.npegs)
             return NULL;
-        ui->display_cur = 1;
-        ui->holds[ui->peg_cur] = 1 - ui->holds[ui->peg_cur];
+        ui->display_cur = true;
+        ui->holds[ui->peg_cur] ^= 1;
         ret = UI_UPDATE;
     }
     return ret;
@@ -936,10 +939,10 @@
 	    ret->guesses[from->next_go]->pegs[i] = atoi(p);
 	    while (*p && isdigit((unsigned char)*p)) p++;
             if (*p == '_') {
-                ret->holds[i] = 1;
+                ret->holds[i] = true;
                 p++;
             } else
-                ret->holds[i] = 0;
+                ret->holds[i] = false;
 	    if (*p == ',') p++;
 	}
 
@@ -1172,7 +1175,7 @@
 }
 
 static void draw_peg(drawing *dr, game_drawstate *ds, int cx, int cy,
-		     int moving, int labelled, int col)
+		     bool moving, bool labelled, int col)
 {
     /*
      * Some platforms antialias circles, which means we shouldn't
@@ -1210,8 +1213,8 @@
 }
 
 static void guess_redraw(drawing *dr, game_drawstate *ds, int guess,
-                         pegrow src, int *holds, int cur_col, int force,
-                         int labelled)
+                         pegrow src, bool *holds, int cur_col, bool force,
+                         bool labelled)
 {
     pegrow dest;
     int rowx, rowy, i, scol;
@@ -1253,11 +1256,11 @@
 }
 
 static void hint_redraw(drawing *dr, game_drawstate *ds, int guess,
-                        pegrow src, int force, int cursor, int markable)
+                        pegrow src, bool force, bool cursor, bool markable)
 {
     pegrow dest = ds->guesses[guess];
     int rowx, rowy, i, scol, col, hintlen;
-    int need_redraw;
+    bool need_redraw;
     int emptycol = (markable ? COL_FLASH : COL_EMPTY);
 
     if (src) assert(src->npegs == dest->npegs);
@@ -1340,7 +1343,8 @@
                         int dir, const game_ui *ui,
                         float animtime, float flashtime)
 {
-    int i, new_move;
+    int i;
+    bool new_move;
 
     new_move = (state->next_go != ds->next_go) || !ds->started;
 
@@ -1377,14 +1381,14 @@
     for (i = state->params.nguesses - 1; i >= 0; i--) {
         if (i < state->next_go || state->solved) {
             /* this info is stored in the game_state already */
-            guess_redraw(dr, ds, i, state->guesses[i], NULL, -1, 0,
+            guess_redraw(dr, ds, i, state->guesses[i], NULL, -1, false,
                          ui->show_labels);
             hint_redraw(dr, ds, i, state->guesses[i],
-                        i == (state->next_go-1) ? 1 : 0, false, false);
+                        i == (state->next_go-1), false, false);
         } else if (i > state->next_go) {
             /* we've not got here yet; it's blank. */
-            guess_redraw(dr, ds, i, NULL, NULL, -1, 0, ui->show_labels);
-            hint_redraw(dr, ds, i, NULL, 0, false, false);
+            guess_redraw(dr, ds, i, NULL, NULL, -1, false, ui->show_labels);
+            hint_redraw(dr, ds, i, NULL, false, false, false);
         }
     }
     if (!state->solved) {
@@ -1391,9 +1395,9 @@
 	/* this is the one we're on; the (incomplete) guess is stored in
 	 * the game_ui. */
 	guess_redraw(dr, ds, state->next_go, ui->curr_pegs,
-		     ui->holds, ui->display_cur ? ui->peg_cur : -1, 0,
+		     ui->holds, ui->display_cur ? ui->peg_cur : -1, false,
 		     ui->show_labels);
-	hint_redraw(dr, ds, state->next_go, NULL, 1,
+	hint_redraw(dr, ds, state->next_go, NULL, true,
 		    ui->display_cur && ui->peg_cur == state->params.npegs,
 		    ui->markable);
     }
@@ -1429,7 +1433,7 @@
     }
     ds->drag_col = ui->drag_col;
 
-    ds->started = 1;
+    ds->started = true;
 }
 
 static float game_anim_length(const game_state *oldstate,
--- a/inertia.c
+++ b/inertia.c
@@ -77,8 +77,8 @@
     int gems;
     char *grid;
     int distance_moved;
-    int dead;
-    int cheated;
+    bool dead;
+    bool cheated;
     int solnpos;
     soln *soln;
 };
@@ -220,7 +220,7 @@
  */
 
 struct solver_scratch {
-    unsigned char *reachable_from, *reachable_to;
+    bool *reachable_from, *reachable_to;
     int *positions;
 };
 
@@ -228,8 +228,8 @@
 {
     struct solver_scratch *sc = snew(struct solver_scratch);
 
-    sc->reachable_from = snewn(w * h * DIRECTIONS, unsigned char);
-    sc->reachable_to = snewn(w * h * DIRECTIONS, unsigned char);
+    sc->reachable_from = snewn(w * h * DIRECTIONS, bool);
+    sc->reachable_to = snewn(w * h * DIRECTIONS, bool);
     sc->positions = snewn(w * h * DIRECTIONS, int);
 
     return sc;
@@ -243,8 +243,8 @@
     sfree(sc);
 }
 
-static int can_go(int w, int h, char *grid,
-		  int x1, int y1, int dir1, int x2, int y2, int dir2)
+static bool can_go(int w, int h, char *grid,
+                   int x1, int y1, int dir1, int x2, int y2, int dir2)
 {
     /*
      * Returns true if we can transition directly from (x1,y1)
@@ -317,8 +317,8 @@
      * flags set.
      */
 
-    memset(sc->reachable_from, 0, wh * DIRECTIONS);
-    memset(sc->reachable_to, 0, wh * DIRECTIONS);
+    memset(sc->reachable_from, 0, wh * DIRECTIONS * sizeof(bool));
+    memset(sc->reachable_to, 0, wh * DIRECTIONS * sizeof(bool));
 
     /*
      * Find the starting square.
@@ -334,8 +334,7 @@
     assert(sy < h);
 
     for (pass = 0; pass < 2; pass++) {
-	unsigned char *reachable = (pass == 0 ? sc->reachable_from :
-				    sc->reachable_to);
+	bool *reachable = (pass == 0 ? sc->reachable_from : sc->reachable_to);
 	int sign = (pass == 0 ? +1 : -1);
 	int dir;
 
@@ -392,7 +391,7 @@
 		if (x2 >= 0 && x2 < w &&
 		    y2 >= 0 && y2 < h &&
 		    !reachable[i2]) {
-		    int ok;
+		    bool ok;
 #ifdef SOLVER_DIAGNOSTICS
 		    printf("  trying point %d,%d,%d", x2, y2, d2);
 #endif
@@ -1491,8 +1490,8 @@
     float anim_length;
     int flashtype;
     int deaths;
-    int just_made_move;
-    int just_died;
+    bool just_made_move;
+    bool just_died;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1549,10 +1548,11 @@
 struct game_drawstate {
     game_params p;
     int tilesize;
-    int started;
+    bool started;
     unsigned short *grid;
     blitter *player_background;
-    int player_bg_saved, pbgx, pbgy;
+    bool player_bg_saved;
+    int pbgx, pbgy;
 };
 
 #define PREFERRED_TILESIZE 32
@@ -1844,7 +1844,7 @@
 }
 
 static void draw_player(drawing *dr, game_drawstate *ds, int x, int y,
-			int dead, int hintdir)
+			bool dead, int hintdir)
 {
     if (dead) {
 	int coords[DIRECTIONS*4];
--- a/keen.c
+++ b/keen.c
@@ -62,7 +62,8 @@
 };
 
 struct game_params {
-    int w, diff, multiplication_only;
+    int w, diff;
+    bool multiplication_only;
 };
 
 struct clues {
@@ -77,7 +78,7 @@
     struct clues *clues;
     digit *grid;
     int *pencil;		       /* bitmaps using bits 1<<1..1<<n */
-    int completed, cheated;
+    bool completed, cheated;
 };
 
 static game_params *default_params(void)
@@ -673,7 +674,8 @@
      * means 26, zb 27 etc).
      */
     for (i = 0; i <= 2*w*(w-1); i++) {
-	int x, y, p0, p1, edge;
+	int x, y, p0, p1;
+        bool edge;
 
 	if (i == 2*w*(w-1)) {
 	    edge = true;       /* terminating virtual edge */
@@ -736,7 +738,8 @@
     dsf_init(dsf, a);
 
     while (**p && (repn > 0 || **p != ',')) {
-	int c, adv;
+	int c;
+        bool adv;
 
 	if (repn > 0) {
 	    repn--;
@@ -1040,7 +1043,7 @@
 	for (i = 0; i < a; i++)
 	    clues[i] = 0;
 	while (1) {
-	    int done_something = false;
+	    bool done_something = false;
 
 	    for (k = 0; k < 4; k++) {
 		long clue;
@@ -1327,7 +1330,8 @@
 	state->pencil[i] = 0;
     }
 
-    state->completed = state->cheated = false;
+    state->completed = false;
+    state->cheated = false;
 
     return state;
 }
@@ -1413,7 +1417,7 @@
 struct game_ui {
     /*
      * These are the coordinates of the currently highlighted
-     * square on the grid, if hshow = 1.
+     * square on the grid, if hshow is true.
      */
     int hx, hy;
     /*
@@ -1420,21 +1424,21 @@
      * This indicates whether the current highlight is a
      * pencil-mark one or a real one.
      */
-    int hpencil;
+    bool hpencil;
     /*
      * This indicates whether or not we're showing the highlight
      * (used to be hx = hy = -1); important so that when we're
      * using the cursor keys it doesn't keep coming back at a
-     * fixed position. When hshow = 1, pressing a valid number
-     * or letter key or Space will enter that number or letter in the grid.
+     * fixed position. When true, pressing a valid number or letter
+     * key or Space will enter that number or letter in the grid.
      */
-    int hshow;
+    bool hshow;
     /*
      * This indicates whether we're using the highlight as a cursor;
      * it means that it doesn't vanish on a keypress, and that it is
      * allowed on immutable squares.
      */
-    int hcursor;
+    bool hcursor;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1442,7 +1446,9 @@
     game_ui *ui = snew(game_ui);
 
     ui->hx = ui->hy = 0;
-    ui->hpencil = ui->hshow = ui->hcursor = 0;
+    ui->hpencil = false;
+    ui->hshow = false;
+    ui->hcursor = false;
 
     return ui;
 }
@@ -1473,7 +1479,7 @@
      */
     if (ui->hshow && ui->hpencil && !ui->hcursor &&
         newstate->grid[ui->hy * w + ui->hx] != 0) {
-        ui->hshow = 0;
+        ui->hshow = false;
     }
 }
 
@@ -1495,21 +1501,22 @@
 
 struct game_drawstate {
     int tilesize;
-    int started;
+    bool started;
     long *tiles;
     long *errors;
     char *minus_sign, *times_sign, *divide_sign;
 };
 
-static int check_errors(const game_state *state, long *errors)
+static bool check_errors(const game_state *state, long *errors)
 {
     int w = state->par.w, a = w*w;
-    int i, j, x, y, errs = false;
+    int i, j, x, y;
+    bool errs = false;
     long *cluevals;
-    int *full;
+    bool *full;
 
     cluevals = snewn(a, long);
-    full = snewn(a, int);
+    full = snewn(a, bool);
 
     if (errors)
 	for (i = 0; i < a; i++) {
@@ -1624,15 +1631,15 @@
     if (tx >= 0 && tx < w && ty >= 0 && ty < w) {
         if (button == LEFT_BUTTON) {
 	    if (tx == ui->hx && ty == ui->hy &&
-		ui->hshow && ui->hpencil == 0) {
-                ui->hshow = 0;
+		ui->hshow && !ui->hpencil) {
+                ui->hshow = false;
             } else {
                 ui->hx = tx;
                 ui->hy = ty;
-                ui->hshow = 1;
-                ui->hpencil = 0;
+                ui->hshow = true;
+                ui->hpencil = false;
             }
-            ui->hcursor = 0;
+            ui->hcursor = false;
             return UI_UPDATE;
         }
         if (button == RIGHT_BUTTON) {
@@ -1642,29 +1649,30 @@
             if (state->grid[ty*w+tx] == 0) {
                 if (tx == ui->hx && ty == ui->hy &&
                     ui->hshow && ui->hpencil) {
-                    ui->hshow = 0;
+                    ui->hshow = false;
                 } else {
-                    ui->hpencil = 1;
+                    ui->hpencil = true;
                     ui->hx = tx;
                     ui->hy = ty;
-                    ui->hshow = 1;
+                    ui->hshow = true;
                 }
             } else {
-                ui->hshow = 0;
+                ui->hshow = false;
             }
-            ui->hcursor = 0;
+            ui->hcursor = false;
             return UI_UPDATE;
         }
     }
     if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->hx, &ui->hy, w, w, 0);
-        ui->hshow = ui->hcursor = 1;
+        move_cursor(button, &ui->hx, &ui->hy, w, w, false);
+        ui->hshow = true;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
     if (ui->hshow &&
         (button == CURSOR_SELECT)) {
-        ui->hpencil = 1 - ui->hpencil;
-        ui->hcursor = 1;
+        ui->hpencil ^= 1;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
 
@@ -1685,7 +1693,7 @@
 	sprintf(buf, "%c%d,%d,%d",
 		(char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
 
-        if (!ui->hcursor) ui->hshow = 0;
+        if (!ui->hcursor) ui->hshow = false;
 
 	return dupstr(buf);
     }
@@ -1839,7 +1847,7 @@
 }
 
 static void draw_tile(drawing *dr, game_drawstate *ds, struct clues *clues,
-		      int x, int y, long tile, int only_one_op)
+		      int x, int y, long tile, bool only_one_op)
 {
     int w = clues->w /* , a = w*w */;
     int tx, ty, tw, th;
@@ -2403,8 +2411,9 @@
     game_state *s;
     char *id = NULL, *desc;
     const char *err;
-    int grade = false;
-    int ret, diff, really_show_working = false;
+    bool grade = false;
+    int ret, diff;
+    bool really_show_working = false;
 
     while (--argc > 0) {
         char *p = *++argv;
@@ -2447,7 +2456,7 @@
      * the puzzle internally before doing anything else.
      */
     ret = -1;			       /* placate optimiser */
-    solver_show_working = false;
+    solver_show_working = 0;
     for (diff = 0; diff < DIFFCOUNT; diff++) {
 	memset(s->grid, 0, p->w * p->w);
 	ret = solver(p->w, s->clues->dsf, s->clues->clues,
@@ -2468,7 +2477,7 @@
 	    else
 		printf("Difficulty rating: %s\n", keen_diffnames[ret]);
 	} else {
-	    solver_show_working = really_show_working;
+	    solver_show_working = really_show_working ? 1 : 0;
 	    memset(s->grid, 0, p->w * p->w);
 	    ret = solver(p->w, s->clues->dsf, s->clues->clues,
 			 s->grid, diff);
--- a/latin.c
+++ b/latin.c
@@ -226,7 +226,7 @@
              */
             int rows = 0;
             for (i = 0; i < n; i++) {
-                int ok = true;
+                bool ok = true;
                 for (j = 0; j < n; j++)
                     if (set[j] && grid[i*o+j]) {
                         ok = false;
@@ -261,7 +261,7 @@
 	    }
 
             if (rows >= n - count) {
-                int progress = false;
+                bool progress = false;
 
                 /*
                  * We've got one! Now, for each row which _doesn't_
@@ -275,7 +275,7 @@
                  * positions in the cube to meddle with.
                  */
                 for (i = 0; i < n; i++) {
-                    int ok = true;
+                    bool ok = true;
                     for (j = 0; j < n; j++)
                         if (set[j] && grid[i*o+j]) {
                             ok = false;
@@ -570,12 +570,12 @@
     solver->o = o;
     solver->cube = snewn(o*o*o, unsigned char);
     solver->grid = grid;		/* write straight back to the input */
-    memset(solver->cube, true, o*o*o);
+    memset(solver->cube, 1, o*o*o);
 
     solver->row = snewn(o*o, unsigned char);
     solver->col = snewn(o*o, unsigned char);
-    memset(solver->row, false, o*o);
-    memset(solver->col, false, o*o);
+    memset(solver->row, 0, o*o);
+    memset(solver->col, 0, o*o);
 
     for (x = 0; x < o; x++)
 	for (y = 0; y < o; y++)
@@ -908,9 +908,9 @@
 	    if (ret == 0 && i == diff_simple)
 		ret = latin_solver_diff_simple(solver);
 	    if (ret == 0 && i == diff_set_0)
-		ret = latin_solver_diff_set(solver, scratch, 0);
+		ret = latin_solver_diff_set(solver, scratch, false);
 	    if (ret == 0 && i == diff_set_1)
-		ret = latin_solver_diff_set(solver, scratch, 1);
+		ret = latin_solver_diff_set(solver, scratch, true);
 	    if (ret == 0 && i == diff_forcing)
 		ret = latin_solver_forcing(solver, scratch);
 
--- a/lightup.c
+++ b/lightup.c
@@ -117,7 +117,7 @@
                            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 @@
 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 @@
     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 @@
 /* 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 @@
         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 @@
         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 @@
     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,11 +523,11 @@
         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;
 
@@ -533,23 +534,23 @@
     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,7 +568,8 @@
 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;
@@ -574,11 +576,11 @@
     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 @@
     }
 
     /* 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 @@
 }
 
 /* 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 @@
 
 /* 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 @@
     }
 
     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 @@
 {
     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 @@
         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 @@
         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 @@
         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 @@
     *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 @@
             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 @@
         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 @@
         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_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 @@
     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 @@
     /* 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 @@
 }
 #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 @@
 }
 
 /* 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 @@
 
     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 @@
  *  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 @@
         }
     }
     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 @@
             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 @@
                      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 @@
         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 @@
                 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 @@
 
                     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 @@
                 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 @@
 #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,7 +1462,7 @@
     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;
         }
@@ -1460,7 +1469,7 @@
     }
 }
 
-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 @@
     /* 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 @@
 }
 
 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 @@
                                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 @@
     int tilesize, crad;
     int w, h;
     unsigned int *flags;         /* width * height */
-    int started;
+    bool started;
 };
 
 
@@ -1882,7 +1893,7 @@
     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 @@
             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 @@
             /* 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 @@
             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 @@
     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 @@
 #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 @@
                         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 @@
         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++) {
--- a/loopgen.c
+++ b/loopgen.c
@@ -75,8 +75,8 @@
 /* 'board' is an array of enum face_colour, indicating which faces are
  * currently black/white/grey.  'colour' is FACE_WHITE or FACE_BLACK.
  * Returns whether it's legal to colour the given face with this colour. */
-static int can_colour_face(grid *g, char* board, int face_index,
-                           enum face_colour colour)
+static bool can_colour_face(grid *g, char* board, int face_index,
+                            enum face_colour colour)
 {
     int i, j;
     grid_face *test_face = g->faces + face_index;
@@ -83,8 +83,8 @@
     grid_face *starting_face, *current_face;
     grid_dot *starting_dot;
     int transitions;
-    int current_state, s; /* booleans: equal or not-equal to 'colour' */
-    int found_same_coloured_neighbour = false;
+    bool current_state, s; /* equal or not-equal to 'colour' */
+    bool found_same_coloured_neighbour = false;
     assert(board[face_index] != colour);
 
     /* Can only consider a face for colouring if it's adjacent to a face
@@ -306,7 +306,7 @@
     tree234 *lightable_faces_sorted;
     tree234 *darkable_faces_sorted;
     int *face_list;
-    int do_random_pass;
+    bool do_random_pass;
 
     /* Make a board */
     memset(board, FACE_GREY, num_faces);
@@ -506,7 +506,7 @@
 
     while (true) {
         /* Remember whether a flip occurred during this pass */
-        int flipped = false;
+        bool flipped = false;
 
         for (i = 0; i < num_faces; ++i) {
             int j = face_list[i];
--- a/loopy.c
+++ b/loopy.c
@@ -117,11 +117,11 @@
      * YES, NO or UNKNOWN */
     char *lines;
 
-    unsigned char *line_errors;
-    int exactly_one_loop;
+    bool *line_errors;
+    bool exactly_one_loop;
 
-    int solved;
-    int cheated;
+    bool solved;
+    bool cheated;
 
     /* Used in game_text_format(), so that it knows what type of
      * grid it's trying to render as ASCII text. */
@@ -152,7 +152,7 @@
     char *dot_no_count;
     char *face_yes_count;
     char *face_no_count;
-    char *dot_solved, *face_solved;
+    bool *dot_solved, *face_solved;
     int *dotdsf;
 
     /* Information for Normal level deductions:
@@ -223,13 +223,13 @@
 
 
 struct game_drawstate {
-    int started;
+    bool started;
     int tilesize;
-    int flashing;
+    bool flashing;
     int *textx, *texty;
     char *lines;
-    char *clue_error;
-    char *clue_satisfied;
+    bool *clue_error;
+    bool *clue_satisfied;
 };
 
 static const char *validate_desc(const game_params *params, const char *desc);
@@ -348,8 +348,9 @@
     ret->lines = snewn(state->game_grid->num_edges, char);
     memcpy(ret->lines, state->lines, state->game_grid->num_edges);
 
-    ret->line_errors = snewn(state->game_grid->num_edges, unsigned char);
-    memcpy(ret->line_errors, state->line_errors, state->game_grid->num_edges);
+    ret->line_errors = snewn(state->game_grid->num_edges, bool);
+    memcpy(ret->line_errors, state->line_errors,
+           state->game_grid->num_edges * sizeof(bool));
     ret->exactly_one_loop = state->exactly_one_loop;
 
     ret->grid_type = state->grid_type;
@@ -386,10 +387,10 @@
         ret->looplen[i] = 1;
     }
 
-    ret->dot_solved = snewn(num_dots, char);
-    ret->face_solved = snewn(num_faces, char);
-    memset(ret->dot_solved, false, num_dots);
-    memset(ret->face_solved, false, num_faces);
+    ret->dot_solved = snewn(num_dots, bool);
+    ret->face_solved = snewn(num_faces, bool);
+    memset(ret->dot_solved, 0, num_dots * sizeof(bool));
+    memset(ret->face_solved, 0, num_faces * sizeof(bool));
 
     ret->dot_yes_count = snewn(num_dots, char);
     memset(ret->dot_yes_count, 0, num_dots);
@@ -455,10 +456,10 @@
     memcpy(ret->looplen, sstate->looplen,
            num_dots * sizeof(int));
 
-    ret->dot_solved = snewn(num_dots, char);
-    ret->face_solved = snewn(num_faces, char);
-    memcpy(ret->dot_solved, sstate->dot_solved, num_dots);
-    memcpy(ret->face_solved, sstate->face_solved, num_faces);
+    ret->dot_solved = snewn(num_dots, bool);
+    ret->face_solved = snewn(num_faces, bool);
+    memcpy(ret->dot_solved, sstate->dot_solved, num_dots * sizeof(bool));
+    memcpy(ret->face_solved, sstate->face_solved, num_faces * sizeof(bool));
 
     ret->dot_yes_count = snewn(num_dots, char);
     memcpy(ret->dot_yes_count, sstate->dot_yes_count, num_dots);
@@ -946,17 +947,17 @@
     int i;
 
     ds->tilesize = 0;
-    ds->started = 0;
+    ds->started = false;
     ds->lines = snewn(num_edges, char);
-    ds->clue_error = snewn(num_faces, char);
-    ds->clue_satisfied = snewn(num_faces, char);
+    ds->clue_error = snewn(num_faces, bool);
+    ds->clue_satisfied = snewn(num_faces, bool);
     ds->textx = snewn(num_faces, int);
     ds->texty = snewn(num_faces, int);
-    ds->flashing = 0;
+    ds->flashing = false;
 
     memset(ds->lines, LINE_UNKNOWN, num_edges);
-    memset(ds->clue_error, 0, num_faces);
-    memset(ds->clue_satisfied, 0, num_faces);
+    memset(ds->clue_error, 0, num_faces * sizeof(bool));
+    memset(ds->clue_satisfied, 0, num_faces * sizeof(bool));
     for (i = 0; i < num_faces; i++)
         ds->textx[i] = ds->texty[i] = -1;
 
@@ -1107,12 +1108,12 @@
 /* Sets the line (with index i) to the new state 'line_new', and updates
  * the cached counts of any affected faces and dots.
  * Returns true if this actually changed the line's state. */
-static int solver_set_line(solver_state *sstate, int i,
-                           enum line_state line_new
+static bool solver_set_line(solver_state *sstate, int i,
+                            enum line_state line_new
 #ifdef SHOW_WORKING
-			   , const char *reason
+                            , const char *reason
 #endif
-			   )
+                            )
 {
     game_state *state = sstate->state;
     grid *g;
@@ -1173,7 +1174,7 @@
  * Returns true if the dots were already linked, ie if they are part of a
  * closed loop, and false otherwise.
  */
-static int merge_dots(solver_state *sstate, int edge_index)
+static bool merge_dots(solver_state *sstate, int edge_index)
 {
     int i, j, len;
     grid *g = sstate->state->game_grid;
@@ -1199,11 +1200,11 @@
 /* Merge two lines because the solver has deduced that they must be either
  * identical or opposite.   Returns true if this is new information, otherwise
  * false. */
-static int merge_lines(solver_state *sstate, int i, int j, bool inverse
+static bool merge_lines(solver_state *sstate, int i, int j, bool inverse
 #ifdef SHOW_WORKING
-                       , const char *reason
+                        , const char *reason
 #endif
-		       )
+                        )
 {
     bool inv_tmp;
 
@@ -1268,10 +1269,10 @@
 
 /* Set all lines bordering a dot of type old_type to type new_type
  * Return value tells caller whether this function actually did anything */
-static int dot_setall(solver_state *sstate, int dot,
-		      char old_type, char new_type)
+static bool dot_setall(solver_state *sstate, int dot,
+                       char old_type, char new_type)
 {
-    int retval = false, r;
+    bool retval = false, r;
     game_state *state = sstate->state;
     grid *g;
     grid_dot *d;
@@ -1287,7 +1288,7 @@
         int line_index = d->edges[i] - g->edges;
         if (state->lines[line_index] == old_type) {
             r = solver_set_line(sstate, line_index, new_type);
-            assert(r == true);
+            assert(r);
             retval = true;
         }
     }
@@ -1295,10 +1296,10 @@
 }
 
 /* Set all lines bordering a face of type old_type to type new_type */
-static int face_setall(solver_state *sstate, int face,
-                       char old_type, char new_type)
+static bool face_setall(solver_state *sstate, int face,
+                        char old_type, char new_type)
 {
-    int retval = false, r;
+    bool retval = false, r;
     game_state *state = sstate->state;
     grid *g;
     grid_face *f;
@@ -1314,7 +1315,7 @@
         int line_index = f->edges[i] - g->edges;
         if (state->lines[line_index] == old_type) {
             r = solver_set_line(sstate, line_index, new_type);
-            assert(r == true);
+            assert(r);
             retval = true;
         }
     }
@@ -1356,9 +1357,9 @@
 }
 
 
-static int game_has_unique_soln(const game_state *state, int diff)
+static bool game_has_unique_soln(const game_state *state, int diff)
 {
-    int ret;
+    bool ret;
     solver_state *sstate_new;
     solver_state *sstate = new_solver_state((game_state *)state, diff);
 
@@ -1425,7 +1426,7 @@
 
     state->clues = snewn(g->num_faces, signed char);
     state->lines = snewn(g->num_edges, char);
-    state->line_errors = snewn(g->num_edges, unsigned char);
+    state->line_errors = snewn(g->num_edges, bool);
     state->exactly_one_loop = false;
 
     state->grid_type = params->type;
@@ -1433,9 +1434,10 @@
     newboard_please:
 
     memset(state->lines, LINE_UNKNOWN, g->num_edges);
-    memset(state->line_errors, 0, g->num_edges);
+    memset(state->line_errors, 0, g->num_edges * sizeof(bool));
 
-    state->solved = state->cheated = false;
+    state->solved = false;
+    state->cheated = false;
 
     /* Get a new random solvable board with all its clues filled in.  Yes, this
      * can loop for ever if the params are suitably unfavourable, but
@@ -1497,7 +1499,7 @@
 
     state->clues = snewn(num_faces, signed char);
     state->lines = snewn(num_edges, char);
-    state->line_errors = snewn(num_edges, unsigned char);
+    state->line_errors = snewn(num_edges, bool);
     state->exactly_one_loop = false;
 
     state->solved = state->cheated = false;
@@ -1528,21 +1530,22 @@
     }
 
     memset(state->lines, LINE_UNKNOWN, num_edges);
-    memset(state->line_errors, 0, num_edges);
+    memset(state->line_errors, 0, num_edges * sizeof(bool));
     return state;
 }
 
 /* Calculates the line_errors data, and checks if the current state is a
  * solution */
-static int check_completion(game_state *state)
+static bool check_completion(game_state *state)
 {
     grid *g = state->game_grid;
-    int i, ret;
+    int i;
+    bool ret;
     int *dsf, *component_state;
     int nsilly, nloop, npath, largest_comp, largest_size, total_pathsize;
     enum { COMP_NONE, COMP_LOOP, COMP_PATH, COMP_SILLY, COMP_EMPTY };
 
-    memset(state->line_errors, 0, g->num_edges);
+    memset(state->line_errors, 0, g->num_edges * sizeof(bool));
 
     /*
      * Find loops in the grid, and determine whether the puzzle is
@@ -1850,19 +1853,19 @@
 #endif
     return ret;
 }
-static int is_atleastone(const char *dline_array, int index)
+static bool is_atleastone(const char *dline_array, int index)
 {
     return BIT_SET(dline_array[index], 0);
 }
-static int set_atleastone(char *dline_array, int index)
+static bool set_atleastone(char *dline_array, int index)
 {
     return SET_BIT(dline_array[index], 0);
 }
-static int is_atmostone(const char *dline_array, int index)
+static bool is_atmostone(const char *dline_array, int index)
 {
     return BIT_SET(dline_array[index], 1);
 }
-static int set_atmostone(char *dline_array, int index)
+static bool set_atmostone(char *dline_array, int index)
 {
     return SET_BIT(dline_array[index], 1);
 }
@@ -1886,8 +1889,8 @@
  * will find the opposite UNKNOWNS (if they are adjacent to one another)
  * and set their corresponding dline to atleastone.  (Setting atmostone
  * already happens in earlier dline deductions) */
-static int dline_set_opp_atleastone(solver_state *sstate,
-                                    grid_dot *d, int edge)
+static bool dline_set_opp_atleastone(solver_state *sstate,
+                                     grid_dot *d, int edge)
 {
     game_state *state = sstate->state;
     grid *g = state->game_grid;
@@ -1918,14 +1921,14 @@
 
 /* Set pairs of lines around this face which are known to be identical, to
  * the given line_state */
-static int face_setall_identical(solver_state *sstate, int face_index,
-                                 enum line_state line_new)
+static bool face_setall_identical(solver_state *sstate, int face_index,
+                                  enum line_state line_new)
 {
     /* can[dir] contains the canonical line associated with the line in
      * direction dir from the square in question.  Similarly inv[dir] is
      * whether or not the line in question is inverse to its canonical
      * element. */
-    int retval = false;
+    bool retval = false;
     game_state *state = sstate->state;
     grid *g = state->game_grid;
     grid_face *f = g->faces + face_index;
@@ -2183,7 +2186,7 @@
             for (j = 0; j < f->order; j++) {
                 e = f->edges[j] - g->edges;
                 if (state->lines[e] == LINE_UNKNOWN && e != e1 && e != e2) {
-                    int r = solver_set_line(sstate, e, LINE_YES);
+                    bool r = solver_set_line(sstate, e, LINE_YES);
                     assert(r);
                     diff = min(diff, DIFF_EASY);
                 }
@@ -2653,7 +2656,7 @@
             /* Infer linedsf from dline flags */
             if (is_atmostone(dlines, dline_index)
 		&& is_atleastone(dlines, dline_index)) {
-                if (merge_lines(sstate, line1_index, line2_index, 1))
+                if (merge_lines(sstate, line1_index, line2_index, true))
                     diff = min(diff, DIFF_HARD);
             }
         }
@@ -2701,9 +2704,9 @@
     game_state *state = sstate->state;
     grid *g = state->game_grid;
     int shortest_chainlen = g->num_dots;
-    int loop_found = false;
+    bool loop_found = false;
     int dots_connected;
-    int progress = false;
+    bool progress = false;
     int i;
 
     /*
@@ -2836,7 +2839,7 @@
          * make.
          */
         progress = solver_set_line(sstate, i, val);
-        assert(progress == true);
+        assert(progress);
         if (val == LINE_YES) {
             sstate->solver_status = SOLVER_AMBIGUOUS;
             goto finished_loop_deductionsing;
@@ -3307,8 +3310,8 @@
     draw_circle(dr, x, y, 2, COL_FOREGROUND, COL_FOREGROUND);
 }
 
-static int boxes_intersect(int x0, int y0, int w0, int h0,
-                           int x1, int y1, int w1, int h1)
+static bool boxes_intersect(int x0, int y0, int w0, int h0,
+                            int x1, int y1, int w1, int h1)
 {
     /*
      * Two intervals intersect iff neither is wholly on one side of
@@ -3363,8 +3366,8 @@
     grid *g = state->game_grid;
     int border = BORDER(ds->tilesize);
     int i;
-    int flash_changed;
-    int redraw_everything = false;
+    bool flash_changed;
+    bool redraw_everything = false;
 
     int edges[REDRAW_OBJECTS_LIMIT], nedges = 0;
     int faces[REDRAW_OBJECTS_LIMIT], nfaces = 0;
@@ -3407,8 +3410,8 @@
         grid_face *f = g->faces + i;
         int sides = f->order;
         int yes_order, no_order;
-        int clue_mistake;
-        int clue_satisfied;
+        bool clue_mistake;
+        bool clue_satisfied;
         int n = state->clues[i];
         if (n < 0)
             continue;
@@ -3697,10 +3700,10 @@
     game_state *s;
     char *id = NULL, *desc;
     const char *err;
-    int grade = false;
+    bool grade = false;
     int ret, diff;
 #if 0 /* verbose solver not supported here (yet) */
-    int really_verbose = false;
+    bool really_verbose = false;
 #endif
 
     while (--argc > 0) {
--- a/magnets.c
+++ b/magnets.c
@@ -41,7 +41,7 @@
 #include "puzzles.h"
 
 #ifdef STANDALONE_SOLVER
-int verbose = 0;
+bool verbose = 0;
 #endif
 
 enum {
@@ -88,7 +88,8 @@
 /* Game parameter functions. */
 
 struct game_params {
-    int w, h, diff, stripclues;
+    int w, h, diff;
+    bool stripclues;
 };
 
 #define DEFAULT_PRESET 2
@@ -165,10 +166,10 @@
 	if (*string) string++;
     }
 
-    ret->stripclues = 0;
+    ret->stripclues = false;
     if (*string == 'S') {
         string++;
-        ret->stripclues = 1;
+        ret->stripclues = true;
     }
 }
 
@@ -267,8 +268,8 @@
     int w, h, wh;
     int *grid;                  /* size w*h, for cell state (pos/neg) */
     unsigned int *flags;        /* size w*h */
-    int solved, completed, numbered;
-    unsigned char *counts_done;
+    bool solved, completed, numbered;
+    bool *counts_done;
 
     struct game_common *common; /* domino layout never changes. */
 };
@@ -277,11 +278,13 @@
 {
     int i;
 
-    ret->solved = ret->completed = ret->numbered = 0;
+    ret->solved = false;
+    ret->completed = false;
+    ret->numbered = false;
 
     memset(ret->common->rowcount, 0, ret->h*3*sizeof(int));
     memset(ret->common->colcount, 0, ret->w*3*sizeof(int));
-    memset(ret->counts_done, 0, (ret->h + ret->w) * 2 * sizeof(unsigned char));
+    memset(ret->counts_done, 0, (ret->h + ret->w) * 2 * sizeof(bool));
 
     for (i = 0; i < ret->wh; i++) {
         ret->grid[i] = EMPTY;
@@ -301,7 +304,7 @@
 
     ret->grid = snewn(ret->wh, int);
     ret->flags = snewn(ret->wh, unsigned int);
-    ret->counts_done = snewn((ret->h + ret->w) * 2, unsigned char);
+    ret->counts_done = snewn((ret->h + ret->w) * 2, bool);
 
     ret->common = snew(struct game_common);
     ret->common->refcount = 1;
@@ -333,9 +336,9 @@
     dest->grid = snewn(dest->wh, int);
     memcpy(dest->grid, src->grid, dest->wh*sizeof(int));
 
-    dest->counts_done = snewn((dest->h + dest->w) * 2, unsigned char);
+    dest->counts_done = snewn((dest->h + dest->w) * 2, bool);
     memcpy(dest->counts_done, src->counts_done,
-           (dest->h + dest->w) * 2 * sizeof(unsigned char));
+           (dest->h + dest->w) * 2 * sizeof(bool));
 
     dest->flags = snewn(dest->wh, unsigned int);
     memcpy(dest->flags, src->flags, dest->wh*sizeof(unsigned int));
@@ -518,7 +521,7 @@
         }
     }
     /* Success. */
-    state->numbered = 1;
+    state->numbered = true;
     goto done;
 
 badchar:
@@ -728,7 +731,7 @@
 }
 
 static void check_rowcol(game_state *state, int num, int roworcol, int which,
-                        int *wrong, int *incomplete)
+                         bool *wrong, bool *incomplete)
 {
     int count, target = mkrowcol(state, num, roworcol).targets[which];
 
@@ -735,14 +738,15 @@
     if (target == -1) return; /* no number to check against. */
 
     count = count_rowcol(state, num, roworcol, which);
-    if (count < target) *incomplete = 1;
-    if (count > target) *wrong = 1;
+    if (count < target) *incomplete = true;
+    if (count > target) *wrong = true;
 }
 
 static int check_completion(game_state *state)
 {
     int i, j, x, y, idx, w = state->w, h = state->h;
-    int which = POSITIVE, wrong = 0, incomplete = 0;
+    int which = POSITIVE;
+    bool wrong = false, incomplete = false;
 
     /* Check row and column counts for magnets. */
     for (which = POSITIVE, j = 0; j < 2; which = OPPOSITE(which), j++) {
@@ -762,7 +766,7 @@
                 continue; /* no domino here */
 
             if (!(state->flags[idx] & GS_SET))
-                incomplete = 1;
+                incomplete = true;
 
             which = state->grid[idx];
             if (which != NEUTRAL) {
@@ -769,7 +773,7 @@
 #define CHECK(xx,yy) do { \
     if (INGRID(state,xx,yy) && \
         (state->grid[(yy)*w+(xx)] == which)) { \
-        wrong = 1; \
+        wrong = true; \
         state->flags[(yy)*w+(xx)] |= GS_ERROR; \
         state->flags[y*w+x] |= GS_ERROR; \
     } \
@@ -1100,7 +1104,8 @@
 
 static int solve_advancedfull(game_state *state, rowcol rc, int *counts)
 {
-    int i, j, nfound = 0, clearpos = 0, clearneg = 0, ret = 0;
+    int i, j, nfound = 0, ret = 0;
+    bool clearpos = false, clearneg = false;
 
     /* For this row/col, look for a domino entirely within the row where
      * both ends can only be + or - (but isn't held).
@@ -1146,11 +1151,11 @@
 
     if (rc.targets[POSITIVE] >= 0 && counts[POSITIVE] == rc.targets[POSITIVE]) {
         debug(("%s %d has now filled POSITIVE:", rc.name, rc.num));
-        clearpos = 1;
+        clearpos = true;
     }
     if (rc.targets[NEGATIVE] >= 0 && counts[NEGATIVE] == rc.targets[NEGATIVE]) {
         debug(("%s %d has now filled NEGATIVE:", rc.name, rc.num));
-        clearneg = 1;
+        clearneg = true;
     }
 
     if (!clearpos && !clearneg) return 0;
@@ -1202,7 +1207,8 @@
 static int solve_oddlength(game_state *state, rowcol rc, int *counts)
 {
     int i, j, ret = 0, extra, tpos, tneg;
-    int start = -1, length = 0, inempty = 0, startodd = -1;
+    int start = -1, length = 0, startodd = -1;
+    bool inempty = false;
 
     /* need zero neutral cells still to find... */
     if (rc.targets[NEUTRAL] != counts[NEUTRAL])
@@ -1225,7 +1231,7 @@
                     if (startodd != -1) goto twoodd;
                     startodd = start;
                 }
-                inempty = 0;
+                inempty = false;
             }
         } else {
             if (inempty)
@@ -1233,7 +1239,7 @@
             else {
                 start = i;
                 length = 1;
-                inempty = 1;
+                inempty = true;
             }
         }
     }
@@ -1259,7 +1265,8 @@
  * or to the #remaining negative, no empty cells can be neutral. */
 static int solve_countdominoes_neutral(game_state *state, rowcol rc, int *counts)
 {
-    int i, j, ndom = 0, nonn = 0, ret = 0;
+    int i, j, ndom = 0, ret = 0;
+    bool nonn = false;
 
     if ((rc.targets[POSITIVE] == -1) && (rc.targets[NEGATIVE] == -1))
         return 0; /* need at least one target to compare. */
@@ -1278,10 +1285,10 @@
 
     if ((rc.targets[POSITIVE] != -1) &&
         (rc.targets[POSITIVE]-counts[POSITIVE] == ndom))
-        nonn = 1;
+        nonn = true;
     if ((rc.targets[NEGATIVE] != -1) &&
         (rc.targets[NEGATIVE]-counts[NEGATIVE] == ndom))
-        nonn = 1;
+        nonn = true;
 
     if (!nonn) return 0;
 
@@ -1400,7 +1407,7 @@
 
 
 static char *game_state_diff(const game_state *src, const game_state *dst,
-                             int issolve)
+                             bool issolve)
 {
     char *ret = NULL, buf[80], c;
     int retlen = 0, x, y, i, k;
@@ -1473,7 +1480,7 @@
     return NULL;
 
 solved:
-    move = game_state_diff(currstate, solved, 1);
+    move = game_state_diff(currstate, solved, true);
     free_game(solved);
     return move;
 }
@@ -1598,7 +1605,7 @@
             new->common->rowcount[y*3+val]++;
         }
     }
-    new->numbered = 1;
+    new->numbered = true;
 
     sfree(scratch);
 }
@@ -1705,7 +1712,8 @@
 }
 
 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)
@@ -1712,7 +1720,7 @@
 {
     game_ui *ui = snew(game_ui);
     ui->cur_x = ui->cur_y = 0;
-    ui->cur_visible = 0;
+    ui->cur_visible = false;
     return ui;
 }
 
@@ -1734,11 +1742,12 @@
                                const game_state *newstate)
 {
     if (!oldstate->completed && newstate->completed)
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
 }
 
 struct game_drawstate {
-    int tilesize, started, solved;
+    int tilesize;
+    bool started, solved;
     int w, h;
     unsigned long *what;                /* size w*h */
     unsigned long *colwhat, *rowwhat;   /* size 3*w, 3*h */
@@ -1761,7 +1770,7 @@
 #define COORD(x) ( (x+1) * TILE_SIZE + BORDER )
 #define FROMCOORD(x) ( (x - BORDER) / TILE_SIZE - 1 )
 
-static int is_clue(const game_state *state, int x, int y)
+static bool is_clue(const game_state *state, int x, int y)
 {
     int h = state->h, w = state->w;
 
@@ -1797,12 +1806,12 @@
     enum { CYCLE_MAGNET, CYCLE_NEUTRAL } action;
 
     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;
         return UI_UPDATE;
     } else if (IS_CURSOR_SELECT(button)) {
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
         action = (button == CURSOR_SELECT) ? CYCLE_MAGNET : CYCLE_NEUTRAL;
@@ -1811,7 +1820,7 @@
     } else if (INGRID(state, gx, gy) &&
                (button == LEFT_BUTTON || button == RIGHT_BUTTON)) {
         if (ui->cur_visible) {
-            ui->cur_visible = 0;
+            ui->cur_visible = false;
             nullret = UI_UPDATE;
         }
         action = (button == LEFT_BUTTON) ? CYCLE_MAGNET : CYCLE_NEUTRAL;
@@ -1905,7 +1914,7 @@
         else if (*move) goto badmove;
     }
     if (check_completion(ret) == 1)
-        ret->completed = 1;
+        ret->completed = true;
 
     return ret;
 
@@ -1973,7 +1982,9 @@
 {
     struct game_drawstate *ds = snew(struct game_drawstate);
 
-    ds->tilesize = ds->started = ds->solved = 0;
+    ds->tilesize = 0;
+    ds->started = false;
+    ds->solved = false;
     ds->w = state->w;
     ds->h = state->h;
 
@@ -2188,7 +2199,8 @@
                         int dir, const game_ui *ui,
                         float animtime, float flashtime)
 {
-    int x, y, w = state->w, h = state->h, which, i, j, flash;
+    int x, y, w = state->w, h = state->h, which, i, j;
+    bool flash;
 
     flash = (int)(flashtime * 5 / FLASH_TIME) % 2;
 
@@ -2261,7 +2273,7 @@
         }
     }
 
-    ds->started = 1;
+    ds->started = true;
 }
 
 static float game_anim_length(const game_state *oldstate,
@@ -2433,7 +2445,7 @@
 #include <stdarg.h>
 
 const char *quis = NULL;
-int csv = 0;
+bool csv = false;
 
 void usage(FILE *out) {
     fprintf(out, "usage: %s [-v] [--print] <params>|<game id>\n", quis);
@@ -2535,7 +2547,8 @@
 
 int main(int argc, const char *argv[])
 {
-    int print = 0, soak = 0, solved = 0, ret;
+    bool print = false, soak = false, solved = false;
+    int ret;
     char *id = NULL, *desc, *desc_gen = NULL, *aux = NULL;
     const char *err;
     game_state *s = NULL;
@@ -2549,16 +2562,16 @@
     while (--argc > 0) {
         char *p = (char*)(*++argv);
         if (!strcmp(p, "-v") || !strcmp(p, "--verbose")) {
-            verbose = 1;
+            verbose = true;
         } else if (!strcmp(p, "--csv")) {
-            csv = 1;
+            csv = true;
         } else if (!strcmp(p, "-e") || !strcmp(p, "--seed")) {
             seed = atoi(*++argv);
             argc--;
         } else if (!strcmp(p, "-p") || !strcmp(p, "--print")) {
-            print = 1;
+            print = true;
         } 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);
@@ -2579,7 +2592,7 @@
 
     p = default_params();
     decode_params(p, id);
-    err = validate_params(p, 1);
+    err = validate_params(p, true);
     if (err) {
         fprintf(stderr, "%s: %s", argv[0], err);
         goto done;
@@ -2595,7 +2608,7 @@
     }
 
     if (!desc)
-        desc = desc_gen = new_game_desc(p, rs, &aux, 0);
+        desc = desc_gen = new_game_desc(p, rs, &aux, false);
 
     err = validate_desc(p, desc);
     if (err) {
@@ -2609,17 +2622,17 @@
         if (verbose || print) {
             doprint(s);
             solve_from_aux(s, aux);
-            solved = 1;
+            solved = true;
         }
     } else {
         doprint(s);
-        verbose = 1;
+        verbose = true;
         ret = solve_state(s, DIFFCOUNT);
         if (ret < 0) printf("Puzzle is impossible.\n");
         else if (ret == 0) printf("Puzzle is ambiguous.\n");
         else printf("Puzzle was solved.\n");
-        verbose = 0;
-        solved = 1;
+        verbose = false;
+        solved = true;
     }
     if (solved) doprint(s);
 
--- a/map.c
+++ b/map.c
@@ -25,7 +25,7 @@
  */
 #if defined STANDALONE_SOLVER
 #define SOLVER_DIAGNOSTICS
-int verbose = false;
+bool verbose = false;
 #elif defined SOLVER_DIAGNOSTICS
 #define verbose true
 #endif
@@ -84,7 +84,7 @@
     int *graph;
     int n;
     int ngraph;
-    int *immutable;
+    bool *immutable;
     int *edgex, *edgey;		       /* position of a point on each edge */
     int *regionx, *regiony;            /* position of a point in each region */
 };
@@ -93,7 +93,7 @@
     game_params p;
     struct map *map;
     int *colouring, *pencil;
-    int completed, cheated;
+    bool completed, cheated;
 };
 
 static game_params *default_params(void)
@@ -680,8 +680,8 @@
  * the sake of the Palm port and its limited stack.
  */
 
-static int fourcolour_recurse(int *graph, int n, int ngraph,
-			      int *colouring, int *scratch, random_state *rs)
+static bool fourcolour_recurse(int *graph, int n, int ngraph,
+                               int *colouring, int *scratch, random_state *rs)
 {
     int nfree, nvert, start, i, j, k, c, ci;
     int cs[FOUR];
@@ -783,6 +783,7 @@
 {
     int *scratch;
     int i;
+    bool retd;
 
     /*
      * For each vertex and each colour, we store the number of
@@ -799,8 +800,8 @@
     for (i = 0; i < n; i++)
 	colouring[i] = -1;
 
-    i = fourcolour_recurse(graph, n, ngraph, colouring, scratch, rs);
-    assert(i);			       /* by the Four Colour Theorem :-) */
+    retd = fourcolour_recurse(graph, n, ngraph, colouring, scratch, rs);
+    assert(retd);                 /* by the Four Colour Theorem :-) */
 
     sfree(scratch);
 }
@@ -870,12 +871,12 @@
 static const char colnames[FOUR] = { 'R', 'Y', 'G', 'B' };
 #endif
 
-static int place_colour(struct solver_scratch *sc,
-			int *colouring, int index, int colour
+static bool place_colour(struct solver_scratch *sc,
+                         int *colouring, int index, int colour
 #ifdef SOLVER_DIAGNOSTICS
-                        , const char *verb
+                         , const char *verb
 #endif
-                        )
+                         )
 {
     int *graph = sc->graph, n = sc->n, ngraph = sc->ngraph;
     int j, k;
@@ -974,7 +975,7 @@
      * Now repeatedly loop until we find nothing further to do.
      */
     while (1) {
-	int done_something = false;
+	bool done_something = false;
 
         if (difficulty < DIFF_EASY)
             break;                     /* can't do anything at all! */
@@ -996,7 +997,8 @@
             }
 
 	    if ((p & (p-1)) == 0) {    /* p is a power of two */
-		int c, ret;
+		int c;
+                bool ret;
 		for (c = 0; c < FOUR; c++)
 		    if (p == (1 << c))
 			break;
@@ -1040,7 +1042,7 @@
             int j1 = graph[i] / n, j2 = graph[i] % n;
             int j, k, v, v2;
 #ifdef SOLVER_DIAGNOSTICS
-            int started = false;
+            bool started = false;
 #endif
 
             if (j1 > j2)
@@ -1279,7 +1281,7 @@
         struct solver_scratch *rsc;
         int *subcolouring, *origcolouring;
         int ret, subret;
-        int we_already_got_one;
+        bool we_already_got_one;
 
         best = -1;
         bestc = FIVE;
@@ -1601,7 +1603,8 @@
     ret = NULL;
 
     {
-	int run, pv;
+	int run;
+        bool pv;
 
 	/*
 	 * Start with a notional non-edge, so that there'll be an
@@ -1609,10 +1612,11 @@
 	 * an edge.
 	 */
 	run = 1;
-	pv = 0;
+	pv = false;
 
 	for (i = 0; i < w*(h-1) + (w-1)*h; i++) {
-	    int x, y, dx, dy, v;
+	    int x, y, dx, dy;
+            bool v;
 
 	    if (i < w*(h-1)) {
 		/* Horizontal edge. */
@@ -1704,13 +1708,14 @@
                                    const char **desc, int *map)
 {
     int w = params->w, h = params->h, wh = w*h, n = params->n;
-    int i, k, pos, state;
+    int i, k, pos;
+    bool state;
     const char *p = *desc;
 
     dsf_init(map+wh, wh);
 
     pos = -1;
-    state = 0;
+    state = false;
 
     /*
      * Parse the game description to get the list of edges, and
@@ -1828,7 +1833,8 @@
     for (i = 0; i < n; i++)
 	state->pencil[i] = 0;
 
-    state->completed = state->cheated = false;
+    state->completed = false;
+    state->cheated = false;
 
     state->map = snew(struct map);
     state->map->refcount = 1;
@@ -1835,7 +1841,7 @@
     state->map->map = snewn(wh*4, int);
     state->map->graph = snewn(n*n, int);
     state->map->n = n;
-    state->map->immutable = snewn(n, int);
+    state->map->immutable = snewn(n, bool);
     for (i = 0; i < n; i++)
 	state->map->immutable[i] = false;
 
@@ -1882,7 +1888,7 @@
     {
         random_state *rs = random_new(desc, strlen(desc));
         int *squares = snewn(wh, int);
-        int done_something;
+        bool done_something;
 
         for (i = 0; i < wh; i++)
             squares[i] = i;
@@ -2268,9 +2274,10 @@
     int drag_colour;
     int drag_pencil;
     int dragx, dragy;
-    int show_numbers;
+    bool show_numbers;
 
-    int cur_x, cur_y, cur_visible, cur_moved, cur_lastmove;
+    int cur_x, cur_y, cur_lastmove;
+    bool cur_visible, cur_moved;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -2280,7 +2287,9 @@
     ui->drag_colour = -2;
     ui->drag_pencil = 0;
     ui->show_numbers = false;
-    ui->cur_x = ui->cur_y = ui->cur_visible = ui->cur_moved = 0;
+    ui->cur_x = ui->cur_y = 0;
+    ui->cur_visible = false;
+    ui->cur_moved = false;
     ui->cur_lastmove = 0;
     return ui;
 }
@@ -2307,8 +2316,9 @@
 struct game_drawstate {
     int tilesize;
     unsigned long *drawn, *todraw;
-    int started;
-    int dragx, dragy, drag_visible;
+    bool started;
+    int dragx, dragy;
+    bool drag_visible;
     blitter *bl;
 };
 
@@ -2383,7 +2393,8 @@
                             int x, int y, int button)
 {
     char *bufp, buf[256];
-    int alt_button, drop_region;
+    bool alt_button;
+    int drop_region;
 
     /*
      * Enable or disable numeric labels on regions.
@@ -2394,15 +2405,16 @@
     }
 
     if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->cur_x, &ui->cur_y, state->p.w, state->p.h, 0);
-        ui->cur_visible = 1;
-        ui->cur_moved = 1;
+        move_cursor(button, &ui->cur_x, &ui->cur_y, state->p.w, state->p.h,
+                    false);
+        ui->cur_visible = true;
+        ui->cur_moved = true;
         ui->cur_lastmove = button;
         return UI_UPDATE;
     }
     if (IS_CURSOR_SELECT(button)) {
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
         if (ui->drag_colour == -2) { /* not currently cursor-dragging, start. */
@@ -2414,10 +2426,10 @@
                 ui->drag_colour = -1;
                 ui->drag_pencil = 0;
             }
-            ui->cur_moved = 0;
+            ui->cur_moved = false;
             return UI_UPDATE;
         } else { /* currently cursor-dragging; drop the colour in the new region. */
-            alt_button = (button == CURSOR_SELECT2) ? 1 : 0;
+            alt_button = (button == CURSOR_SELECT2);
             /* Double-select removes current colour. */
             if (!ui->cur_moved) ui->drag_colour = -1;
             drop_region = region_from_ui_cursor(state, ui);
@@ -2439,7 +2451,7 @@
 	}
         ui->dragx = x;
         ui->dragy = y;
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
         return UI_UPDATE;
     }
 
@@ -2452,7 +2464,7 @@
 
     if ((button == LEFT_RELEASE || button == RIGHT_RELEASE) &&
         ui->drag_colour > -2) {
-        alt_button = (button == RIGHT_RELEASE) ? 1 : 0;
+        alt_button = (button == RIGHT_RELEASE);
         drop_region = region_from_coords(state, ds, x, y);
         goto drag_dropped;
     }
@@ -2518,7 +2530,7 @@
     int c, k, adv, i;
 
     while (*move) {
-        int pencil = false;
+        bool pencil = false;
 
 	c = *move;
         if (c == 'p') {
@@ -2562,7 +2574,7 @@
      * Check for completion.
      */
     if (!ret->completed) {
-	int ok = true;
+	bool ok = true;
 
 	for (i = 0; i < n; i++)
 	    if (ret->colouring[i] < 0) {
@@ -2987,7 +2999,8 @@
      * Draw the dragged colour blob if any.
      */
     if ((ui->drag_colour > -2) || ui->cur_visible) {
-        int bg, iscur = 0, cursor_x, cursor_y;
+        int bg, cursor_x, cursor_y;
+        bool iscur = false;
         if (ui->drag_colour >= 0)
             bg = COL_0 + ui->drag_colour;
         else if (ui->drag_colour == -1) {
@@ -2997,7 +3010,7 @@
             int c = (r < 0) ? -1 : state->colouring[r];
             /*bg = COL_GRID;*/
             bg = (c < 0) ? COL_BACKGROUND : COL_0 + c;
-            iscur = 1;
+            iscur = true;
         }
 
         if (ui->cur_visible) {
@@ -3262,8 +3275,9 @@
     game_state *s;
     char *id = NULL, *desc;
     const char *err;
-    int grade = false;
-    int ret, diff, really_verbose = false;
+    bool grade = false;
+    int ret, diff;
+    bool really_verbose = false;
     struct solver_scratch *sc;
     int i;
 
--- a/matching.c
+++ b/matching.c
@@ -135,7 +135,7 @@
 
         layer = 0;
         while (1) {
-            int found_free_R_vertex = false;
+            bool found_free_R_vertex = false;
 
             Rqs = 0;
             for (i = 0; i < Lqs; i++) {
@@ -685,7 +685,7 @@
 {
     static const char stdin_identifier[] = "<standard input>";
     const char *infile = NULL;
-    int doing_opts = true;
+    bool doing_opts = true;
     enum { USER_INPUT, AUTOTEST } mode = USER_INPUT;
 
     while (--argc > 0) {
--- a/midend.c
+++ b/midend.c
@@ -69,7 +69,7 @@
     struct midend_state_entry *states;
 
     struct midend_serialise_buf newgame_undo, newgame_redo;
-    int newgame_can_store_undo;
+    bool newgame_can_store_undo;
 
     game_params *params, *curparams;
     game_drawstate *drawstate;
@@ -80,7 +80,7 @@
     float flash_time, flash_pos;
     int dir;
 
-    int timing;
+    bool timing;
     float elapsed;
     char *laststatus;
 
@@ -573,7 +573,7 @@
 }
 
 struct newgame_undo_deserialise_check_ctx {
-    int refused;
+    bool refused;
 };
 
 static const char *newgame_undo_deserialise_check(
@@ -628,7 +628,7 @@
     return NULL;
 }
 
-static int midend_undo(midend *me)
+static bool midend_undo(midend *me)
 {
     const char *deserialise_error;
 
@@ -639,7 +639,7 @@
                                        me->states[me->statepos-2].state);
 	me->statepos--;
         me->dir = -1;
-        return 1;
+        return true;
     } else if (me->newgame_undo.len) {
 	struct newgame_undo_deserialise_read_ctx rctx;
 	struct newgame_undo_deserialise_check_ctx cctx;
@@ -669,7 +669,7 @@
              * function, which we ignore.)
              */
             sfree(serbuf.buf);
-            return 0;
+            return false;
         } else {
             /*
              * There should never be any _other_ deserialisation
@@ -695,13 +695,13 @@
             newgame_serialise_write(&me->newgame_redo, serbuf.buf, serbuf.len);
 
             sfree(serbuf.buf);
-            return 1;
+            return true;
         }
     } else
-        return 0;
+        return false;
 }
 
-static int midend_redo(midend *me)
+static bool midend_redo(midend *me)
 {
     const char *deserialise_error;
 
@@ -712,7 +712,7 @@
                                        me->states[me->statepos].state);
 	me->statepos++;
         me->dir = +1;
-        return 1;
+        return true;
     } else if (me->newgame_redo.len) {
 	struct newgame_undo_deserialise_read_ctx rctx;
 	struct newgame_undo_deserialise_check_ctx cctx;
@@ -742,7 +742,7 @@
              * function, which we ignore.)
              */
             sfree(serbuf.buf);
-            return 0;
+            return false;
         } else {
             /*
              * There should never be any _other_ deserialisation
@@ -768,10 +768,10 @@
             newgame_serialise_write(&me->newgame_undo, serbuf.buf, serbuf.len);
 
             sfree(serbuf.buf);
-            return 1;
+            return true;
         }
     } else
-        return 0;
+        return false;
 }
 
 static void midend_finish_move(midend *me)
@@ -856,7 +856,8 @@
 {
     game_state *oldstate =
         me->ourgame->dup_game(me->states[me->statepos - 1].state);
-    int type = MOVE, gottype = false, ret = true;
+    int type = MOVE;
+    bool gottype = false, ret = true;
     float anim_time;
     game_state *s;
     char *movestr = NULL;
@@ -1161,7 +1162,7 @@
 
 void midend_timer(midend *me, float tplus)
 {
-    int need_redraw = (me->anim_time > 0 || me->flash_time > 0);
+    bool need_redraw = (me->anim_time > 0 || me->flash_time > 0);
 
     me->anim_pos += tplus;
     if (me->anim_pos >= me->anim_time ||
@@ -1283,7 +1284,7 @@
 }
 
 static char *preset_menu_add_from_user_env(
-    midend *me, struct preset_menu *menu, char *p, int top_level)
+    midend *me, struct preset_menu *menu, char *p, bool top_level)
 {
     while (*p) {
         char *name, *val;
@@ -1537,7 +1538,7 @@
     char *par = NULL;
     const char *desc, *seed;
     game_params *newcurparams, *newparams, *oldparams1, *oldparams2;
-    int free_params;
+    bool free_params;
 
     seed = strchr(id, '#');
     desc = strchr(id, ':');
@@ -2066,7 +2067,7 @@
 {
     struct deserialise_data data;
     int gotstates = 0;
-    int started = false;
+    bool started = false;
     int i;
 
     char *val = NULL;
@@ -2445,7 +2446,7 @@
                           void *rctx)
 {
     int nstates = 0, statepos = -1, gotstates = 0;
-    int started = false;
+    bool started = false;
 
     char *val = NULL;
     /* Initially all errors give the same report */
--- a/mines.c
+++ b/mines.c
@@ -43,7 +43,7 @@
 
 struct game_params {
     int w, h, n;
-    int unique;
+    bool unique;
 };
 
 struct mine_layout {
@@ -52,19 +52,20 @@
      * given instance of the puzzle, so we reference-count it.
      */
     int refcount;
-    char *mines;
+    bool *mines;
     /*
      * If we haven't yet actually generated the mine layout, here's
      * all the data we will need to do so.
      */
-    int n, unique;
+    int n;
+    bool unique;
     random_state *rs;
     midend *me;		       /* to give back the new game desc */
 };
 
 struct game_state {
-    int w, h, n, dead, won;
-    int used_solve;
+    int w, h, n;
+    bool dead, won, used_solve;
     struct mine_layout *layout;	       /* real mine positions */
     signed char *grid;			       /* player knowledge */
     /*
@@ -296,7 +297,7 @@
  */
 struct set {
     short x, y, mask, mines;
-    int todo;
+    bool todo;
     struct set *prev, *next;
 };
 
@@ -340,7 +341,7 @@
  * with the second. Return the new mask part of the first set.
  */
 static int setmunge(int x1, int y1, int mask1, int x2, int y2, int mask2,
-		    int diff)
+		    bool diff)
 {
     /*
      * Adjust the second set so that it has the same x,y
@@ -569,7 +570,7 @@
 static void known_squares(int w, int h, struct squaretodo *std,
                           signed char *grid,
 			  open_cb open, void *openctx,
-			  int x, int y, int mask, int mine)
+			  int x, int y, int mask, bool mine)
 {
     int xx, yy, bit;
 
@@ -671,7 +672,7 @@
      * Main deductive loop.
      */
     while (1) {
-	int done_something = false;
+	bool done_something = false;
 	struct set *s;
 
 	/*
@@ -891,7 +892,8 @@
 	     */
 
 	    int minesleft, squaresleft;
-	    int nsets, setused[10], cursor;
+	    int nsets, cursor;
+            bool setused[10];
 
 	    /*
 	     * Start by scanning the current grid state to work out
@@ -972,10 +974,9 @@
 		 * I'm going to use a virtual recursion within this
 		 * function. The way this works is:
 		 * 
-		 *  - we have an array `setused', such that
-		 *    setused[n] is 0 or 1 depending on whether set
-		 *    n is currently in the union we are
-		 *    considering.
+		 *  - we have an array `setused', such that setused[n]
+		 *    is true if set n is currently in the union we
+		 *    are considering.
 		 * 
 		 *  - we have a value `cursor' which indicates how
 		 *    much of `setused' we have so far filled in.
@@ -983,11 +984,10 @@
 		 * 
 		 * We begin by setting `cursor' to zero. Then:
 		 * 
-		 *  - if cursor can advance, we advance it by one.
-		 *    We set the value in `setused' that it went
-		 *    past to 1 if that set is disjoint from
-		 *    anything else currently in `setused', or to 0
-		 *    otherwise.
+		 *  - if cursor can advance, we advance it by one. We
+		 *    set the value in `setused' that it went past to
+		 *    true if that set is disjoint from anything else
+		 *    currently in `setused', or to false otherwise.
 		 * 
 		 *  - If cursor cannot advance because it has
 		 *    reached the end of the setused list, then we
@@ -996,10 +996,10 @@
 		 *    properties. If so, mark all the squares not
 		 *    in the union as known and terminate.
 		 * 
-		 *  - If cursor has reached the end of setused and
-		 *    the algorithm _hasn't_ terminated, back
-		 *    cursor up to the nearest 1, turn it into a 0
-		 *    and advance cursor just past it.
+		 *  - If cursor has reached the end of setused and the
+		 *    algorithm _hasn't_ terminated, back cursor up to
+		 *    the nearest true entry, reset it to false, and
+		 *    advance cursor just past it.
 		 * 
 		 *  - If we attempt to back up to the nearest 1 and
 		 *    there isn't one at all, then we have gone
@@ -1015,7 +1015,7 @@
 		while (1) {
 
 		    if (cursor < nsets) {
-			int ok = true;
+			bool ok = true;
 
 			/* See if any existing set overlaps this one. */
 			for (i = 0; i < cursor; i++)
@@ -1065,7 +1065,7 @@
 			     */
 			    for (i = 0; i < w*h; i++)
 				if (grid[i] == -2) {
-				    int outside = true;
+                                    bool outside = true;
 				    y = i / w;
 				    x = i % w;
 				    for (j = 0; j < nsets; j++)
@@ -1104,7 +1104,7 @@
 			    minesleft += sets[cursor]->mines;
 			    squaresleft += bitcount16(sets[cursor]->mask);
 
-			    setused[cursor++] = 0;
+			    setused[cursor++] = false;
 			} else {
 			    /*
 			     * We've backtracked all the way to the
@@ -1299,10 +1299,10 @@
  */
 
 struct minectx {
-    char *grid;
+    bool *grid;
     int w, h;
     int sx, sy;
-    int allow_big_perturbs;
+    bool allow_big_perturbs;
     random_state *rs;
 };
 
@@ -1720,11 +1720,11 @@
     return ret;
 }
 
-static char *minegen(int w, int h, int n, int x, int y, int unique,
+static bool *minegen(int w, int h, int n, int x, int y, bool unique,
 		     random_state *rs)
 {
-    char *ret = snewn(w*h, char);
-    int success;
+    bool *ret = snewn(w*h, bool);
+    bool success;
     int ntries = 0;
 
     do {
@@ -1756,7 +1756,7 @@
 	    nn = n;
 	    while (nn-- > 0) {
 		i = random_upto(rs, k);
-		ret[tmp[i]] = 1;
+		ret[tmp[i]] = true;
 		tmp[i] = tmp[--k];
 	    }
 
@@ -1832,8 +1832,8 @@
     return ret;
 }
 
-static char *describe_layout(char *grid, int area, int x, int y,
-                             int obfuscate)
+static char *describe_layout(bool *grid, int area, int x, int y,
+                             bool obfuscate)
 {
     char *ret, *p;
     unsigned char *bmp;
@@ -1873,10 +1873,10 @@
     return ret;
 }
 
-static char *new_mine_layout(int w, int h, int n, int x, int y, int unique,
+static bool *new_mine_layout(int w, int h, int n, int x, int y, bool unique,
 			     random_state *rs, char **game_desc)
 {
-    char *grid;
+    bool *grid;
 
 #ifdef TEST_OBFUSCATION
     static int tested_obfuscation = false;
@@ -1970,7 +1970,7 @@
 	/*
 	 * For batch-generated grids, pre-open one square.
 	 */
-	char *grid;
+	bool *grid;
 	char *desc;
 
 	grid = new_mine_layout(params->w, params->h, params->n,
@@ -2099,7 +2099,7 @@
      * using repeated N^2 scans of the grid.
      */
     while (1) {
-	int done_something = false;
+	bool done_something = false;
 
 	for (yy = 0; yy < h; yy++)
 	    for (xx = 0; xx < w; xx++)
@@ -2165,7 +2165,8 @@
                             const char *desc)
 {
     game_state *state = snew(game_state);
-    int i, wh, x, y, masked;
+    int i, wh, x, y;
+    bool masked;
     unsigned char *bmp;
 
     state->w = params->w;
@@ -2203,7 +2204,7 @@
     } else {
 	state->layout->rs = NULL;
 	state->layout->me = NULL;
-	state->layout->mines = snewn(wh, char);
+	state->layout->mines = snewn(wh, bool);
 
 	if (*desc && isdigit((unsigned char)*desc)) {
 	    x = atoi(desc);
@@ -2253,10 +2254,10 @@
 	if (masked)
 	    obfuscate_bitmap(bmp, wh, true);
 
-	memset(state->layout->mines, 0, wh);
+	memset(state->layout->mines, 0, wh * sizeof(bool));
 	for (i = 0; i < wh; i++) {
 	    if (bmp[i / 8] & (0x80 >> (i % 8)))
-		state->layout->mines[i] = 1;
+		state->layout->mines[i] = true;
 	}
 
 	if (x >= 0 && y >= 0)
@@ -2344,9 +2345,11 @@
 struct game_ui {
     int hx, hy, hradius;	       /* for mouse-down highlights */
     int validradius;
-    int flash_is_death;
-    int deaths, completed;
-    int cur_x, cur_y, cur_visible;
+    bool flash_is_death;
+    int deaths;
+    bool completed;
+    int cur_x, cur_y;
+    bool cur_visible;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -2357,7 +2360,8 @@
     ui->deaths = 0;
     ui->completed = false;
     ui->flash_is_death = false;	       /* *shrug* */
-    ui->cur_x = ui->cur_y = ui->cur_visible = 0;
+    ui->cur_x = ui->cur_y = 0;
+    ui->cur_visible = false;
     return ui;
 }
 
@@ -2395,7 +2399,8 @@
 }
 
 struct game_drawstate {
-    int w, h, started, tilesize, bg;
+    int w, h, tilesize, bg;
+    bool started;
     signed char *grid;
     /*
      * Items in this `grid' array have all the same values as in
@@ -2424,8 +2429,8 @@
     cy = FROMCOORD(y);
 
     if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, 0);
-        ui->cur_visible = 1;
+        move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, false);
+        ui->cur_visible = true;
         return UI_UPDATE;
     }
     if (IS_CURSOR_SELECT(button)) {
@@ -2432,7 +2437,7 @@
         int v = from->grid[ui->cur_y * from->w + ui->cur_x];
 
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
         if (button == CURSOR_SELECT2) {
@@ -2472,7 +2477,7 @@
 	    ui->validradius = ui->hradius;
 	else if (button == MIDDLE_BUTTON)
 	    ui->validradius = 1;
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
 	return UI_UPDATE;
     }
 
@@ -2956,7 +2961,8 @@
 {
     int x, y;
     int mines, markers, closed, bg;
-    int cx = -1, cy = -1, cmoved;
+    int cx = -1, cy = -1;
+    bool cmoved;
 
     if (flashtime) {
 	int frame = (int)(flashtime / FLASH_FRAME);
@@ -3010,7 +3016,8 @@
     mines = markers = closed = 0;
     for (y = 0; y < ds->h; y++)
 	for (x = 0; x < ds->w; x++) {
-	    int v = state->grid[y*ds->w+x], cc = 0;
+	    int v = state->grid[y*ds->w+x];
+            bool cc = false;
 
             if (v < 0)
                 closed++;
@@ -3045,7 +3052,7 @@
 
             if (cmoved && /* if cursor has moved, force redraw of curr and prev pos */
                 ((x == cx && y == cy) || (x == ds->cur_x && y == ds->cur_y)))
-              cc = 1;
+              cc = true;
 
 	    if (ds->grid[y*ds->w+x] != v || bg != ds->bg || cc) {
 		draw_tile(dr, ds, COORD(x), COORD(y), v,
--- a/nestedvm.c
+++ b/nestedvm.c
@@ -31,10 +31,11 @@
 struct frontend {
     // TODO kill unneeded members!
     midend *me;
-    int timer_active;
+    bool timer_active;
     struct timeval last_time;
     config_item *cfg;
-    int cfg_which, cfgret;
+    int cfg_which;
+    bool cfgret;
     int ox, oy, w, h;
 };
 
@@ -291,7 +292,7 @@
     i->u.choices.selected = selected;
 }
 
-static int get_config(frontend *fe, int which)
+static bool get_config(frontend *fe, int which)
 {
     char *title;
     config_item *i;
--- a/net.c
+++ b/net.c
@@ -83,8 +83,8 @@
 struct game_params {
     int width;
     int height;
-    int wrapping;
-    int unique;
+    bool wrapping;
+    bool unique;
     float barrier_probability;
 };
 
@@ -94,9 +94,10 @@
 } game_immutable_state;
 
 struct game_state {
-    int width, height, wrapping, completed;
+    int width, height;
+    bool wrapping, completed;
     int last_rotate_x, last_rotate_y, last_rotate_dir;
-    int used_solve;
+    bool used_solve;
     unsigned char *tiles;
     struct game_immutable_state *imm;
 };
@@ -396,7 +397,7 @@
  */
 
 struct todo {
-    unsigned char *marked;
+    bool *marked;
     int *buffer;
     int buflen;
     int head, tail;
@@ -405,7 +406,7 @@
 static struct todo *todo_new(int maxsize)
 {
     struct todo *todo = snew(struct todo);
-    todo->marked = snewn(maxsize, unsigned char);
+    todo->marked = snewn(maxsize, bool);
     memset(todo->marked, 0, maxsize);
     todo->buflen = maxsize + 1;
     todo->buffer = snewn(todo->buflen, int);
@@ -449,7 +450,7 @@
  * fully.
  */
 static int net_solver(int w, int h, unsigned char *tiles,
-		      unsigned char *barriers, int wrapping)
+		      unsigned char *barriers, bool wrapping)
 {
     unsigned char *tilestate;
     unsigned char *edgestate;
@@ -458,7 +459,7 @@
     struct todo *todo;
     int i, j, x, y;
     int area;
-    int done_something;
+    bool done_something;
 
     /*
      * Set up the solver's data structures.
@@ -628,7 +629,7 @@
 	    deadendmax[1] = deadendmax[2] = deadendmax[4] = deadendmax[8] = 0;
 
 	    for (i = j = 0; i < 4 && tilestate[(y*w+x) * 4 + i] != 255; i++) {
-		int valid;
+		bool valid;
 		int nnondeadends, nondeadends[4], deadendtotal;
 		int nequiv, equiv[5];
 		int val = tilestate[(y*w+x) * 4 + i];
@@ -837,7 +838,7 @@
  * Function to randomly perturb an ambiguous section in a grid, to
  * attempt to ensure unique solvability.
  */
-static void perturb(int w, int h, unsigned char *tiles, int wrapping,
+static void perturb(int w, int h, unsigned char *tiles, bool wrapping,
 		    random_state *rs, int startx, int starty, int startd)
 {
     struct xyd *perimeter, *perim2, *loop[2], looppos[2];
@@ -1125,7 +1126,7 @@
     sfree(perimeter);
 }
 
-static int *compute_loops_inner(int w, int h, int wrapping,
+static int *compute_loops_inner(int w, int h, bool wrapping,
                                 const unsigned char *tiles,
                                 const unsigned char *barriers);
 
@@ -1950,7 +1951,7 @@
         return -1;
 }
 
-static int *compute_loops_inner(int w, int h, int wrapping,
+static int *compute_loops_inner(int w, int h, bool wrapping,
                                 const unsigned char *tiles,
                                 const unsigned char *barriers)
 {
@@ -2000,10 +2001,11 @@
     int org_x, org_y; /* origin */
     int cx, cy;       /* source tile (game coordinates) */
     int cur_x, cur_y;
-    int cur_visible;
+    bool cur_visible;
     random_state *rs; /* used for jumbling */
 #ifdef USE_DRAGGING
-    int dragtilex, dragtiley, dragstartx, dragstarty, dragged;
+    int dragtilex, dragtiley, dragstartx, dragstarty;
+    bool dragged;
 #endif
 };
 
@@ -2052,7 +2054,7 @@
 }
 
 struct game_drawstate {
-    int started;
+    bool started;
     int width, height;
     int tilesize;
     unsigned long *visible, *to_draw;
@@ -2067,7 +2069,7 @@
 {
     char *nullret;
     int tx = -1, ty = -1, dir = 0;
-    int shift = button & MOD_SHFT, ctrl = button & MOD_CTRL;
+    bool shift = button & MOD_SHFT, ctrl = button & MOD_CTRL;
     enum {
         NONE, ROTATE_LEFT, ROTATE_180, ROTATE_RIGHT, TOGGLE_LOCK, JUMBLE,
         MOVE_ORIGIN, MOVE_SOURCE, MOVE_ORIGIN_AND_SOURCE, MOVE_CURSOR
@@ -2338,7 +2340,8 @@
 static game_state *execute_move(const game_state *from, const char *move)
 {
     game_state *ret;
-    int tx = -1, ty = -1, n, noanim, orig;
+    int tx = -1, ty = -1, n, orig;
+    bool noanim;
 
     ret = dup_game(from);
 
@@ -2403,7 +2406,7 @@
     {
 	unsigned char *active;
 	int pos;
-	int complete = true;
+        bool complete = true;
 
 	for (pos = 0; pos < ret->width * ret->height; pos++)
             if (ret->tiles[pos] & 0xF)
@@ -2571,7 +2574,7 @@
     float fpoints[12*2];
     int points[12*2];
     int npoints, d, dsh, i;
-    int any_wire_this_colour = false;
+    bool any_wire_this_colour = false;
     float xf, yf;
 
     npoints = 0;
@@ -3005,7 +3008,7 @@
     {
 	char statusbuf[256], *p;
 	int i, n, n2, a;
-        int complete = false;
+        bool complete = false;
 
         p = statusbuf;
         *p = '\0';     /* ensure even an empty status string is terminated */
@@ -3107,7 +3110,7 @@
 }
 
 static void draw_diagram(drawing *dr, game_drawstate *ds, int x, int y,
-			 int topleft, int v, int drawlines, int ink)
+			 bool topleft, int v, bool drawlines, int ink)
 {
     int tx, ty, cx, cy, r, br, k, thick;
 
--- a/netslide.c
+++ b/netslide.c
@@ -77,14 +77,14 @@
 struct game_params {
     int width;
     int height;
-    int wrapping;
+    bool wrapping;
     float barrier_probability;
     int movetarget;
 };
 
 struct game_state {
-    int width, height, cx, cy, wrapping, completed;
-    int used_solve;
+    int width, height, cx, cy, completed;
+    bool wrapping, used_solve;
     int move_count, movetarget;
 
     /* position (row or col number, starting at 0) of last move. */
@@ -218,7 +218,8 @@
         p++;
         ret->height = atoi(p);
         while (*p && isdigit((unsigned char)*p)) p++;
-        if ( (ret->wrapping = (*p == 'w')) != 0 )
+        ret->wrapping = (*p == 'w');
+        if (ret->wrapping)
             p++;
         if (*p == 'b') {
             ret->barrier_probability = (float)atof(++p);
@@ -806,7 +807,7 @@
             for (dir = 1; dir < 0x10; dir <<= 1) {
                 int dir2 = A(dir);
                 int x1, y1, x2, y2, x3, y3;
-                int corner = false;
+                bool corner = false;
 
                 if (!(barrier(state, x, y) & dir))
                     continue;
@@ -967,7 +968,7 @@
 
 struct game_ui {
     int cur_x, cur_y;
-    int cur_visible;
+    bool cur_visible;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1042,7 +1043,7 @@
 }
 
 struct game_drawstate {
-    int started;
+    bool started;
     int width, height;
     int tilesize;
     unsigned char *visible;
@@ -1071,7 +1072,7 @@
             } while (ui->cur_x == state->cx || ui->cur_y == state->cy);
         }
 
-        ui->cur_visible = 1;
+        ui->cur_visible = true;
         return UI_UPDATE;
     }
 
@@ -1078,7 +1079,7 @@
     if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
         cx = (x - (BORDER + WINDOW_OFFSET + TILE_BORDER) + 2*TILE_SIZE) / TILE_SIZE - 2;
         cy = (y - (BORDER + WINDOW_OFFSET + TILE_BORDER) + 2*TILE_SIZE) / TILE_SIZE - 2;
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
     } else if (IS_CURSOR_SELECT(button)) {
         if (ui->cur_visible) {
             cx = ui->cur_x;
@@ -1085,7 +1086,7 @@
             cy = ui->cur_y;
         } else {
             /* 'click' when cursor is invisible just makes cursor visible. */
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
     } else
@@ -1125,7 +1126,8 @@
 static game_state *execute_move(const game_state *from, const char *move)
 {
     game_state *ret;
-    int c, d, col;
+    int c, d;
+    bool col;
 
     if ((move[0] == 'C' || move[0] == 'R') &&
 	sscanf(move+1, "%d,%d", &c, &d) == 2 &&
@@ -1174,7 +1176,7 @@
     if (!ret->completed) {
 	unsigned char *active = compute_active(ret, -1, -1);
 	int x1, y1;
-	int complete = true;
+        bool complete = true;
 
 	for (x1 = 0; x1 < ret->width; x1++)
 	    for (y1 = 0; y1 < ret->height; y1++)
@@ -1530,7 +1532,7 @@
 }
 
 static void draw_arrow(drawing *dr, game_drawstate *ds,
-                       int x, int y, int xdx, int xdy, int cur)
+                       int x, int y, int xdx, int xdy, bool cur)
 {
     int coords[14];
     int ydy = -xdx, ydx = xdy;
@@ -1554,7 +1556,7 @@
 }
 
 static void draw_arrow_for_cursor(drawing *dr, game_drawstate *ds,
-                                  int cur_x, int cur_y, int cur)
+                                  int cur_x, int cur_y, bool cur)
 {
     if (cur_x == -1 && cur_y == -1)
         return; /* 'no cursur here */
@@ -1641,13 +1643,13 @@
          */
         for (x = 0; x < ds->width; x++) {
             if (x == state->cx) continue;
-            draw_arrow(dr, ds, x, 0, +1, 0, 0);
-            draw_arrow(dr, ds, x+1, ds->height, -1, 0, 0);
+            draw_arrow(dr, ds, x, 0, +1, 0, false);
+            draw_arrow(dr, ds, x+1, ds->height, -1, 0, false);
         }
         for (y = 0; y < ds->height; y++) {
             if (y == state->cy) continue;
-            draw_arrow(dr, ds, ds->width, y, 0, +1, 0);
-            draw_arrow(dr, ds, 0, y+1, 0, -1, 0);
+            draw_arrow(dr, ds, ds->width, y, 0, +1, false);
+            draw_arrow(dr, ds, 0, y+1, 0, -1, false);
         }
     }
     if (ui->cur_visible) {
@@ -1657,8 +1659,8 @@
         /* Cursor has changed; redraw two (prev and curr) arrows. */
         assert(cur_x != state->cx && cur_y != state->cy);
 
-        draw_arrow_for_cursor(dr, ds, cur_x, cur_y, 1);
-        draw_arrow_for_cursor(dr, ds, ds->cur_x, ds->cur_y, 0);
+        draw_arrow_for_cursor(dr, ds, cur_x, cur_y, true);
+        draw_arrow_for_cursor(dr, ds, ds->cur_x, ds->cur_y, false);
         ds->cur_x = cur_x; ds->cur_y = cur_y;
     }
 
--- a/obfusc.c
+++ b/obfusc.c
@@ -36,8 +36,8 @@
     char *inhex = NULL;
     unsigned char *data;
     int datalen;
-    int decode = -1;
-    int doing_opts = true;
+    enum { UNKNOWN, DECODE, ENCODE } mode = UNKNOWN;
+    bool doing_opts = true;
 
     while (--argc > 0) {
 	char *p = *++argv;
@@ -51,10 +51,10 @@
 	    while (*p) {
 		switch (*p) {
 		  case 'e':
-		    decode = 0;
+		    mode = ENCODE;
 		    break;
 		  case 'd':
-		    decode = 1;
+		    mode = DECODE;
 		    break;
 		  case 'b':
 		    outputmode = BINARY;
@@ -79,13 +79,13 @@
 	}
     }
 
-    if (decode < 0) {
+    if (mode == UNKNOWN) {
 	fprintf(stderr, "usage: obfusc < -e | -d > [ -b | -h ] [hex data]\n");
 	return 0;
     }
 
     if (outputmode == DEFAULT)
-	outputmode = (decode ? BINARY : HEX);
+	outputmode = (mode == DECODE ? BINARY : HEX);
 
     if (inhex) {
 	datalen = strlen(inhex) / 2;
@@ -111,7 +111,7 @@
 	}
     }
 
-    obfuscate_bitmap(data, datalen * 8, decode);
+    obfuscate_bitmap(data, datalen * 8, mode == DECODE);
 
     if (outputmode == BINARY) {
 	int ret = fwrite(data, 1, datalen, stdout);
--- a/osx.m
+++ b/osx.m
@@ -392,7 +392,7 @@
     MyImageView *view;
     NSColor **colours;
     int ncolours;
-    int clipped;
+    bool clipped;
     int w, h;
 };
 
@@ -522,7 +522,7 @@
     frame.origin.x = 0;
 
     w = h = INT_MAX;
-    midend_size(me, &w, &h, FALSE);
+    midend_size(me, &w, &h, false);
     frame.size.width = w;
     frame.size.height = h;
     fe.w = w;
@@ -557,7 +557,7 @@
      */
     midend_new_game(me);
     w = h = INT_MAX;
-    midend_size(me, &w, &h, FALSE);
+    midend_size(me, &w, &h, false);
     rect.size.width = w;
     rect.size.height = h;
     fe.w = w;
@@ -654,23 +654,23 @@
 	 * function key codes.
 	 */
 	if (c >= 0x80) {
-	    int mods = FALSE;
+	    bool mods = false;
 	    switch (c) {
 	      case NSUpArrowFunctionKey:
 		c = CURSOR_UP;
-		mods = TRUE;
+		mods = true;
 		break;
 	      case NSDownArrowFunctionKey:
 		c = CURSOR_DOWN;
-		mods = TRUE;
+		mods = true;
 		break;
 	      case NSLeftArrowFunctionKey:
 		c = CURSOR_LEFT;
-		mods = TRUE;
+		mods = true;
 		break;
 	      case NSRightArrowFunctionKey:
 		c = CURSOR_RIGHT;
-		mods = TRUE;
+		mods = true;
 		break;
 	      default:
 		continue;
@@ -957,7 +957,7 @@
     int w, h;
 
     w = h = INT_MAX;
-    midend_size(me, &w, &h, FALSE);
+    midend_size(me, &w, &h, false);
     size.width = w;
     size.height = h;
     fe.w = w;
@@ -1275,7 +1275,7 @@
     [self startConfigureSheet:CFG_SETTINGS];
 }
 
-- (void)sheetEndWithStatus:(BOOL)update
+- (void)sheetEndWithStatus:(bool)update
 {
     assert(sheet != NULL);
     [app endSheet:sheet];
@@ -1325,11 +1325,11 @@
 }
 - (void)sheetOKButton:(id)sender
 {
-    [self sheetEndWithStatus:YES];
+    [self sheetEndWithStatus:true];
 }
 - (void)sheetCancelButton:(id)sender
 {
-    [self sheetEndWithStatus:NO];
+    [self sheetEndWithStatus:false];
 }
 
 - (void)setStatusLine:(const char *)text
@@ -1577,7 +1577,7 @@
     if (!fe->clipped)
 	[[NSGraphicsContext currentContext] saveGraphicsState];
     [NSBezierPath clipRect:r];
-    fe->clipped = TRUE;
+    fe->clipped = true;
 }
 static void osx_unclip(void *handle)
 {
@@ -1584,13 +1584,13 @@
     frontend *fe = (frontend *)handle;
     if (fe->clipped)
 	[[NSGraphicsContext currentContext] restoreGraphicsState];
-    fe->clipped = FALSE;
+    fe->clipped = false;
 }
 static void osx_start_draw(void *handle)
 {
     frontend *fe = (frontend *)handle;
     [fe->image lockFocus];
-    fe->clipped = FALSE;
+    fe->clipped = false;
 }
 static void osx_end_draw(void *handle)
 {
--- a/palisade.c
+++ b/palisade.c
@@ -59,8 +59,7 @@
     shared_state *shared;
     borderflag *borders; /* length w*h */
 
-    unsigned int completed: 1;
-    unsigned int cheated: 1;
+    bool completed, cheated;
 };
 
 #define DEFAULT_PRESET 0
@@ -268,7 +267,7 @@
     dsf_merge(ctx->dsf, i, j);
 }
 
-static int connected(solver_ctx *ctx, int i, int j, int dir)
+static bool connected(solver_ctx *ctx, int i, int j, int dir)
 {
     if (j == COMPUTE_J) j = i + dx[dir] + ctx->params->w*dy[dir];
     return dsf_canonify(ctx->dsf, i) == dsf_canonify(ctx->dsf, j);
@@ -281,13 +280,13 @@
     ctx->borders[j] |= BORDER(FLIP(dir));
 }
 
-static int disconnected(solver_ctx *ctx, int i, int j, int dir)
+static bool disconnected(solver_ctx *ctx, int i, int j, int dir)
 {
     assert (j == COMPUTE_J || j == i + dx[dir] + ctx->params->w*dy[dir]);
     return ctx->borders[i] & BORDER(dir);
 }
 
-static int maybe(solver_ctx *ctx, int i, int j, int dir)
+static bool maybe(solver_ctx *ctx, int i, int j, int dir)
 {
     assert (j == COMPUTE_J || j == i + dx[dir] + ctx->params->w*dy[dir]);
     return !disconnected(ctx, i, j, dir) && !connected(ctx, i, j, dir);
@@ -321,10 +320,10 @@
     }
 }
 
-static int solver_number_exhausted(solver_ctx *ctx)
+static bool solver_number_exhausted(solver_ctx *ctx)
 {
     int w = ctx->params->w, h = ctx->params->h, wh = w*h, i, dir, off;
-    int changed = false;
+    bool changed = false;
 
     for (i = 0; i < wh; ++i) {
         if (ctx->clues[i] == EMPTY) continue;
@@ -357,10 +356,10 @@
     return changed;
 }
 
-static int solver_not_too_big(solver_ctx *ctx)
+static bool solver_not_too_big(solver_ctx *ctx)
 {
     int w = ctx->params->w, h = ctx->params->h, wh = w*h, i, dir;
-    int changed = false;
+    bool changed = false;
 
     for (i = 0; i < wh; ++i) {
         int size = dsf_size(ctx->dsf, i);
@@ -376,10 +375,11 @@
     return changed;
 }
 
-static int solver_not_too_small(solver_ctx *ctx)
+static bool solver_not_too_small(solver_ctx *ctx)
 {
     int w = ctx->params->w, h = ctx->params->h, wh = w*h, i, dir;
-    int *outs, k = ctx->params->k, ci, changed = false;
+    int *outs, k = ctx->params->k, ci;
+    bool changed = false;
 
     snewa(outs, wh);
     setmem(outs, -1, wh);
@@ -407,10 +407,10 @@
     return changed;
 }
 
-static int solver_no_dangling_edges(solver_ctx *ctx)
+static bool solver_no_dangling_edges(solver_ctx *ctx)
 {
     int w = ctx->params->w, h = ctx->params->h, r, c;
-    int changed = false;
+    bool changed = false;
 
     /* for each vertex */
     for (r = 1; r < h; ++r)
@@ -458,10 +458,10 @@
     return changed;
 }
 
-static int solver_equivalent_edges(solver_ctx *ctx)
+static bool solver_equivalent_edges(solver_ctx *ctx)
 {
     int w = ctx->params->w, h = ctx->params->h, wh = w*h, i, dirj;
-    int changed = false;
+    bool changed = false;
 
     /* if a square is adjacent to two connected squares, the two
      * borders (i,j) and (i,k) are either both on or both off. */
@@ -505,7 +505,7 @@
 #define UNVISITED 6
 
 /* build connected components in `dsf', along the lines of `borders'. */
-static void dfs_dsf(int i, int w, borderflag *border, int *dsf, int black)
+static void dfs_dsf(int i, int w, borderflag *border, int *dsf, bool black)
 {
     int dir;
     for (dir = 0; dir < 4; ++dir) {
@@ -518,8 +518,8 @@
     }
 }
 
-static int is_solved(const game_params *params, clue *clues,
-                     borderflag *border)
+static bool is_solved(const game_params *params, clue *clues,
+                      borderflag *border)
 {
     int w = params->w, h = params->h, wh = w*h, k = params->k;
     int i, x, y;
@@ -570,9 +570,10 @@
     return false;
 }
 
-static int solver(const game_params *params, clue *clues, borderflag *borders)
+static bool solver(const game_params *params, clue *clues, borderflag *borders)
 {
-    int w = params->w, h = params->h, wh = w*h, changed;
+    int w = params->w, h = params->h, wh = w*h;
+    bool changed;
     solver_ctx ctx;
 
     ctx.params = params;
@@ -865,7 +866,7 @@
 
 struct game_ui {
     int x, y;
-    unsigned int show: 1;
+    bool show;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -916,7 +917,7 @@
                             const game_drawstate *ds, int x, int y, int button)
 {
     int w = state->shared->params.w, h = state->shared->params.h;
-    int control = button & MOD_CTRL, shift = button & MOD_SHFT;
+    bool control = button & MOD_CTRL, shift = button & MOD_SHFT;
 
     button &= ~MOD_MASK;
 
@@ -1281,7 +1282,7 @@
 static bool game_timing_state(const game_state *state, game_ui *ui)
 {
     assert (!"this shouldn't get called");
-    return 0;                          /* placate optimiser */
+    return false;                      /* placate optimiser */
 }
 
 static void game_print_size(const game_params *params, float *x, float *y)
@@ -1295,7 +1296,7 @@
 }
 
 static void print_line(drawing *dr, int x1, int y1, int x2, int y2,
-                       int colour, int full)
+                       int colour, bool full)
 {
     if (!full) {
         int i, subdivisions = 8;
--- a/pattern.c
+++ b/pattern.c
@@ -50,7 +50,7 @@
     int w, h;
     int rowsize;
     int *rowdata, *rowlen;
-    unsigned char *immutable;
+    bool *immutable;
     int refcount;
 } game_state_common;
 
@@ -57,7 +57,7 @@
 struct game_state {
     game_state_common *common;
     unsigned char *grid;
-    int completed, cheated;
+    bool completed, cheated;
 };
 
 #define FLASH_TIME 0.13F
@@ -357,10 +357,10 @@
 #define STILL_UNKNOWN 3
 
 #ifdef STANDALONE_SOLVER
-int verbose = false;
+bool verbose = false;
 #endif
 
-static int do_recurse(unsigned char *known, unsigned char *deduced,
+static bool do_recurse(unsigned char *known, unsigned char *deduced,
                        unsigned char *row,
 		       unsigned char *minpos_done, unsigned char *maxpos_done,
 		       unsigned char *minpos_ok, unsigned char *maxpos_ok,
@@ -424,18 +424,19 @@
 }
 
 
-static int do_row(unsigned char *known, unsigned char *deduced,
-                  unsigned char *row,
-                  unsigned char *minpos_done, unsigned char *maxpos_done,
-		  unsigned char *minpos_ok, unsigned char *maxpos_ok,
-                  unsigned char *start, int len, int step, int *data,
-		  unsigned int *changed
+static bool do_row(unsigned char *known, unsigned char *deduced,
+                   unsigned char *row,
+                   unsigned char *minpos_done, unsigned char *maxpos_done,
+                   unsigned char *minpos_ok, unsigned char *maxpos_ok,
+                   unsigned char *start, int len, int step, int *data,
+                   unsigned int *changed
 #ifdef STANDALONE_SOLVER
-		  , const char *rowcol, int index, int cluewid
+                   , const char *rowcol, int index, int cluewid
 #endif
-		  )
+                   )
 {
-    int rowlen, i, freespace, done_any;
+    int rowlen, i, freespace;
+    bool done_any;
 
     freespace = len+1;
     for (rowlen = 0; data[rowlen]; rowlen++) {
@@ -491,19 +492,20 @@
     return done_any;
 }
 
-static int solve_puzzle(const game_state *state, unsigned char *grid,
-                        int w, int h,
-			unsigned char *matrix, unsigned char *workspace,
-			unsigned int *changed_h, unsigned int *changed_w,
-			int *rowdata
+static bool solve_puzzle(const game_state *state, unsigned char *grid,
+                         int w, int h,
+                         unsigned char *matrix, unsigned char *workspace,
+                         unsigned int *changed_h, unsigned int *changed_w,
+                         int *rowdata
 #ifdef STANDALONE_SOLVER
-			, int cluewid
+                         , int cluewid
 #else
-			, int dummy
+                         , int dummy
 #endif
-			)
+                         )
 {
-    int i, j, ok, max;
+    int i, j, max;
+    bool ok;
     int max_h, max_w;
 
     assert((state!=NULL && state->common->rowdata!=NULL) ^ (grid!=NULL));
@@ -649,7 +651,8 @@
 #ifndef STANDALONE_PICTURE_GENERATOR
 static unsigned char *generate_soluble(random_state *rs, int w, int h)
 {
-    int i, j, ok, ntries, max;
+    int i, j, ntries, max;
+    bool ok;
     unsigned char *grid, *matrix, *workspace;
     unsigned int *changed_h, *changed_w;
     int *rowdata;
@@ -744,8 +747,9 @@
     state->grid = grid;
     state->common = snew(game_state_common);
     state->common->rowdata = NULL;
-    state->common->immutable = snewn(params->w * params->h, unsigned char);
-    memset(state->common->immutable, 1, params->w * params->h);
+    state->common->immutable = snewn(params->w * params->h, bool);
+    for (i = 0; i < params->w * params->h; i++)
+        state->common->immutable[i] = true;
 
     index = snewn(params->w * params->h, int);
     for (i = 0; i < params->w * params->h; i++)
@@ -759,11 +763,11 @@
         unsigned int *changed_w = snewn(max+1, unsigned int);
         int *rowdata = snewn(max+1, int);
         for (i = 0; i < params->w * params->h; i++) {
-            state->common->immutable[index[i]] = 0;
+            state->common->immutable[index[i]] = false;
             if (!solve_puzzle(state, grid, params->w, params->h,
                               matrix, workspace, changed_h, changed_w,
                               rowdata, 0))
-                state->common->immutable[index[i]] = 1;
+                state->common->immutable[index[i]] = true;
         }
         sfree(workspace);
         sfree(changed_h);
@@ -972,8 +976,9 @@
     memset(state->grid, GRID_UNKNOWN, state->common->w * state->common->h);
 
     state->common->immutable = snewn(state->common->w * state->common->h,
-                                     unsigned char);
-    memset(state->common->immutable, 0, state->common->w * state->common->h);
+                                     bool);
+    memset(state->common->immutable, 0,
+           state->common->w * state->common->h * sizeof(bool));
 
     state->common->rowsize = max(state->common->w, state->common->h);
     state->common->rowdata = snewn(state->common->rowsize * (state->common->w + state->common->h), int);
@@ -1003,7 +1008,8 @@
         i = 0;
         while (i < params->w * params->h) {
             int c = (unsigned char)*desc++;
-            int full = isupper(c), len = tolower(c) - 'a';
+            bool full = isupper(c);
+            int len = tolower(c) - 'a';
             i += len;
             if (len < 25 && i < params->w*params->h) {
                 state->grid[i] = full ? GRID_FULL : GRID_EMPTY;
@@ -1051,7 +1057,8 @@
     int w = state->common->w, h = state->common->h;
     int i;
     char *ret;
-    int max, ok;
+    int max;
+    bool ok;
     unsigned char *workspace;
     unsigned int *changed_h, *changed_w;
     int *rowdata;
@@ -1118,7 +1125,8 @@
 	    }
     }
     for (i = 0; i < h; ++i) {
-	int rowlen = 0, predecessors = false;
+	int rowlen = 0;
+        bool predecessors = false;
 	for (j = 0; j < state->common->rowlen[i+w]; ++j) {
 	    int copy = state->common->rowdata[(i+w)*state->common->rowsize + j];
 	    rowlen += predecessors;
@@ -1170,7 +1178,7 @@
 	    int cell = topleft + i*cw + j*ch*lw;
 	    int center = cell + cw/2 + (ch/2)*lw;
 	    int dx, dy;
-	    board[cell] = 0 ? center : '+';
+	    board[cell] = false ? center : '+';
 	    for (dx = 1; dx < cw; ++dx) board[cell + dx] = '-';
 	    for (dy = 1; dy < ch; ++dy) board[cell + dy*lw] = '|';
 	    if (state->grid[i*w+j] == GRID_UNKNOWN) continue;
@@ -1189,13 +1197,14 @@
 }
 
 struct game_ui {
-    int dragging;
+    bool dragging;
     int drag_start_x;
     int drag_start_y;
     int drag_end_x;
     int drag_end_y;
     int drag, release, state;
-    int cur_x, cur_y, cur_visible;
+    int cur_x, cur_y;
+    bool cur_visible;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1204,7 +1213,8 @@
 
     ret = snew(game_ui);
     ret->dragging = false;
-    ret->cur_x = ret->cur_y = ret->cur_visible = 0;
+    ret->cur_x = ret->cur_y = 0;
+    ret->cur_visible = false;
 
     return ret;
 }
@@ -1229,7 +1239,7 @@
 }
 
 struct game_drawstate {
-    int started;
+    bool started;
     int w, h;
     int tilesize;
     unsigned char *visible, *numcolours;
@@ -1240,7 +1250,7 @@
                             const game_drawstate *ds,
                             int x, int y, int button)
 {
-    int control = button & MOD_CTRL, shift = button & MOD_SHFT;
+    bool control = button & MOD_CTRL, shift = button & MOD_SHFT;
     button &= ~MOD_MASK;
 
     x = FROMCOORD(state->common->w, x);
@@ -1279,7 +1289,7 @@
 
         ui->drag_start_x = ui->drag_end_x = x;
         ui->drag_start_y = ui->drag_end_y = y;
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
 
         return UI_UPDATE;
     }
@@ -1315,7 +1325,7 @@
 
     if (ui->dragging && button == ui->release) {
         int x1, x2, y1, y2, xx, yy;
-        int move_needed = false;
+        bool move_needed = false;
 
         x1 = min(ui->drag_start_x, ui->drag_end_x);
         x2 = max(ui->drag_start_x, ui->drag_end_x);
@@ -1344,8 +1354,8 @@
     if (IS_CURSOR_MOVE(button)) {
 	int x = ui->cur_x, y = ui->cur_y, newstate;
 	char buf[80];
-        move_cursor(button, &ui->cur_x, &ui->cur_y, state->common->w, state->common->h, 0);
-        ui->cur_visible = 1;
+        move_cursor(button, &ui->cur_x, &ui->cur_y, state->common->w, state->common->h, false);
+        ui->cur_visible = true;
 	if (!control && !shift) return UI_UPDATE;
 
 	newstate = control ? shift ? GRID_UNKNOWN : GRID_FULL : GRID_EMPTY;
@@ -1365,7 +1375,7 @@
         char buf[80];
 
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
 
@@ -1535,7 +1545,7 @@
     int ncontig;
 };
 
-static int errcheck_found_run(struct errcheck_state *es, int r)
+static bool errcheck_found_run(struct errcheck_state *es, int r)
 {
 /* Macro to handle the pretence that rowdata has a 0 at each end */
 #define ROWDATA(k) ((k)<0 || (k)>=es->rowlen ? 0 : es->rowdata[(k)])
@@ -1566,7 +1576,7 @@
 #undef ROWDATA
 }
 
-static int check_errors(const game_state *state, int i)
+static bool check_errors(const game_state *state, int i)
 {
     int start, step, end, j;
     int val, runlen;
@@ -1689,7 +1699,7 @@
 }
 
 static void grid_square(drawing *dr, game_drawstate *ds,
-                        int y, int x, int state, int cur)
+                        int y, int x, int state, bool cur)
 {
     int xl, xr, yt, yb, dx, dy, dw, dh;
 
@@ -1721,8 +1731,9 @@
 /*
  * Draw the numbers for a single row or column.
  */
-static void draw_numbers(drawing *dr, game_drawstate *ds,
-                         const game_state *state, int i, int erase, int colour)
+static void draw_numbers(
+    drawing *dr, game_drawstate *ds, const game_state *state,
+    int i, bool erase, int colour)
 {
     int rowlen = state->common->rowlen[i];
     int *rowdata = state->common->rowdata + state->common->rowsize * i;
@@ -1788,7 +1799,8 @@
 {
     int i, j;
     int x1, x2, y1, y2;
-    int cx, cy, cmoved;
+    int cx, cy;
+    bool cmoved;
 
     if (!ds->started) {
         /*
@@ -1833,7 +1845,8 @@
      */
     for (i = 0; i < ds->h; i++) {
         for (j = 0; j < ds->w; j++) {
-            int val, cc = 0;
+            int val;
+            bool cc = false;
 
             /*
              * Work out what state this square should be drawn in,
@@ -1848,8 +1861,8 @@
             if (cmoved) {
                 /* the cursor has moved; if we were the old or
                  * the new cursor position we need to redraw. */
-                if (j == cx && i == cy) cc = 1;
-                if (j == ds->cur_x && i == ds->cur_y) cc = 1;
+                if (j == cx && i == cy) cc = true;
+                if (j == ds->cur_x && i == ds->cur_y) cc = true;
             }
 
             /*
--- a/pearl.c
+++ b/pearl.c
@@ -113,7 +113,7 @@
 struct game_params {
     int w, h;
     int difficulty;
-    int nosolve;        /* XXX remove me! */
+    bool nosolve;        /* XXX remove me! */
 };
 
 struct shared_state {
@@ -129,7 +129,7 @@
     char *lines;        /* size w*h: lines placed */
     char *errors;       /* size w*h: errors detected */
     char *marks;        /* size w*h: 'no line here' marks placed. */
-    int completed, used_solve;
+    bool completed, used_solve;
 };
 
 #define DEFAULT_PRESET 3
@@ -283,7 +283,7 @@
  */
 
 int pearl_solve(int w, int h, char *clues, char *result,
-                int difficulty, int partial)
+                int difficulty, bool partial)
 {
     int W = 2*w+1, H = 2*h+1;
     short *workspace;
@@ -347,7 +347,7 @@
      * Now repeatedly try to find something we can do.
      */
     while (1) {
-	int done_something = false;
+	bool done_something = false;
 
 #ifdef SOLVER_DIAGNOSTICS
 	for (y = 0; y < H; y++) {
@@ -900,7 +900,7 @@
     struct pearl_loopgen_bias_ctx_boundary {
         int colour;                    /* FACE_WHITE or FACE_BLACK */
 
-        char *edges;                   /* is each edge part of the loop? */
+        bool *edges;                   /* is each edge part of the loop? */
         tdq *edges_todo;
 
         char *vertextypes;             /* bits 0-3 == outgoing edge bitmap;
@@ -962,8 +962,8 @@
             grid_edge *e = &g->edges[j];
             int fc1 = e->face1 ? board[e->face1 - g->faces] : FACE_BLACK;
             int fc2 = e->face2 ? board[e->face2 - g->faces] : FACE_BLACK;
-            int oldedge = b->edges[j];
-            int newedge = (fc1==c) ^ (fc2==c);
+            bool oldedge = b->edges[j];
+            bool newedge = (fc1==c) ^ (fc2==c);
             if (oldedge != newedge) {
                 b->edges[j] = newedge;
                 tdq_add(b->vertextypes_todo, e->dot1 - g->dots);
@@ -1070,8 +1070,8 @@
     biasctx.score = 0;
     memset(biasctx.faces, FACE_GREY, g->num_faces);
     for (i = 0; i < 2; i++) {
-        biasctx.boundaries[i].edges = snewn(g->num_edges, char);
-        memset(biasctx.boundaries[i].edges, 0, g->num_edges);
+        biasctx.boundaries[i].edges = snewn(g->num_edges, bool);
+        memset(biasctx.boundaries[i].edges, 0, g->num_edges * sizeof(bool));
         biasctx.boundaries[i].edges_todo = tdq_new(g->num_edges);
         tdq_fill(biasctx.boundaries[i].edges_todo);
         biasctx.boundaries[i].vertextypes = snewn(g->num_dots, char);
@@ -1416,7 +1416,8 @@
     game_state *state = snew(game_state);
     int i, j, sz = params->w*params->h;
 
-    state->completed = state->used_solve = false;
+    state->completed = false;
+    state->used_solve = false;
     state->shared = snew(struct shared_state);
 
     state->shared->w = params->w;
@@ -1508,10 +1509,10 @@
     dsf_merge(dsf, ac, bc);
 }
 
-static void check_completion(game_state *state, int mark)
+static void check_completion(game_state *state, bool mark)
 {
     int w = state->shared->w, h = state->shared->h, x, y, i, d;
-    int had_error = false;
+    bool had_error = false;
     int *dsf, *component_state;
     int nsilly, nloop, npath, largest_comp, largest_size, total_pathsize;
     enum { COMP_NONE, COMP_LOOP, COMP_PATH, COMP_SILLY, COMP_EMPTY };
@@ -1808,7 +1809,7 @@
     int clickx, clicky;    /* pixel position of initial click */
 
     int curx, cury;        /* grid position of keyboard cursor */
-    int cursor_active;     /* true iff cursor is shown */
+    bool cursor_active;    /* true iff cursor is shown */
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1882,7 +1883,7 @@
 
 struct game_drawstate {
     int halfsz;
-    int started;
+    bool started;
 
     int w, h, sz;
     unsigned int *lflags;       /* size w*h */
@@ -1963,7 +1964,7 @@
  *
  * Call it in a loop, like this:
  *
- *     int clearing = true;
+ *     bool clearing = true;
  *     for (i = 0; i < ui->ndragcoords - 1; i++) {
  *         int sx, sy, dx, dy, dir, oldstate, newstate;
  *         interpret_ui_drag(state, ui, &clearing, i, &sx, &sy, &dx, &dy,
@@ -1976,7 +1977,7 @@
  *     }
  */
 static void interpret_ui_drag(const game_state *state, const game_ui *ui,
-                              int *clearing, int i, int *sx, int *sy,
+                              bool *clearing, int i, int *sx, int *sy,
                               int *dx, int *dy, int *dir,
                               int *oldstate, int *newstate)
 {
@@ -2008,7 +2009,7 @@
 }
 
 static char *mark_in_direction(const game_state *state, int x, int y, int dir,
-			       int primary, char *buf)
+			       bool primary, char *buf)
 {
     int w = state->shared->w /*, h = state->shared->h, sz = state->shared->sz */;
     int x2 = x + DX(dir);
@@ -2037,10 +2038,10 @@
 {
     int w = state->shared->w, h = state->shared->h /*, sz = state->shared->sz */;
     int gx = FROMCOORD(x), gy = FROMCOORD(y), i;
-    int release = false;
+    bool release = false;
     char tmpbuf[80];
 
-    int shift = button & MOD_SHFT, control = button & MOD_CTRL;
+    bool shift = button & MOD_SHFT, control = button & MOD_CTRL;
     button &= ~MOD_MASK;
 
     if (IS_MOUSE_DOWN(button)) {
@@ -2068,7 +2069,7 @@
     if (IS_CURSOR_MOVE(button)) {
 	if (!ui->cursor_active) {
 	    ui->cursor_active = true;
-	} else if (control | shift) {
+	} else if (control || shift) {
 	    char *move;
 	    if (ui->ndragcoords > 0) return NULL;
 	    ui->ndragcoords = -1;
@@ -2114,7 +2115,7 @@
             int buflen = 0, bufsize = 256, tmplen;
             char *buf = NULL;
             const char *sep = "";
-            int clearing = true;
+            bool clearing = true;
 
             for (i = 0; i < ui->ndragcoords - 1; i++) {
                 int sx, sy, dx, dy, dir, oldstate, newstate;
@@ -2453,7 +2454,8 @@
                         float animtime, float flashtime)
 {
     int w = state->shared->w, h = state->shared->h, sz = state->shared->sz;
-    int x, y, force = 0, flashing = 0;
+    int x, y, flashing = 0;
+    bool force = false;
 
     if (!ds->started) {
         /*
@@ -2478,7 +2480,7 @@
         draw_update(dr, 0, 0, w*TILE_SIZE + 2*BORDER, h*TILE_SIZE + 2*BORDER);
 
         ds->started = true;
-        force = 1;
+        force = true;
     }
 
     if (flashtime > 0 &&
@@ -2488,7 +2490,8 @@
 
     memset(ds->draglines, 0, sz);
     if (ui->ndragcoords > 0) {
-        int i, clearing = true;
+        int i;
+        bool clearing = true;
         for (i = 0; i < ui->ndragcoords - 1; i++) {
             int sx, sy, dx, dy, dir, oldstate, newstate;
             interpret_ui_drag(state, ui, &clearing, i, &sx, &sy, &dx, &dy,
@@ -2739,7 +2742,7 @@
         }
 
         decode_params(p, id);
-        err = validate_params(p, 1);
+        err = validate_params(p, true);
         if (err) {
             fprintf(stderr, "%s: %s", argv[0], err);
             goto done;
--- a/pegs.c
+++ b/pegs.c
@@ -55,7 +55,7 @@
 
 struct game_state {
     int w, h;
-    int completed;
+    bool completed;
     unsigned char *grid;
 };
 
@@ -677,7 +677,7 @@
 
     state->w = w;
     state->h = h;
-    state->completed = 0;
+    state->completed = false;
     state->grid = snewn(w*h, unsigned char);
     for (i = 0; i < w*h; i++)
 	state->grid[i] = (desc[i] == 'P' ? GRID_PEG :
@@ -737,10 +737,11 @@
 }
 
 struct game_ui {
-    int dragging;		       /* boolean: is a drag in progress? */
+    bool dragging;                     /* is a drag in progress? */
     int sx, sy;			       /* grid coords of drag start cell */
     int dx, dy;			       /* pixel coords of current drag posn */
-    int cur_x, cur_y, cur_visible, cur_jumping;
+    int cur_x, cur_y;
+    bool cur_visible, cur_jumping;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -750,7 +751,8 @@
 
     ui->sx = ui->sy = ui->dx = ui->dy = 0;
     ui->dragging = false;
-    ui->cur_visible = ui->cur_jumping = 0;
+    ui->cur_visible = false;
+    ui->cur_jumping = false;
 
     /* make sure we start the cursor somewhere on the grid. */
     for (x = 0; x < state->w; x++) {
@@ -804,10 +806,11 @@
 struct game_drawstate {
     int tilesize;
     blitter *drag_background;
-    int dragging, dragx, dragy;
+    bool dragging;
+    int dragx, dragy;
     int w, h;
     unsigned char *grid;
-    int started;
+    bool started;
     int bgcolour;
 };
 
@@ -843,7 +846,8 @@
 	    ui->sy = ty;
 	    ui->dx = x;
 	    ui->dy = y;
-            ui->cur_visible = ui->cur_jumping = 0;
+            ui->cur_visible = false;
+            ui->cur_jumping = false;
 	    return UI_UPDATE;
 	}
     } else if (button == LEFT_DRAG && ui->dragging) {
@@ -888,8 +892,8 @@
             /* Not jumping; move cursor as usual, making sure we don't
              * leave the gameboard (which may be an irregular shape) */
             int cx = ui->cur_x, cy = ui->cur_y;
-            move_cursor(button, &cx, &cy, w, h, 0);
-            ui->cur_visible = 1;
+            move_cursor(button, &cx, &cy, w, h, false);
+            ui->cur_visible = true;
             if (state->grid[cy*w+cx] == GRID_HOLE ||
                 state->grid[cy*w+cx] == GRID_PEG) {
                 ui->cur_x = cx;
@@ -908,7 +912,7 @@
             mx = ui->cur_x+dx; my = ui->cur_y+dy;
             jx = mx+dx; jy = my+dy;
 
-            ui->cur_jumping = 0; /* reset, whatever. */
+            ui->cur_jumping = false; /* reset, whatever. */
             if (jx >= 0 && jy >= 0 && jx < w && jy < h &&
                 state->grid[my*w+mx] == GRID_PEG &&
                 state->grid[jy*w+jx] == GRID_HOLE) {
@@ -922,16 +926,16 @@
         }
     } else if (IS_CURSOR_SELECT(button)) {
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
         if (ui->cur_jumping) {
-            ui->cur_jumping = 0;
+            ui->cur_jumping = false;
             return UI_UPDATE;
         }
         if (state->grid[ui->cur_y*w+ui->cur_x] == GRID_PEG) {
             /* cursor is on peg: next arrow-move wil jump. */
-            ui->cur_jumping = 1;
+            ui->cur_jumping = true;
             return UI_UPDATE;
         }
         return NULL;
@@ -983,7 +987,7 @@
                 if (ret->grid[i] == GRID_PEG)
                     count++;
             if (count == 1)
-                ret->completed = 1;
+                ret->completed = true;
         }
 
 	return ret;
@@ -1069,16 +1073,17 @@
 static void draw_tile(drawing *dr, game_drawstate *ds,
 		      int x, int y, int v, int bgcolour)
 {
-    int cursor = 0, jumping = 0, bg;
+    bool cursor = false, jumping = false;
+    int bg;
 
     if (bgcolour >= 0) {
 	draw_rect(dr, x, y, TILESIZE, TILESIZE, bgcolour);
     }
     if (v >= GRID_JUMPING) {
-        jumping = 1; v -= GRID_JUMPING;
+        jumping = true; v -= GRID_JUMPING;
     }
     if (v >= GRID_CURSOR) {
-        cursor = 1; v -= GRID_CURSOR;
+        cursor = true; v -= GRID_CURSOR;
     }
 
     if (v == GRID_HOLE) {
--- a/printing.c
+++ b/printing.c
@@ -17,7 +17,7 @@
     int npuzzles;
     struct puzzle *puzzles;
     int puzzlesize;
-    int got_solns;
+    bool got_solns;
     float *colwid, *rowht;
     float userscale;
 };
--- a/ps.c
+++ b/ps.c
@@ -13,9 +13,9 @@
 
 struct psdata {
     FILE *fp;
-    int colour;
+    bool colour;
     int ytop;
-    int clipped;
+    bool clipped;
     float hatchthick, hatchspace;
     int gamewidth, gameheight;
     drawing *drawing;
--- a/range.c
+++ b/range.c
@@ -94,8 +94,7 @@
 
 struct game_state {
     struct game_params params;
-    unsigned int has_cheated: 1;
-    unsigned int was_solved: 1;
+    bool has_cheated, was_solved;
     puzzle_size *grid;
 };
 
@@ -702,7 +701,7 @@
     state.params = *params;
     state.grid = grid;
 
-    interactive = 0; /* I don't need it, I shouldn't use it*/
+    interactive = false; /* I don't need it, I shouldn't use it*/
 
     for (i = 0; i < n; ++i) shuffle_1toN[i] = i;
 
@@ -1221,7 +1220,7 @@
 
 struct game_ui {
     puzzle_size r, c; /* cursor position */
-    unsigned int cursor_show: 1;
+    bool cursor_show;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1248,15 +1247,13 @@
 
 typedef struct drawcell {
     puzzle_size value;
-    unsigned int error: 1;
-    unsigned int cursor: 1;
-    unsigned int flash: 1;
+    bool error, cursor, flash;
 } drawcell;
 
 struct game_drawstate {
     int tilesize;
     drawcell *grid;
-    unsigned int started: 1;
+    bool started;
 };
 
 #define TILESIZE (ds->tilesize)
@@ -1271,8 +1268,8 @@
     enum {none, forwards, backwards, hint};
     int const w = state->params.w, h = state->params.h;
     int r = ui->r, c = ui->c, action = none, cell;
-    int shift = button & MOD_SHFT;
-    button &= ~shift;
+    bool shift = button & MOD_SHFT;
+    button &= ~MOD_SHFT;
 
     if (IS_CURSOR_SELECT(button) && !ui->cursor_show) return NULL;
 
@@ -1331,7 +1328,8 @@
             for (i = 0; i < 4 && cursors[i] != button; ++i);
             assert (i < 4);
             if (shift) {
-                int pre_r = r, pre_c = c, do_pre, do_post;
+                int pre_r = r, pre_c = c;
+                bool do_pre, do_post;
                 cell = state->grid[idx(r, c, state->params.w)];
                 do_pre = (cell == EMPTY);
 
@@ -1407,7 +1405,7 @@
     return NULL;
 }
 
-static int find_errors(const game_state *state, int *report)
+static bool find_errors(const game_state *state, bool *report)
 {
     int const w = state->params.w, h = state->params.h, n = w * h;
     int *dsf;
@@ -1543,7 +1541,7 @@
         ret->grid[idx(r, c, ret->params.w)] = value;
     }
 
-    if (ret->was_solved == false)
+    if (!ret->was_solved)
         ret->was_solved = !find_errors(ret, NULL);
 
     return ret;
@@ -1626,7 +1624,8 @@
     return ret;
 }
 
-static drawcell makecell(puzzle_size value, int error, int cursor, int flash)
+static drawcell makecell(puzzle_size value,
+                         bool error, bool cursor, bool flash)
 {
     drawcell ret;
     setmember(ret, value);
@@ -1660,7 +1659,7 @@
 
 #define cmpmember(a, b, field) ((a) . field == (b) . field)
 
-static int cell_eq(drawcell a, drawcell b)
+static bool cell_eq(drawcell a, drawcell b)
 {
     return
         cmpmember(a, b, value) &&
@@ -1683,8 +1682,8 @@
 
     int r, c, i;
 
-    int *errors = snewn(n, int);
-    memset(errors, false, n * sizeof (int));
+    bool *errors = snewn(n, bool);
+    memset(errors, 0, n * sizeof (bool));
     find_errors(state, errors);
 
     assert (oldstate == NULL); /* only happens if animating moves */
--- a/rect.c
+++ b/rect.c
@@ -44,7 +44,7 @@
 struct game_params {
     int w, h;
     float expandfactor;
-    int unique;
+    bool unique;
 };
 
 #define INDEX(state, x, y)    (((y) * (state)->w) + (x))
@@ -80,7 +80,7 @@
     int *grid;			       /* contains the numbers */
     unsigned char *vedge;	       /* (w+1) x h */
     unsigned char *hedge;	       /* w x (h+1) */
-    int completed, cheated;
+    bool completed, cheated;
     unsigned char *correct;
 };
 
@@ -493,7 +493,7 @@
      * Now run the actual deduction loop.
      */
     while (1) {
-        int done_something = false;
+        bool done_something = false;
 
 #ifdef SOLVER_DIAGNOSTICS
         printf("starting deduction loop\n");
@@ -606,7 +606,7 @@
 
             for (j = 0; j < rectpositions[i].n; j++) {
                 int xx, yy, k;
-                int del = false;
+                bool del = false;
 
                 for (k = 0; k < nrects; k++)
                     workspace[k] = 0;
@@ -1814,7 +1814,8 @@
 	    if (index(state,ret,x,y) == 0xFF) {
 		int rw, rh;
 		int xx, yy;
-		int num, area, valid;
+		int num, area;
+                bool valid;
 
 		/*
 		 * Find a rectangle starting at this point.
@@ -1908,7 +1909,8 @@
     state->grid = snewn(area, int);
     state->vedge = snewn(area, unsigned char);
     state->hedge = snewn(area, unsigned char);
-    state->completed = state->cheated = false;
+    state->completed = false;
+    state->cheated = false;
 
     i = 0;
     while (*desc) {
@@ -2161,12 +2163,12 @@
      * the pointer _returns_ to its starting point the action is
      * treated as a small drag rather than a click.
      */
-    int dragged;
+    bool dragged;
     /* This flag is set if we're doing an erase operation (i.e.
      * removing edges in the centre of the rectangle without altering
      * the outlines).
      */
-    int erasing;
+    bool erasing;
     /*
      * These are the co-ordinates of the top-left and bottom-right squares
      * in the drag box, respectively, or -1 otherwise.
@@ -2179,7 +2181,8 @@
      * These are the coordinates of a cursor, whether it's visible, and
      * whether it was used to start a drag.
      */
-    int cur_x, cur_y, cur_visible, cur_dragging;
+    int cur_x, cur_y;
+    bool cur_visible, cur_dragging;
 };
 
 static void reset_ui(game_ui *ui)
@@ -2200,7 +2203,9 @@
     game_ui *ui = snew(game_ui);
     reset_ui(ui);
     ui->erasing = false;
-    ui->cur_x = ui->cur_y = ui->cur_visible = ui->cur_dragging = 0;
+    ui->cur_x = ui->cur_y = 0;
+    ui->cur_visible = false;
+    ui->cur_dragging = false;
     return ui;
 }
 
@@ -2305,13 +2310,13 @@
 /*
  * Returns true if it has made any change to the grid.
  */
-static int grid_draw_rect(const game_state *state,
+static bool grid_draw_rect(const game_state *state,
 			  unsigned char *hedge, unsigned char *vedge,
-			  int c, int really, int outline,
+			  int c, bool really, bool outline,
 			  int x1, int y1, int x2, int y2)
 {
     int x, y;
-    int changed = false;
+    bool changed = false;
 
     /*
      * Draw horizontal edges of rectangles.
@@ -2350,9 +2355,9 @@
     return changed;
 }
 
-static int ui_draw_rect(const game_state *state, const game_ui *ui,
+static bool ui_draw_rect(const game_state *state, const game_ui *ui,
 			unsigned char *hedge, unsigned char *vedge, int c,
-			int really, int outline)
+			bool really, bool outline)
 {
     return grid_draw_rect(state, hedge, vedge, c, really, outline,
 			  ui->x1, ui->y1, ui->x2, ui->y2);
@@ -2364,7 +2369,7 @@
 }
 
 struct game_drawstate {
-    int started;
+    bool started;
     int w, h, tilesize;
     unsigned long *visible;
 };
@@ -2374,7 +2379,7 @@
                             int x, int y, int button)
 {
     int xc, yc;
-    int startdrag = false, enddrag = false, active = false, erasing = false;
+    bool startdrag = false, enddrag = false, active = false, erasing = false;
     char buf[80], *ret;
 
     button &= ~MOD_MASK;
@@ -2398,7 +2403,7 @@
         enddrag = true;
         erasing = (button == RIGHT_RELEASE);
     } else if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, 0);
+        move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, false);
         ui->cur_visible = true;
         active = true;
         if (!ui->cur_dragging) return UI_UPDATE;
@@ -2586,7 +2591,8 @@
      * if the game has been completed.
      */
     if (!ret->completed) {
-	int x, y, ok;
+	int x, y;
+        bool ok;
 
 	ok = true;
 	for (x = 0; x < ret->w; x++)
--- a/samegame.c
+++ b/samegame.c
@@ -97,7 +97,7 @@
 /* scoresub is 1 or 2 (for (n-1)^2 or (n-2)^2) */
 struct game_params {
     int w, h, ncols, scoresub;
-    int soluble;		       /* choose generation algorithm */
+    bool soluble;                    /* choose generation algorithm */
 };
 
 /* These flags must be unique across all uses; in the game_state,
@@ -132,7 +132,7 @@
     int n;
     int *tiles; /* colour only */
     int score;
-    int complete, impossible;
+    bool complete, impossible;
 };
 
 static game_params *default_params(void)
@@ -317,7 +317,8 @@
     int wh = w*h, tc = nc+1;
     int i, j, k, c, x, y, pos, n;
     int *list, *grid2;
-    int ok, failures = 0;
+    bool ok;
+    int failures = 0;
 
     /*
      * We'll use `list' to track the possible places to put our
@@ -662,7 +663,7 @@
                  */
                 {
                     int x1, x2, y1, y2;
-                    int ok = true;
+                    bool ok = true;
                     int fillstart = -1, ntc = 0;
 
 #ifdef GENERATION_DIAGNOSTICS
@@ -691,7 +692,7 @@
 #endif
 
                     for (x1 = x2 = 0; x2 < w; x2++) {
-                        int usedcol = false;
+                        bool usedcol = false;
 
                         for (y1 = y2 = h-1; y2 >= 0; y2--) {
                             if (grid2[y2*w+x2] == tc) {
@@ -987,7 +988,8 @@
             p++;
         if (*p) p++;                   /* eat comma */
     }
-    state->complete = state->impossible = 0;
+    state->complete = false;
+    state->impossible = false;
     state->score = 0;
 
     return state;
@@ -1049,7 +1051,8 @@
     struct game_params params;
     int *tiles; /* selected-ness only */
     int nselected;
-    int xsel, ysel, displaysel;
+    int xsel, ysel;
+    bool displaysel;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1061,7 +1064,8 @@
     memset(ui->tiles, 0, state->n*sizeof(int));
     ui->nselected = 0;
 
-    ui->xsel = ui->ysel = ui->displaysel = 0;
+    ui->xsel = ui->ysel = 0;
+    ui->displaysel = false;
 
     return ui;
 }
@@ -1102,7 +1106,7 @@
      * control cursor.
      */
     if (newstate->complete || newstate->impossible)
-	ui->displaysel = 0;
+	ui->displaysel = false;
 }
 
 static char *sel_movedesc(game_ui *ui, const game_state *state)
@@ -1192,13 +1196,13 @@
     }
 }
 
-static int sg_emptycol(game_state *ret, int x)
+static bool sg_emptycol(game_state *ret, int x)
 {
     int y;
     for (y = 0; y < ret->params.h; y++) {
-	if (COL(ret,x,y)) return 0;
+	if (COL(ret,x,y)) return false;
     }
-    return 1;
+    return true;
 }
 
 
@@ -1236,20 +1240,21 @@
 
 static void sg_check(game_state *ret)
 {
-    int x,y, complete = 1, impossible = 1;
+    int x,y;
+    bool complete = true, impossible = true;
 
     for (x = 0; x < ret->params.w; x++) {
 	for (y = 0; y < ret->params.h; y++) {
 	    if (COL(ret,x,y) == 0)
 		continue;
-	    complete = 0;
+	    complete = false;
 	    if (x+1 < ret->params.w) {
 		if (COL(ret,x,y) == COL(ret,x+1,y))
-		    impossible = 0;
+		    impossible = false;
 	    }
 	    if (y+1 < ret->params.h) {
 		if (COL(ret,x,y) == COL(ret,x,y+1))
-		    impossible = 0;
+		    impossible = false;
 	    }
 	}
     }
@@ -1258,7 +1263,8 @@
 }
 
 struct game_drawstate {
-    int started, bgcolour;
+    bool started;
+    int bgcolour;
     int tileinner, tilegap;
     int *tiles; /* contains colour and SELECTED. */
 };
@@ -1270,13 +1276,13 @@
     int tx, ty;
     char *ret = UI_UPDATE;
 
-    ui->displaysel = 0;
+    ui->displaysel = false;
 
     if (button == RIGHT_BUTTON || button == LEFT_BUTTON) {
 	tx = FROMCOORD(x); ty= FROMCOORD(y);
     } else if (IS_CURSOR_MOVE(button)) {
 	int dx = 0, dy = 0;
-	ui->displaysel = 1;
+	ui->displaysel = true;
 	dx = (button == CURSOR_LEFT) ? -1 : ((button == CURSOR_RIGHT) ? +1 : 0);
 	dy = (button == CURSOR_DOWN) ? +1 : ((button == CURSOR_UP)    ? -1 : 0);
 	ui->xsel = (ui->xsel + state->params.w + dx) % state->params.w;
@@ -1283,7 +1289,7 @@
 	ui->ysel = (ui->ysel + state->params.h + dy) % state->params.h;
 	return ret;
     } else if (IS_CURSOR_SELECT(button)) {
-	ui->displaysel = 1;
+	ui->displaysel = true;
 	tx = ui->xsel;
 	ty = ui->ysel;
     } else
@@ -1429,7 +1435,7 @@
     struct game_drawstate *ds = snew(struct game_drawstate);
     int i;
 
-    ds->started = 0;
+    ds->started = false;
     ds->tileinner = ds->tilegap = 0;   /* not decided yet */
     ds->tiles = snewn(state->n, int);
     ds->bgcolour = -1;
@@ -1452,7 +1458,7 @@
  */
 
 static void tile_redraw(drawing *dr, game_drawstate *ds,
-			int x, int y, int dright, int dbelow,
+			int x, int y, bool dright, bool dbelow,
                         int tile, int bgcolour)
 {
     int outer = bgcolour, inner = outer, col = tile & TILE_COLMASK;
@@ -1532,7 +1538,7 @@
 	coords[0] = COORD(0) - HIGHLIGHT_WIDTH;
 	draw_polygon(dr, coords, 5, COL_LOWLIGHT, COL_LOWLIGHT);
 
-	ds->started = 1;
+	ds->started = true;
     }
 
     if (flashtime > 0.0) {
@@ -1545,8 +1551,8 @@
 	for (y = 0; y < state->params.h; y++) {
 	    int i = (state->params.w * y) + x;
 	    int col = COL(state,x,y), tile = col;
-	    int dright = (x+1 < state->params.w);
-	    int dbelow = (y+1 < state->params.h);
+	    bool dright = (x+1 < state->params.w);
+	    bool dbelow = (y+1 < state->params.h);
 
 	    tile |= ISSEL(ui,x,y);
 	    if (state->impossible)
--- a/signpost.c
+++ b/signpost.c
@@ -39,7 +39,7 @@
 
 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 @@
 
 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,26 +92,26 @@
     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);
@@ -118,9 +118,10 @@
 }
 
 /* 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,27 +137,27 @@
         /* 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];
 
@@ -163,27 +164,27 @@
     /* 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 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 @@
     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 @@
         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 @@
 {
     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 @@
         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 @@
     }
 }
 
-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 @@
     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 @@
 
     /* 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 @@
 
 /* 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 @@
     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 @@
         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 @@
             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 @@
         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 @@
                 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 @@
             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 @@
     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 @@
                         state->flags[j] |= FLAG_ERROR;
                         state->flags[k] |= FLAG_ERROR;
                     }
-                    error = 1;
+                    error = true;
                 }
             }
         }
@@ -1173,16 +1178,16 @@
 
     /* 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 @@
         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 @@
     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 @@
         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 @@
             ;
         } 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 @@
         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 @@
     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 @@
     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 @@
     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 @@
 
 
 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 @@
     /* 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 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 @@
     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 @@
         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 @@
             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 @@
         }
 
         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 @@
         }
 
         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 @@
 	    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 @@
     }
     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 @@
     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 @@
 
     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 @@
     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 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 @@
                         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 @@
         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 @@
         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 @@
 {
     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 @@
     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 @@
             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);
--- a/singles.c
+++ b/singles.c
@@ -64,7 +64,7 @@
 #include "latin.h"
 
 #ifdef STANDALONE_SOLVER
-int verbose = 0;
+bool verbose = false;
 #endif
 
 #define PREFERRED_TILE_SIZE 32
@@ -99,7 +99,7 @@
 
 struct game_state {
     int w, h, n, o;             /* n = w*h; o = max(w, h) */
-    int completed, used_solve, impossible;
+    bool completed, used_solve, impossible;
     int *nums;                  /* size w*h */
     unsigned int *flags;        /* size w*h */
 };
@@ -277,7 +277,9 @@
     state->n = w*h;
     state->o = max(w,h);
 
-    state->completed = state->used_solve = state->impossible = 0;
+    state->completed = false;
+    state->used_solve = false;
+    state->impossible = false;
 
     state->nums  = snewn(state->n, int);
     state->flags = snewn(state->n, unsigned int);
@@ -359,7 +361,7 @@
     }
 }
 
-static char *generate_desc(game_state *state, int issolve)
+static char *generate_desc(game_state *state, bool issolve)
 {
     char *ret = snewn(state->n+1+(issolve?1:0), char);
     int i, p=0;
@@ -490,7 +492,7 @@
     return nerr;
 }
 
-static int check_complete(game_state *state, unsigned flags)
+static bool check_complete(game_state *state, unsigned flags)
 {
     int *dsf = snewn(state->n, int);
     int x, y, i, error = 0, nwhite, w = state->w, h = state->h;
@@ -557,11 +559,11 @@
     }
 
     sfree(dsf);
-    return (error > 0) ? 0 : 1;
+    return !(error > 0);
 }
 
 static char *game_state_diff(const game_state *src, const game_state *dst,
-                             int issolve)
+                             bool issolve)
 {
     char *ret = NULL, buf[80], c;
     int retlen = 0, x, y, i, k;
@@ -651,7 +653,7 @@
     if (!INGRID(state, x, y)) return;
     if (state->flags[i] & F_BLACK) {
         debug(("... solver wants to add auto-circle on black (%d,%d)\n", x, y));
-        state->impossible = 1;
+        state->impossible = true;
         return;
     }
     /* Only add circle op if it's not already circled. */
@@ -669,7 +671,7 @@
     if (state->nums[i] != num) return;
     if (state->flags[i] & F_CIRCLE) {
         debug(("... solver wants to add auto-black on circled(%d,%d)\n", x, y));
-        state->impossible = 1;
+        state->impossible = true;
         return;
     }
     /* Only add black op if it's not already black. */
@@ -693,7 +695,7 @@
         if (op.op == BLACK) {
             if (state->flags[i] & F_CIRCLE) {
                 debug(("Solver wants to blacken circled square (%d,%d)!\n", op.x, op.y));
-                state->impossible = 1;
+                state->impossible = true;
                 return n_ops;
             }
             if (!(state->flags[i] & F_BLACK)) {
@@ -713,7 +715,7 @@
         } else {
             if (state->flags[i] & F_BLACK) {
                 debug(("Solver wants to circle blackened square (%d,%d)!\n", op.x, op.y));
-                state->impossible = 1;
+                state->impossible = true;
                 return n_ops;
             }
             if (!(state->flags[i] & F_CIRCLE)) {
@@ -845,7 +847,7 @@
                               "CC/CE/QM: white cell with single non-black around it");
             else {
                 debug(("White cell with no escape at (%d,%d)\n", x, y));
-                state->impossible = 1;
+                state->impossible = true;
                 return 0;
             }
 skip: ;
@@ -994,7 +996,8 @@
     return ss->n_ops - n_ops;
 }
 
-static int solve_hassinglewhiteregion(game_state *state, struct solver_state *ss)
+static bool solve_hassinglewhiteregion(
+    game_state *state, struct solver_state *ss)
 {
     int i, j, nwhite = 0, lwhite = -1, szwhite, start, end, next, a, d, x, y;
 
@@ -1007,8 +1010,8 @@
     }
     if (lwhite == -1) {
         debug(("solve_hassinglewhite: no white squares found!\n"));
-        state->impossible = 1;
-        return 0;
+        state->impossible = true;
+        return false;
     }
     /* We don't use connect_dsf here; it's too slow, and there's a quicker
      * algorithm if all we want is the size of one region. */
@@ -1034,13 +1037,14 @@
         start = end; end = next;
     }
     szwhite = next;
-    return (szwhite == nwhite) ? 1 : 0;
+    return (szwhite == nwhite);
 }
 
 static void solve_removesplits_check(game_state *state, struct solver_state *ss,
                                      int x, int y)
 {
-    int i = y*state->w + x, issingle;
+    int i = y*state->w + x;
+    bool issingle;
 
     if (!INGRID(state, x, y)) return;
     if ((state->flags[i] & F_CIRCLE) || (state->flags[i] & F_BLACK))
@@ -1066,7 +1070,7 @@
 
     if (!solve_hassinglewhiteregion(state, ss)) {
         debug(("solve_removesplits: white region is not contiguous at start!\n"));
-        state->impossible = 1;
+        state->impossible = true;
         return 0;
     }
 
@@ -1144,7 +1148,7 @@
     return nunique;
 }
 
-static int solve_specific(game_state *state, int diff, int sneaky)
+static int solve_specific(game_state *state, int diff, bool sneaky)
 {
     struct solver_state *ss = solver_state_new(state);
 
@@ -1186,11 +1190,11 @@
     game_state *solved = dup_game(currstate);
     char *move = NULL;
 
-    if (solve_specific(solved, DIFF_ANY, 0) > 0) goto solved;
+    if (solve_specific(solved, DIFF_ANY, false) > 0) goto solved;
     free_game(solved);
 
     solved = dup_game(state);
-    if (solve_specific(solved, DIFF_ANY, 0) > 0) goto solved;
+    if (solve_specific(solved, DIFF_ANY, false) > 0) goto solved;
     free_game(solved);
 
     *error = "Unable to solve puzzle.";
@@ -1197,7 +1201,7 @@
     return NULL;
 
 solved:
-    move = game_state_diff(currstate, solved, 1);
+    move = game_state_diff(currstate, solved, true);
     free_game(solved);
     return move;
 }
@@ -1216,14 +1220,15 @@
       the solver gets a headstart working out where they are.
  */
 
-static int new_game_is_good(const game_params *params,
-                            game_state *state, game_state *tosolve)
+static bool new_game_is_good(const game_params *params,
+                             game_state *state, game_state *tosolve)
 {
     int sret, sret_easy = 0;
 
     memcpy(tosolve->nums, state->nums, state->n * sizeof(int));
     memset(tosolve->flags, 0, state->n * sizeof(unsigned int));
-    tosolve->completed = tosolve->impossible = 0;
+    tosolve->completed = false;
+    tosolve->impossible = false;
 
     /*
      * We try and solve it twice, once at our requested difficulty level
@@ -1241,13 +1246,14 @@
      */
 
     assert(params->diff < DIFF_MAX);
-    sret = solve_specific(tosolve, params->diff, 0);
+    sret = solve_specific(tosolve, params->diff, false);
     if (params->diff > DIFF_EASY) {
         memset(tosolve->flags, 0, state->n * sizeof(unsigned int));
-        tosolve->completed = tosolve->impossible = 0;
+        tosolve->completed = false;
+        tosolve->impossible = false;
 
-        /* this is the only time the 'sneaky' flag is set to 1. */
-        sret_easy = solve_specific(tosolve, params->diff-1, 1);
+        /* this is the only time the 'sneaky' flag is set. */
+        sret_easy = solve_specific(tosolve, params->diff-1, true);
     }
 
     if (sret <= 0 || sret_easy > 0) {
@@ -1254,9 +1260,9 @@
         debug(("Generated puzzle %s at chosen difficulty %s\n",
                sret <= 0 ? "insoluble" : "too easy",
                singles_diffnames[params->diff]));
-        return 0;
+        return false;
     }
-    return 1;
+    return true;
 }
 
 #define MAXTRIES 20
@@ -1398,7 +1404,7 @@
         goto randomise;
     }
 
-    ret = generate_desc(state, 0);
+    ret = generate_desc(state, false);
 
     free_game(tosolve);
     free_game(state);
@@ -1431,8 +1437,8 @@
 /* --- Game UI and move routines --- */
 
 struct game_ui {
-    int cx, cy, cshow;
-    int show_black_nums;
+    int cx, cy;
+    bool cshow, show_black_nums;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1439,8 +1445,9 @@
 {
     game_ui *ui = snew(game_ui);
 
-    ui->cx = ui->cy = ui->cshow = 0;
-    ui->show_black_nums = 0;
+    ui->cx = ui->cy = 0;
+    ui->cshow = false;
+    ui->show_black_nums = false;
 
     return ui;
 }
@@ -1463,7 +1470,7 @@
                                const game_state *newstate)
 {
     if (!oldstate->completed && newstate->completed)
-        ui->cshow = 0;
+        ui->cshow = false;
 }
 
 #define DS_BLACK        0x1
@@ -1475,7 +1482,8 @@
 #define DS_IMPOSSIBLE   0x40
 
 struct game_drawstate {
-    int tilesize, started, solved;
+    int tilesize;
+    bool started, solved;
     int w, h, n;
 
     unsigned int *flags;
@@ -1490,14 +1498,14 @@
     enum { NONE, TOGGLE_BLACK, TOGGLE_CIRCLE, UI } action = NONE;
 
     if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->cx, &ui->cy, state->w, state->h, 1);
-        ui->cshow = 1;
+        move_cursor(button, &ui->cx, &ui->cy, state->w, state->h, true);
+        ui->cshow = true;
         action = UI;
     } else if (IS_CURSOR_SELECT(button)) {
         x = ui->cx; y = ui->cy;
         if (!ui->cshow) {
             action = UI;
-            ui->cshow = 1;
+            ui->cshow = true;
         }
         if (button == CURSOR_SELECT) {
             action = TOGGLE_BLACK;
@@ -1506,11 +1514,11 @@
         }
     } else if (IS_MOUSE_DOWN(button)) {
         if (ui->cshow) {
-            ui->cshow = 0;
+            ui->cshow = false;
             action = UI;
         }
         if (!INGRID(state, x, y)) {
-            ui->show_black_nums = 1 - ui->show_black_nums;
+            ui->show_black_nums = !ui->show_black_nums;
             action = UI; /* this wants to be a per-game option. */
         } else if (button == LEFT_BUTTON) {
             action = TOGGLE_BLACK;
@@ -1557,7 +1565,7 @@
             move += n;
         } else if (c == 'S') {
             move++;
-            ret->used_solve = 1;
+            ret->used_solve = true;
         } else
             goto badmove;
 
@@ -1566,7 +1574,7 @@
         else if (*move)
             goto badmove;
     }
-    if (check_complete(ret, CC_MARK_ERRORS)) ret->completed = 1;
+    if (check_complete(ret, CC_MARK_ERRORS)) ret->completed = true;
     return ret;
 
 badmove:
@@ -1623,7 +1631,9 @@
 {
     struct game_drawstate *ds = snew(struct game_drawstate);
 
-    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;
@@ -1644,17 +1654,18 @@
 static void tile_redraw(drawing *dr, game_drawstate *ds, int x, int y,
                         int num, unsigned int f)
 {
-    int tcol, bg, dnum, cx, cy, tsz;
+    int tcol, bg, cx, cy, tsz;
+    bool dnum;
     char buf[32];
 
     if (f & DS_BLACK) {
         bg = (f & DS_ERROR) ? COL_ERROR : COL_BLACK;
         tcol = COL_BLACKNUM;
-        dnum = (f & DS_BLACK_NUM) ? 1 : 0;
+        dnum = (f & DS_BLACK_NUM);
     } else {
         bg = (f & DS_FLASH) ? COL_LOWLIGHT : COL_BACKGROUND;
         tcol = (f & DS_ERROR) ? COL_ERROR : COL_BLACK;
-        dnum = 1;
+        dnum = true;
     }
 
     cx = x + TILE_SIZE/2; cy = y + TILE_SIZE/2;
@@ -1729,7 +1740,7 @@
             }
         }
     }
-    ds->started = 1;
+    ds->started = true;
 }
 
 static float game_anim_length(const game_state *oldstate,
@@ -1867,14 +1878,15 @@
 
     while (1) {
         n++;
-        desc = new_game_desc(p, rs, &aux, 0);
+        desc = new_game_desc(p, rs, &aux, false);
         s = new_game(NULL, p, desc);
         nsneaky += solve_sneaky(s, NULL);
 
         for (diff = 0; diff < DIFF_MAX; diff++) {
             memset(s->flags, 0, s->n * sizeof(unsigned int));
-            s->completed = s->impossible = 0;
-            sret = solve_specific(s, diff, 0);
+            s->completed = false;
+            s->impossible = false;
+            sret = solve_specific(s, diff, false);
             if (sret > 0) {
                 ndiff[diff]++;
                 break;
@@ -1911,7 +1923,8 @@
     const char *err;
     game_state *s = NULL;
     game_params *p = NULL;
-    int soln, soak = 0, ret = 1;
+    int soln, ret = 1;
+    bool soak = false;
     time_t seed = time(NULL);
     random_state *rs = NULL;
 
@@ -1920,9 +1933,9 @@
     while (--argc > 0) {
         char *p = *++argv;
         if (!strcmp(p, "-v")) {
-            verbose = 1;
+            verbose = true;
         } else if (!strcmp(p, "--soak")) {
-            soak = 1;
+            soak = true;
         } else if (!strcmp(p, "--seed")) {
             if (argc == 0) {
                 fprintf(stderr, "%s: --seed needs an argument", argv[0]);
@@ -1949,7 +1962,7 @@
 
     p = default_params();
     decode_params(p, id);
-    err = validate_params(p, 1);
+    err = validate_params(p, true);
     if (err) {
         fprintf(stderr, "%s: %s", argv[0], err);
         goto done;
@@ -1962,7 +1975,7 @@
         }
         start_soak(p, rs);
     } else {
-        if (!desc) desc = desc_gen = new_game_desc(p, rs, &aux, 0);
+        if (!desc) desc = desc_gen = new_game_desc(p, rs, &aux, false);
 
         err = validate_desc(p, desc);
         if (err) {
@@ -1978,7 +1991,7 @@
             sfree(tgame);
         }
 
-        soln = solve_specific(s, DIFF_ANY, 0);
+        soln = solve_specific(s, DIFF_ANY, false);
         tgame = game_text_format(s);
         fputs(tgame, stdout);
         sfree(tgame);
--- a/sixteen.c
+++ b/sixteen.c
@@ -47,7 +47,7 @@
     int w, h, n;
     int *tiles;
     int completed;
-    int used_solve;		       /* used to suppress completion flash */
+    bool used_solve;           /* used to suppress completion flash */
     int movecount, movetarget;
     int last_movement_sense;
 };
@@ -196,7 +196,8 @@
 {
     int stop, n, i, x;
     int x1, x2, p1, p2;
-    int *tiles, *used;
+    int *tiles;
+    bool *used;
     char *ret;
     int retlen;
 
@@ -296,7 +297,7 @@
 
     } else {
 
-	used = snewn(n, int);
+	used = snewn(n, bool);
 
 	for (i = 0; i < n; i++) {
 	    tiles[i] = -1;
@@ -400,13 +401,13 @@
 {
     const char *p, *err;
     int i, area;
-    int *used;
+    bool *used;
 
     area = params->w * params->h;
     p = desc;
     err = NULL;
 
-    used = snewn(area, int);
+    used = snewn(area, bool);
     for (i = 0; i < area; i++)
 	used[i] = false;
 
@@ -556,7 +557,7 @@
 
 struct game_ui {
     int cur_x, cur_y;
-    int cur_visible;
+    bool cur_visible;
     enum cursor_mode cur_mode;
 };
 
@@ -591,7 +592,7 @@
 }
 
 struct game_drawstate {
-    int started;
+    bool started;
     int w, h, bgcolour;
     int *tiles;
     int tilesize;
@@ -604,14 +605,14 @@
 {
     int cx = -1, cy = -1, dx, dy;
     char buf[80];
-    int shift = button & MOD_SHFT, control = button & MOD_CTRL,
-        pad = button & MOD_NUM_KEYPAD;
+    bool shift = button & MOD_SHFT, control = button & MOD_CTRL;
+    int pad = button & MOD_NUM_KEYPAD;
 
     button &= ~MOD_MASK;
 
     if (IS_CURSOR_MOVE(button) || pad) {
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
 
@@ -666,7 +667,7 @@
                 ui->cur_y = y - 1;
             }
 
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
     }
@@ -674,7 +675,7 @@
     if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
         cx = FROMCOORD(x);
         cy = FROMCOORD(y);
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
     } else if (IS_CURSOR_SELECT(button)) {
         if (ui->cur_visible) {
             if (ui->cur_x == -1 || ui->cur_x == state->w ||
@@ -688,7 +689,7 @@
                 return UI_UPDATE;
             }
         } else {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
     } else {
@@ -777,7 +778,7 @@
         ret->completed = ret->movecount;
         for (n = 0; n < ret->n; n++)
             if (ret->tiles[n] != n+1)
-                ret->completed = false;
+                ret->completed = 0;
     }
 
     return ret;
@@ -878,7 +879,7 @@
 }
 
 static void draw_arrow(drawing *dr, game_drawstate *ds,
-                       int x, int y, int xdx, int xdy, int cur)
+                       int x, int y, int xdx, int xdy, bool cur)
 {
     int coords[14];
     int ydy = -xdx, ydx = xdy;
@@ -899,7 +900,7 @@
 }
 
 static void draw_arrow_for_cursor(drawing *dr, game_drawstate *ds,
-                                  int cur_x, int cur_y, int cur)
+                                  int cur_x, int cur_y, bool cur)
 {
     if (cur_x == -1 && cur_y == -1)
         return; /* 'no cursur here */
@@ -965,12 +966,12 @@
          * Arrows for making moves.
          */
         for (i = 0; i < state->w; i++) {
-            draw_arrow(dr, ds, COORD(i), COORD(0), +1, 0, 0);
-            draw_arrow(dr, ds, COORD(i+1), COORD(state->h), -1, 0, 0);
+            draw_arrow(dr, ds, COORD(i), COORD(0), +1, 0, false);
+            draw_arrow(dr, ds, COORD(i+1), COORD(state->h), -1, 0, false);
         }
         for (i = 0; i < state->h; i++) {
-            draw_arrow(dr, ds, COORD(state->w), COORD(i), 0, +1, 0);
-            draw_arrow(dr, ds, COORD(0), COORD(i+1), 0, -1, 0);
+            draw_arrow(dr, ds, COORD(state->w), COORD(i), 0, +1, false);
+            draw_arrow(dr, ds, COORD(0), COORD(i+1), 0, -1, false);
         }
 
         ds->started = true;
@@ -984,8 +985,8 @@
 
     if (cur_x != ds->cur_x || cur_y != ds->cur_y) {
         /* Cursor has changed; redraw two (prev and curr) arrows. */
-        draw_arrow_for_cursor(dr, ds, cur_x, cur_y, 1);
-        draw_arrow_for_cursor(dr, ds, ds->cur_x, ds->cur_y, 0);
+        draw_arrow_for_cursor(dr, ds, cur_x, cur_y, true);
+        draw_arrow_for_cursor(dr, ds, ds->cur_x, ds->cur_y, false);
     }
 
     /*
--- a/slant.c
+++ b/slant.c
@@ -51,7 +51,7 @@
  */
 #if defined STANDALONE_SOLVER
 #define SOLVER_DIAGNOSTICS
-int verbose = false;
+bool verbose = false;
 #elif defined SOLVER_DIAGNOSTICS
 #define verbose true
 #endif
@@ -91,8 +91,8 @@
     game_clues *clues;
     signed char *soln;
     unsigned char *errors;
-    int completed;
-    int used_solve;		       /* used to suppress completion flash */
+    bool completed;
+    bool used_solve;           /* used to suppress completion flash */
 };
 
 static game_params *default_params(void)
@@ -253,7 +253,7 @@
      * Tracks whether each connected set of points includes a
      * border point.
      */
-    unsigned char *border;
+    bool *border;
 
     /*
      * Another disjoint set forest. This one tracks _squares_ which
@@ -308,7 +308,7 @@
     struct solver_scratch *ret = snew(struct solver_scratch);
     ret->connected = snewn(W*H, int);
     ret->exits = snewn(W*H, int);
-    ret->border = snewn(W*H, unsigned char);
+    ret->border = snewn(W*H, bool);
     ret->equiv = snewn(w*h, int);
     ret->slashval = snewn(w*h, signed char);
     ret->vbitmap = snewn(w*h, unsigned char);
@@ -333,7 +333,8 @@
 static void merge_vertices(int *connected,
 			   struct solver_scratch *sc, int i, int j)
 {
-    int exits = -1, border = false;    /* initialise to placate optimiser */
+    int exits = -1;
+    bool border = false;    /* initialise to placate optimiser */
 
     if (sc) {
 	i = dsf_canonify(connected, i);
@@ -412,10 +413,10 @@
     }
 }
 
-static int vbitmap_clear(int w, int h, struct solver_scratch *sc,
-                         int x, int y, int vbits, const char *reason, ...)
+static bool vbitmap_clear(int w, int h, struct solver_scratch *sc,
+                          int x, int y, int vbits, const char *reason, ...)
 {
-    int done_something = false;
+    bool done_something = false;
     int vbit;
 
     for (vbit = 1; vbit <= 8; vbit <<= 1)
@@ -452,7 +453,7 @@
 {
     int W = w+1, H = h+1;
     int x, y, i, j;
-    int done_something;
+    bool done_something;
 
     /*
      * Clear the output.
@@ -731,8 +732,8 @@
 	 */
 	for (y = 0; y < h; y++)
 	    for (x = 0; x < w; x++) {
-		int fs, bs, v;
-		int c1, c2;
+		bool fs, bs;
+                int v, c1, c2;
 #ifdef SOLVER_DIAGNOSTICS
 		const char *reason = "<internal error>";
 #endif
@@ -1016,7 +1017,8 @@
      * Fill in each one in turn.
      */
     for (i = 0; i < w*h; i++) {
-	int fs, bs, v;
+	bool fs, bs;
+        int v;
 
 	y = indices[i] / w;
 	x = indices[i] % w;
@@ -1119,7 +1121,8 @@
 	shuffle(clueindices, W*H, sizeof(*clueindices), rs);
 	for (j = 0; j < 2; j++) {
 	    for (i = 0; i < W*H; i++) {
-		int pass, yb, xb;
+		int pass;
+                bool yb, xb;
 
 		y = clueindices[i] / W;
 		x = clueindices[i] % W;
@@ -1319,7 +1322,7 @@
  * squares that contributed to it.
  */
 static int vertex_degree(int w, int h, signed char *soln, int x, int y,
-                         int anti, int *sx, int *sy)
+                         bool anti, int *sx, int *sy)
 {
     int ret = 0;
 
@@ -1376,10 +1379,11 @@
         return -1;
 }
 
-static int check_completion(game_state *state)
+static bool check_completion(game_state *state)
 {
     int w = state->p.w, h = state->p.h, W = w+1, H = h+1;
-    int x, y, err = false;
+    int x, y;
+    bool err = false;
 
     memset(state->errors, 0, W*H);
 
@@ -1461,7 +1465,7 @@
     int w = state->p.w, h = state->p.h;
     signed char *soln;
     int bs, ret;
-    int free_soln = false;
+    bool free_soln = false;
     char *move, buf[80];
     int movelen, movesize;
     int x, y;
@@ -1568,13 +1572,15 @@
 }
 
 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;
 }
 
@@ -1632,7 +1638,7 @@
 
 struct game_drawstate {
     int tilesize;
-    int started;
+    bool started;
     long *grid;
     long *todraw;
 };
@@ -1675,10 +1681,10 @@
         y = FROMCOORD(y);
         if (x < 0 || y < 0 || x >= w || y >= h)
             return NULL;
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
     } else if (IS_CURSOR_SELECT(button)) {
         if (!ui->cur_visible) {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
         x = ui->cur_x;
@@ -1686,8 +1692,8 @@
 
         action = (button == CURSOR_SELECT2) ? ANTICLOCKWISE : CLOCKWISE;
     } else if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, 0);
-        ui->cur_visible = 1;
+        move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, false);
+        ui->cur_visible = true;
         return UI_UPDATE;
     } else if (button == '\\' || button == '\b' || button == '/') {
 	int x = ui->cur_x, y = ui->cur_y;
@@ -1843,7 +1849,7 @@
 }
 
 static void draw_clue(drawing *dr, game_drawstate *ds,
-		      int x, int y, long v, long err, int bg, int colour)
+		      int x, int y, long v, bool err, int bg, int colour)
 {
     char p[2];
     int ccol = colour >= 0 ? colour : ((x ^ y) & 1) ? COL_SLANT1 : COL_SLANT2;
@@ -1959,7 +1965,7 @@
 {
     int w = state->p.w, h = state->p.h, W = w+1, H = h+1;
     int x, y;
-    int flashing;
+    bool flashing;
 
     if (flashtime > 0)
 	flashing = (int)(flashtime * 3 / FLASH_TIME) != 1;
@@ -1989,7 +1995,7 @@
 
     for (y = 0; y < h; y++) {
 	for (x = 0; x < w; x++) {
-            int err = state->errors[y*W+x] & ERR_SQUARE;
+            bool err = state->errors[y*W+x] & ERR_SQUARE;
 
 	    if (state->soln[y*w+x] < 0) {
 		ds->todraw[(y+1)*(w+2)+(x+1)] |= BACKSLASH;
@@ -2192,8 +2198,9 @@
     game_state *s;
     char *id = NULL, *desc;
     const char *err;
-    int grade = false;
-    int ret, diff, really_verbose = false;
+    bool grade = false;
+    int ret, diff;
+    bool really_verbose = false;
     struct solver_scratch *sc;
 
     while (--argc > 0) {
--- a/solo.c
+++ b/solo.c
@@ -210,8 +210,8 @@
      * compositeness - a 7x7 jigsaw sudoku makes perfect sense).
      */
     int c, r, symm, diff, kdiff;
-    int xtype;			       /* require all digits in X-diagonals */
-    int killer;
+    bool xtype;                /* require all digits in X-diagonals */
+    bool killer;
 };
 
 struct block_structure {
@@ -263,11 +263,11 @@
     int cr;
     struct block_structure *blocks;
     struct block_structure *kblocks;   /* Blocks for killer puzzles.  */
-    int xtype, killer;
+    bool xtype, killer;
     digit *grid, *kgrid;
-    unsigned char *pencil;             /* c*r*c*r elements */
-    unsigned char *immutable;	       /* marks which digits are clues */
-    int completed, cheated;
+    bool *pencil;                      /* c*r*c*r elements */
+    bool *immutable;                   /* marks which digits are clues */
+    bool completed, cheated;
 };
 
 static game_params *default_params(void)
@@ -333,7 +333,7 @@
 
 static void decode_params(game_params *ret, char const *string)
 {
-    int seen_r = false;
+    bool seen_r = false;
 
     ret->c = ret->r = atoi(string);
     ret->xtype = false;
@@ -358,7 +358,8 @@
 	    string++;
 	    ret->killer = true;
 	} else if (*string == 'r' || *string == 'm' || *string == 'a') {
-            int sn, sc, sd;
+            int sn, sc;
+            bool sd;
             sc = *string++;
             if (sc == 'm' && *string == 'd') {
                 sd = true;
@@ -714,7 +715,7 @@
      * The way to index this array is cube[(y*cr+x)*cr+n-1]; there
      * are macros below to help with this.
      */
-    unsigned char *cube;
+    bool *cube;
     /*
      * This is the grid in which we write down our final
      * deductions. y-coordinates in here are _not_ transformed.
@@ -731,13 +732,13 @@
      * many times.
      */
     /* row[y*cr+n-1] true if digit n has been placed in row y */
-    unsigned char *row;
+    bool *row;
     /* col[x*cr+n-1] true if digit n has been placed in row x */
-    unsigned char *col;
+    bool *col;
     /* blk[i*cr+n-1] true if digit n has been placed in block i */
-    unsigned char *blk;
+    bool *blk;
     /* diag[i*cr+n-1] true if digit n has been placed in diagonal i */
-    unsigned char *diag;	       /* diag 0 is \, 1 is / */
+    bool *diag;                        /* diag 0 is \, 1 is / */
 
     int *regions;
     int nr_regions;
@@ -968,7 +969,7 @@
             }
 #endif
             ret = +1;		       /* we did something */
-            usage->cube[p] = 0;
+            usage->cube[p] = false;
         }
     }
 
@@ -1005,8 +1006,8 @@
      * any row with a solitary 1 - and discarding that row and the
      * column containing the 1.
      */
-    memset(rowidx, true, cr);
-    memset(colidx, true, cr);
+    memset(rowidx, 1, cr);
+    memset(colidx, 1, cr);
     for (i = 0; i < cr; i++) {
         int count = 0, first = -1;
         for (j = 0; j < cr; j++)
@@ -1033,7 +1034,7 @@
             return -1;
         }
         if (count == 1)
-            rowidx[i] = colidx[first] = false;
+            rowidx[i] = colidx[first] = 0;
     }
 
     /*
@@ -1079,7 +1080,7 @@
              */
             int rows = 0;
             for (i = 0; i < n; i++) {
-                int ok = true;
+                bool ok = true;
                 for (j = 0; j < n; j++)
                     if (set[j] && grid[i*cr+j]) {
                         ok = false;
@@ -1114,7 +1115,7 @@
 	    }
 
             if (rows >= n - count) {
-                int progress = false;
+                bool progress = false;
 
                 /*
                  * We've got one! Now, for each row which _doesn't_
@@ -1128,7 +1129,7 @@
                  * positions in the cube to meddle with.
                  */
                 for (i = 0; i < n; i++) {
-                    int ok = true;
+                    bool ok = true;
                     for (j = 0; j < n; j++)
                         if (set[j] && grid[i*cr+j]) {
                             ok = false;
@@ -1463,7 +1464,7 @@
 
 static int solver_killer_sums(struct solver_usage *usage, int b,
 			      struct block_structure *cages, int clue,
-			      int cage_is_region
+			      bool cage_is_region
 #ifdef STANDALONE_SOLVER
 			      , const char *cage_type
 #endif
@@ -1700,7 +1701,7 @@
 };
 
 static void solver(int cr, struct block_structure *blocks,
-		  struct block_structure *kblocks, int xtype,
+		  struct block_structure *kblocks, bool xtype,
 		  digit *grid, digit *kgrid, struct difficulty *dlev)
 {
     struct solver_usage *usage;
@@ -1725,7 +1726,7 @@
 	usage->kblocks = usage->extra_cages = NULL;
 	usage->extra_clues = NULL;
     }
-    usage->cube = snewn(cr*cr*cr, unsigned char);
+    usage->cube = snewn(cr*cr*cr, bool);
     usage->grid = grid;		       /* write straight back to the input */
     if (kgrid) {
 	int nclues;
@@ -1748,18 +1749,19 @@
 	usage->kclues = NULL;
     }
 
-    memset(usage->cube, true, cr*cr*cr);
+    for (i = 0; i < cr*cr*cr; i++)
+        usage->cube[i] = true;
 
-    usage->row = snewn(cr * cr, unsigned char);
-    usage->col = snewn(cr * cr, unsigned char);
-    usage->blk = snewn(cr * cr, unsigned char);
-    memset(usage->row, false, cr * cr);
-    memset(usage->col, false, cr * cr);
-    memset(usage->blk, false, cr * cr);
+    usage->row = snewn(cr * cr, bool);
+    usage->col = snewn(cr * cr, bool);
+    usage->blk = snewn(cr * cr, bool);
+    memset(usage->row, 0, cr * cr * sizeof(bool));
+    memset(usage->col, 0, cr * cr * sizeof(bool));
+    memset(usage->blk, 0, cr * cr * sizeof(bool));
 
     if (xtype) {
-	usage->diag = snewn(cr * 2, unsigned char);
-	memset(usage->diag, false, cr * 2);
+	usage->diag = snewn(cr * 2, bool);
+	memset(usage->diag, 0, cr * 2 * sizeof(bool));
     } else
 	usage->diag = NULL; 
 
@@ -1840,7 +1842,7 @@
 		}
 
 	if (usage->kclues != NULL) {
-	    int changed = false;
+	    bool changed = false;
 
 	    /*
 	     * First, bring the kblocks into a more useful form: remove
@@ -1907,7 +1909,7 @@
 	    }
 	}
 	if (dlev->maxkdiff >= DIFF_KINTERSECT && usage->kclues != NULL) {
-	    int changed = false;
+	    bool changed = false;
 	    /*
 	     * Now, create the extra_cages information.  Every full region
 	     * (row, column, or block) has the same sum total (45 for 3x3
@@ -1996,7 +1998,7 @@
 	 * implement it for a higher difficulty level.
 	 */
 	if (dlev->maxkdiff >= DIFF_KMINMAX && usage->kclues != NULL) {
-	    int changed = false;
+	    bool changed = false;
 	    for (b = 0; b < usage->kblocks->nr_blocks; b++) {
 		int ret = solver_killer_minmax(usage, usage->kblocks,
 					       usage->kclues, b
@@ -2035,7 +2037,7 @@
 	 * This can only be used if a cage lies entirely within a region.
 	 */
 	if (dlev->maxkdiff >= DIFF_KSUMS && usage->kclues != NULL) {
-	    int changed = false;
+	    bool changed = false;
 
 	    for (b = 0; b < usage->kblocks->nr_blocks; b++) {
 		int ret = solver_killer_sums(usage, b, usage->kblocks,
@@ -2754,10 +2756,11 @@
  * Return values: 1 means solution found, 0 means no solution
  * found on this branch.
  */
-static int gridgen_real(struct gridgen_usage *usage, digit *grid, int *steps)
+static bool gridgen_real(struct gridgen_usage *usage, digit *grid, int *steps)
 {
     int cr = usage->cr;
-    int i, j, n, sx, sy, bestm, bestr, ret;
+    int i, j, n, sx, sy, bestm, bestr;
+    bool ret;
     int *digits;
     unsigned int used;
 
@@ -2877,12 +2880,13 @@
  * Entry point to generator. You give it parameters and a starting
  * grid, which is simply an array of cr*cr digits.
  */
-static int gridgen(int cr, struct block_structure *blocks,
-		   struct block_structure *kblocks, int xtype,
-		   digit *grid, random_state *rs, int maxsteps)
+static bool gridgen(int cr, struct block_structure *blocks,
+                    struct block_structure *kblocks, bool xtype,
+                    digit *grid, random_state *rs, int maxsteps)
 {
     struct gridgen_usage *usage;
-    int x, y, ret;
+    int x, y;
+    bool ret;
 
     /*
      * Clear the grid to start with.
@@ -2905,7 +2909,7 @@
     if (kblocks != NULL) {
 	usage->kblocks = kblocks;
 	usage->cge = snewn(usage->kblocks->nr_blocks, unsigned int);
-	memset(usage->cge, false, kblocks->nr_blocks * sizeof *usage->cge);
+	memset(usage->cge, 0, kblocks->nr_blocks * sizeof *usage->cge);
     } else {
 	usage->cge = NULL;
     }
@@ -3011,20 +3015,20 @@
 /*
  * Check whether a grid contains a valid complete puzzle.
  */
-static int check_valid(int cr, struct block_structure *blocks,
-		       struct block_structure *kblocks,
-                       digit *kgrid, int xtype, digit *grid)
+static bool check_valid(int cr, struct block_structure *blocks,
+                        struct block_structure *kblocks,
+                        digit *kgrid, bool xtype, digit *grid)
 {
-    unsigned char *used;
+    bool *used;
     int x, y, i, j, n;
 
-    used = snewn(cr, unsigned char);
+    used = snewn(cr, bool);
 
     /*
      * Check that each row contains precisely one of everything.
      */
     for (y = 0; y < cr; y++) {
-	memset(used, false, cr);
+	memset(used, 0, cr * sizeof(bool));
 	for (x = 0; x < cr; x++)
 	    if (grid[y*cr+x] > 0 && grid[y*cr+x] <= cr)
 		used[grid[y*cr+x]-1] = true;
@@ -3039,7 +3043,7 @@
      * Check that each column contains precisely one of everything.
      */
     for (x = 0; x < cr; x++) {
-	memset(used, false, cr);
+	memset(used, 0, cr * sizeof(bool));
 	for (y = 0; y < cr; y++)
 	    if (grid[y*cr+x] > 0 && grid[y*cr+x] <= cr)
 		used[grid[y*cr+x]-1] = true;
@@ -3054,7 +3058,7 @@
      * Check that each block contains precisely one of everything.
      */
     for (i = 0; i < cr; i++) {
-	memset(used, false, cr);
+	memset(used, 0, cr * sizeof(bool));
 	for (j = 0; j < cr; j++)
 	    if (grid[blocks->blocks[i][j]] > 0 &&
 		grid[blocks->blocks[i][j]] <= cr)
@@ -3074,7 +3078,7 @@
      */
     if (kblocks) {
 	for (i = 0; i < kblocks->nr_blocks; i++) {
-	    memset(used, false, cr);
+            memset(used, 0, cr * sizeof(bool));
 	    for (j = 0; j < kblocks->nr_squares[i]; j++)
 		if (grid[kblocks->blocks[i][j]] > 0 &&
 		    grid[kblocks->blocks[i][j]] <= cr) {
@@ -3096,7 +3100,7 @@
      * Check that each diagonal contains precisely one of everything.
      */
     if (xtype) {
-	memset(used, false, cr);
+        memset(used, 0, cr * sizeof(bool));
 	for (i = 0; i < cr; i++)
 	    if (grid[diag0(i)] > 0 && grid[diag0(i)] <= cr)
 		used[grid[diag0(i)]-1] = true;
@@ -3106,7 +3110,7 @@
 		return false;
 	    }
 
-	memset(used, false, cr);
+        memset(used, 0, cr * sizeof(bool));
 	for (i = 0; i < cr; i++)
 	    if (grid[diag1(i)] > 0 && grid[diag1(i)] <= cr)
 		used[grid[diag1(i)]-1] = true;
@@ -3273,7 +3277,8 @@
      * etc).
      */
     for (i = 0; i <= 2*cr*(cr-1); i++) {
-	int x, y, p0, p1, edge;
+	int x, y, p0, p1;
+        bool edge;
 
 	if (i == 2*cr*(cr-1)) {
 	    edge = true;       /* terminating virtual edge */
@@ -3430,7 +3435,7 @@
     b->nr_blocks = n1;
 }
 
-static int merge_some_cages(struct block_structure *b, int cr, int area,
+static bool merge_some_cages(struct block_structure *b, int cr, int area,
 			     digit *grid, random_state *rs)
 {
     /*
@@ -3536,7 +3541,7 @@
 }
 
 static struct block_structure *gen_killer_cages(int cr, random_state *rs,
-						int remove_singletons)
+						bool remove_singletons)
 {
     int nr;
     int x, y, area = cr * cr;
@@ -3908,7 +3913,8 @@
     *pdsf = dsf = snew_dsf(area);
 
     while (*desc && *desc != ',') {
-	int c, adv;
+	int c;
+        bool adv;
 
 	if (*desc == '_')
 	    c = 0;
@@ -4132,10 +4138,10 @@
     state->killer = params->killer;
 
     state->grid = snewn(area, digit);
-    state->pencil = snewn(area * cr, unsigned char);
-    memset(state->pencil, 0, area * cr);
-    state->immutable = snewn(area, unsigned char);
-    memset(state->immutable, false, area);
+    state->pencil = snewn(area * cr, bool);
+    memset(state->pencil, 0, area * cr * sizeof(bool));
+    state->immutable = snewn(area, bool);
+    memset(state->immutable, 0, area * sizeof(bool));
 
     state->blocks = alloc_block_structure (c, r, area, cr, cr);
 
@@ -4246,11 +4252,11 @@
     } else
 	ret->kgrid = NULL;
 
-    ret->pencil = snewn(area * cr, unsigned char);
-    memcpy(ret->pencil, state->pencil, area * cr);
+    ret->pencil = snewn(area * cr, bool);
+    memcpy(ret->pencil, state->pencil, area * cr * sizeof(bool));
 
-    ret->immutable = snewn(area, unsigned char);
-    memcpy(ret->immutable, state->immutable, area);
+    ret->immutable = snewn(area, bool);
+    memcpy(ret->immutable, state->immutable, area * sizeof(bool));
 
     ret->completed = state->completed;
     ret->cheated = state->cheated;
@@ -4313,7 +4319,7 @@
 }
 
 static char *grid_text_format(int cr, struct block_structure *blocks,
-			      int xtype, digit *grid)
+			      bool xtype, digit *grid)
 {
     int vmod, hmod;
     int x, y;
@@ -4529,21 +4535,21 @@
      * This indicates whether the current highlight is a
      * pencil-mark one or a real one.
      */
-    int hpencil;
+    bool hpencil;
     /*
      * This indicates whether or not we're showing the highlight
      * (used to be hx = hy = -1); important so that when we're
      * using the cursor keys it doesn't keep coming back at a
-     * fixed position. When hshow = 1, pressing a valid number
+     * fixed position. When hshow is true, pressing a valid number
      * or letter key or Space will enter that number or letter in the grid.
      */
-    int hshow;
+    bool hshow;
     /*
      * This indicates whether we're using the highlight as a cursor;
      * it means that it doesn't vanish on a keypress, and that it is
      * allowed on immutable squares.
      */
-    int hcursor;
+    bool hcursor;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -4551,7 +4557,9 @@
     game_ui *ui = snew(game_ui);
 
     ui->hx = ui->hy = 0;
-    ui->hpencil = ui->hshow = ui->hcursor = 0;
+    ui->hpencil = false;
+    ui->hshow = false;
+    ui->hcursor = false;
 
     return ui;
 }
@@ -4582,13 +4590,13 @@
      */
     if (ui->hshow && ui->hpencil && !ui->hcursor &&
         newstate->grid[ui->hy * cr + ui->hx] != 0) {
-        ui->hshow = 0;
+        ui->hshow = false;
     }
 }
 
 struct game_drawstate {
-    int started;
-    int cr, xtype;
+    bool started, xtype;
+    int cr;
     int tilesize;
     digit *grid;
     unsigned char *pencil;
@@ -4613,17 +4621,17 @@
     if (tx >= 0 && tx < cr && ty >= 0 && ty < cr) {
         if (button == LEFT_BUTTON) {
             if (state->immutable[ty*cr+tx]) {
-                ui->hshow = 0;
+                ui->hshow = false;
             } else if (tx == ui->hx && ty == ui->hy &&
-                       ui->hshow && ui->hpencil == 0) {
-                ui->hshow = 0;
+                       ui->hshow && !ui->hpencil) {
+                ui->hshow = false;
             } else {
                 ui->hx = tx;
                 ui->hy = ty;
-                ui->hshow = 1;
-                ui->hpencil = 0;
+                ui->hshow = true;
+                ui->hpencil = false;
             }
-            ui->hcursor = 0;
+            ui->hcursor = false;
             return UI_UPDATE;
         }
         if (button == RIGHT_BUTTON) {
@@ -4633,29 +4641,30 @@
             if (state->grid[ty*cr+tx] == 0) {
                 if (tx == ui->hx && ty == ui->hy &&
                     ui->hshow && ui->hpencil) {
-                    ui->hshow = 0;
+                    ui->hshow = false;
                 } else {
-                    ui->hpencil = 1;
+                    ui->hpencil = true;
                     ui->hx = tx;
                     ui->hy = ty;
-                    ui->hshow = 1;
+                    ui->hshow = true;
                 }
             } else {
-                ui->hshow = 0;
+                ui->hshow = false;
             }
-            ui->hcursor = 0;
+            ui->hcursor = false;
             return UI_UPDATE;
         }
     }
     if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->hx, &ui->hy, cr, cr, 0);
-        ui->hshow = ui->hcursor = 1;
+        move_cursor(button, &ui->hx, &ui->hy, cr, cr, false);
+        ui->hshow = true;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
     if (ui->hshow &&
         (button == CURSOR_SELECT)) {
-        ui->hpencil = 1 - ui->hpencil;
-        ui->hcursor = 1;
+        ui->hpencil = !ui->hpencil;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
 
@@ -4689,7 +4698,7 @@
 	sprintf(buf, "%c%d,%d,%d",
 		(char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
 
-        if (!ui->hcursor) ui->hshow = 0;
+        if (!ui->hcursor) ui->hshow = false;
 
 	return dupstr(buf);
     }
@@ -4759,7 +4768,9 @@
         for (y = 0; y < cr; y++) {
             for (x = 0; x < cr; x++) {
                 if (!ret->grid[y*cr+x]) {
-                    memset(ret->pencil + (y*cr+x)*cr, 1, cr);
+                    int i;
+                    for (i = 0; i < cr; i++)
+                        ret->pencil[(y*cr+x)*cr + i] = true;
                 }
             }
         }
@@ -4938,7 +4949,8 @@
 	int t = GRIDEXTRA * 3;
 	int kcx, kcy, kcw, kch;
 	int kl, kt, kr, kb;
-	int has_left = 0, has_right = 0, has_top = 0, has_bottom = 0;
+	bool has_left = false, has_right = false;
+        bool has_top = false, has_bottom = false;
 
 	/*
 	 * In non-jigsaw mode, the Killer cages are placed at a
@@ -4971,13 +4983,13 @@
 	 * different areas.
 	 */
 	if (x == 0 || state->kblocks->whichblock[y*cr+x] != state->kblocks->whichblock[y*cr+x-1])
-	    has_left = 1, kl += t;
+	    has_left = true, kl += t;
 	if (x+1 >= cr || state->kblocks->whichblock[y*cr+x] != state->kblocks->whichblock[y*cr+x+1])
-	    has_right = 1, kr -= t;
+	    has_right = true, kr -= t;
 	if (y == 0 || state->kblocks->whichblock[y*cr+x] != state->kblocks->whichblock[(y-1)*cr+x])
-	    has_top = 1, kt += t;
+	    has_top = true, kt += t;
 	if (y+1 >= cr || state->kblocks->whichblock[y*cr+x] != state->kblocks->whichblock[(y+1)*cr+x])
-	    has_bottom = 1, kb -= t;
+	    has_bottom = true, kb -= t;
 	if (has_top)
 	    draw_line(dr, kl, kt, kr, kt, col_killer);
 	if (has_bottom)
@@ -5625,7 +5637,7 @@
     game_state *s;
     char *id = NULL, *desc;
     const char *err;
-    int grade = false;
+    bool grade = false;
     struct difficulty dlev;
 
     while (--argc > 0) {
--- a/tdq.c
+++ b/tdq.c
@@ -30,7 +30,7 @@
     int n;
     int *queue;
     int ip, op;                        /* in pointer, out pointer */
-    char *flags;
+    bool *flags;
 };
 
 tdq *tdq_new(int n)
@@ -38,10 +38,10 @@
     int i;
     tdq *tdq = snew(struct tdq);
     tdq->queue = snewn(n, int);
-    tdq->flags = snewn(n, char);
+    tdq->flags = snewn(n, bool);
     for (i = 0; i < n; i++) {
         tdq->queue[i] = 0;
-        tdq->flags[i] = 0;
+        tdq->flags[i] = false;
     }
     tdq->n = n;
     tdq->ip = tdq->op = 0;
@@ -60,7 +60,7 @@
     assert((unsigned)k < (unsigned)tdq->n);
     if (!tdq->flags[k]) {
         tdq->queue[tdq->ip] = k;
-        tdq->flags[k] = 1;
+        tdq->flags[k] = true;
         if (++tdq->ip == tdq->n)
             tdq->ip = 0;
     }
@@ -73,7 +73,7 @@
     if (!tdq->flags[ret])
         return -1;
 
-    tdq->flags[ret] = 0;
+    tdq->flags[ret] = false;
     if (++tdq->op == tdq->n)
         tdq->op = 0;
 
--- a/tents.c
+++ b/tents.c
@@ -229,7 +229,7 @@
  */
 #if defined STANDALONE_SOLVER
 #define SOLVER_DIAGNOSTICS
-int verbose = false;
+bool verbose = false;
 #elif defined SOLVER_DIAGNOSTICS
 #define verbose true
 #endif
@@ -279,7 +279,7 @@
     game_params p;
     char *grid;
     struct numbers *numbers;
-    int completed, used_solve;
+    bool completed, used_solve;
 };
 
 static game_params *default_params(void)
@@ -471,7 +471,7 @@
      * Main solver loop.
      */
     while (1) {
-	int done_something = false;
+	bool done_something = false;
 
 	/*
 	 * Any tent which has only one unattached tree adjacent to
@@ -528,7 +528,7 @@
 	for (y = 0; y < h; y++)
 	    for (x = 0; x < w; x++)
 		if (soln[y*w+x] == BLANK) {
-		    int can_be_tent = false;
+		    bool can_be_tent = false;
 
 		    for (d = 1; d < MAXDIR; d++) {
 			int x2 = x + dx(d), y2 = y + dy(d);
@@ -559,7 +559,8 @@
 	for (y = 0; y < h; y++)
 	    for (x = 0; x < w; x++)
 		if (soln[y*w+x] == BLANK) {
-		    int dx, dy, imposs = false;
+		    int dx, dy;
+                    bool imposs = false;
 
 		    for (dy = -1; dy <= +1; dy++)
 			for (dx = -1; dx <= +1; dx++)
@@ -751,7 +752,8 @@
 	     * And iterate over all possibilities.
 	     */
 	    while (1) {
-		int p, valid;
+		int p;
+                bool valid;
 
 		/*
 		 * See if this possibility is valid. The only way
@@ -993,7 +995,8 @@
          * is too few to fit the remaining tents into. */
 	for (i = 0; j > 0 && i+j <= w*h; i++) {
             int which, x, y, d, tmp;
-	    int dy, dx, ok = true;
+	    int dy, dx;
+            bool ok = true;
 
             which = i + random_upto(rs, j);
             tmp = order[which];
@@ -1141,7 +1144,7 @@
     p = ret;
     j = 0;
     for (i = 0; i <= w*h; i++) {
-	int c = (i < w*h ? grid[i] == TREE : 1);
+	bool c = (i < w*h ? grid[i] == TREE : true);
 	if (c) {
 	    *p++ = (j == 0 ? '_' : j-1 + 'a');
 	    j = 0;
@@ -1419,9 +1422,10 @@
     int dsx, dsy;                      /* coords of drag start */
     int dex, dey;                      /* coords of drag end */
     int drag_button;                   /* -1 for none, or a button code */
-    int drag_ok;                       /* dragged off the window, to cancel */
+    bool drag_ok;                      /* dragged off the window, to cancel */
 
-    int cx, cy, cdisp;                 /* cursor position, and ?display. */
+    int cx, cy;                        /* cursor position. */
+    bool cdisp;                        /* is cursor displayed? */
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1431,7 +1435,8 @@
     ui->dex = ui->dey = -1;
     ui->drag_button = -1;
     ui->drag_ok = false;
-    ui->cx = ui->cy = ui->cdisp = 0;
+    ui->cx = ui->cy = 0;
+    ui->cdisp = false;
     return ui;
 }
 
@@ -1456,7 +1461,7 @@
 
 struct game_drawstate {
     int tilesize;
-    int started;
+    bool started;
     game_params p;
     int *drawn, *numbersdrawn;
     int cx, cy;         /* last-drawn cursor pos, or (-1,-1) if absent. */
@@ -1539,7 +1544,7 @@
 {
     int w = state->p.w, h = state->p.h;
     char tmpbuf[80];
-    int shift = button & MOD_SHFT, control = button & MOD_CTRL;
+    bool shift = button & MOD_SHFT, control = button & MOD_CTRL;
 
     button &= ~MOD_MASK;
 
@@ -1553,7 +1558,7 @@
         ui->dsx = ui->dex = x;
         ui->dsy = ui->dey = y;
         ui->drag_ok = true;
-        ui->cdisp = 0;
+        ui->cdisp = false;
         return UI_UPDATE;
     }
 
@@ -1639,11 +1644,11 @@
     }
 
     if (IS_CURSOR_MOVE(button)) {
-        ui->cdisp = 1;
+        ui->cdisp = true;
         if (shift || control) {
             int len = 0, i, indices[2];
             indices[0] = ui->cx + w * ui->cy;
-            move_cursor(button, &ui->cx, &ui->cy, w, h, 0);
+            move_cursor(button, &ui->cx, &ui->cy, w, h, false);
             indices[1] = ui->cx + w * ui->cy;
 
             /* NONTENTify all unique traversed eligible squares */
@@ -1658,7 +1663,7 @@
             tmpbuf[len] = '\0';
             if (len) return dupstr(tmpbuf);
         } else
-            move_cursor(button, &ui->cx, &ui->cy, w, h, 0);
+            move_cursor(button, &ui->cx, &ui->cy, w, h, false);
         return UI_UPDATE;
     }
     if (ui->cdisp) {
@@ -1685,7 +1690,7 @@
             return dupstr(tmpbuf);
         }
     } else if (IS_CURSOR_SELECT(button)) {
-        ui->cdisp = 1;
+        ui->cdisp = true;
         return UI_UPDATE;
     }
 
@@ -2302,7 +2307,7 @@
 }
 
 static void draw_tile(drawing *dr, game_drawstate *ds,
-                      int x, int y, int v, int cur, int printing)
+                      int x, int y, int v, bool cur, bool printing)
 {
     int err;
     int tx = COORD(x), ty = COORD(y);
@@ -2390,18 +2395,19 @@
 static void int_redraw(drawing *dr, game_drawstate *ds,
                        const game_state *oldstate, const game_state *state,
                        int dir, const game_ui *ui,
-		       float animtime, float flashtime, int printing)
+		       float animtime, float flashtime, bool printing)
 {
     int w = state->p.w, h = state->p.h;
-    int x, y, flashing;
+    int x, y;
+    bool flashing;
     int cx = -1, cy = -1;
-    int cmoved = 0;
+    bool cmoved = false;
     char *tmpgrid;
     int *errors;
 
     if (ui) {
       if (ui->cdisp) { cx = ui->cx; cy = ui->cy; }
-      if (cx != ds->cx || cy != ds->cy) cmoved = 1;
+      if (cx != ds->cx || cy != ds->cy) cmoved = true;
     }
 
     if (printing || !ds->started) {
@@ -2454,7 +2460,7 @@
     for (y = 0; y < h; y++) {
         for (x = 0; x < w; x++) {
             int v = state->grid[y*w+x];
-            int credraw = 0;
+            bool credraw = false;
 
             /*
              * We deliberately do not take drag_ok into account
@@ -2470,7 +2476,7 @@
 
             if (cmoved) {
               if ((x == cx && y == cy) ||
-                  (x == ds->cx && y == ds->cy)) credraw = 1;
+                  (x == ds->cx && y == ds->cy)) credraw = true;
             }
 
 	    v |= errors[y*w+x];
@@ -2641,8 +2647,9 @@
     game_state *s, *s2;
     char *id = NULL, *desc;
     const char *err;
-    int grade = false;
-    int ret, diff, really_verbose = false;
+    bool grade = false;
+    int ret, diff;
+    bool really_verbose = false;
     struct solver_scratch *sc;
 
     while (--argc > 0) {
--- a/towers.c
+++ b/towers.c
@@ -114,10 +114,10 @@
 struct game_state {
     game_params par;
     struct clues *clues;
-    unsigned char *clues_done;
+    bool *clues_done;
     digit *grid;
     int *pencil;		       /* bitmaps using bits 1<<1..1<<n */
-    int completed, cheated;
+    bool completed, cheated;
 };
 
 static game_params *default_params(void)
@@ -250,7 +250,7 @@
 
 struct solver_ctx {
     int w, diff;
-    int started;
+    bool started;
     int *clues;
     long *iscratch;
     int *dscratch;
@@ -898,7 +898,7 @@
     state->clues->clues = snewn(4*w, int);
     state->clues->immutable = snewn(a, digit);
     state->grid = snewn(a, digit);
-    state->clues_done = snewn(4*w, unsigned char);
+    state->clues_done = snewn(4*w, bool);
     state->pencil = snewn(a, int);
 
     for (i = 0; i < a; i++) {
@@ -907,7 +907,7 @@
     }
 
     memset(state->clues->immutable, 0, a);
-    memset(state->clues_done, 0, 4*w*sizeof(unsigned char));
+    memset(state->clues_done, 0, 4*w*sizeof(bool));
 
     for (i = 0; i < 4*w; i++) {
 	if (i > 0) {
@@ -944,7 +944,8 @@
     }
     assert(!*p);
 
-    state->completed = state->cheated = false;
+    state->completed = false;
+    state->cheated = false;
 
     return state;
 }
@@ -961,10 +962,10 @@
 
     ret->grid = snewn(a, digit);
     ret->pencil = snewn(a, int);
-    ret->clues_done = snewn(4*w, unsigned char);
+    ret->clues_done = snewn(4*w, bool);
     memcpy(ret->grid, state->grid, a*sizeof(digit));
     memcpy(ret->pencil, state->pencil, a*sizeof(int));
-    memcpy(ret->clues_done, state->clues_done, 4*w*sizeof(unsigned char));
+    memcpy(ret->clues_done, state->clues_done, 4*w*sizeof(bool));
 
     ret->completed = state->completed;
     ret->cheated = state->cheated;
@@ -1106,7 +1107,7 @@
      * This indicates whether the current highlight is a
      * pencil-mark one or a real one.
      */
-    int hpencil;
+    bool hpencil;
     /*
      * This indicates whether or not we're showing the highlight
      * (used to be hx = hy = -1); important so that when we're
@@ -1114,13 +1115,13 @@
      * fixed position. When hshow = 1, pressing a valid number
      * or letter key or Space will enter that number or letter in the grid.
      */
-    int hshow;
+    bool hshow;
     /*
      * This indicates whether we're using the highlight as a cursor;
      * it means that it doesn't vanish on a keypress, and that it is
      * allowed on immutable squares.
      */
-    int hcursor;
+    bool hcursor;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1128,7 +1129,9 @@
     game_ui *ui = snew(game_ui);
 
     ui->hx = ui->hy = 0;
-    ui->hpencil = ui->hshow = ui->hcursor = 0;
+    ui->hpencil = false;
+    ui->hshow = false;
+    ui->hcursor = false;
 
     return ui;
 }
@@ -1159,7 +1162,7 @@
      */
     if (ui->hshow && ui->hpencil && !ui->hcursor &&
         newstate->grid[ui->hy * w + ui->hx] != 0) {
-        ui->hshow = 0;
+        ui->hshow = false;
     }
 }
 
@@ -1186,20 +1189,21 @@
 
 struct game_drawstate {
     int tilesize;
-    int three_d;		/* default 3D graphics are user-disableable */
-    int started;
+    bool three_d;       /* default 3D graphics are user-disableable */
+    bool started;
     long *tiles;		       /* (w+2)*(w+2) temp space */
     long *drawn;		       /* (w+2)*(w+2)*4: current drawn data */
-    int *errtmp;
+    bool *errtmp;
 };
 
-static int check_errors(const game_state *state, int *errors)
+static bool check_errors(const game_state *state, bool *errors)
 {
     int w = state->par.w /*, a = w*w */;
     int W = w+2, A = W*W;	       /* the errors array is (w+2) square */
     int *clues = state->clues->clues;
     digit *grid = state->grid;
-    int i, x, y, errs = false;
+    int i, x, y;
+    bool errs = false;
     int tmp[32];
 
     assert(w < lenof(tmp));
@@ -1206,7 +1210,7 @@
 
     if (errors)
 	for (i = 0; i < A; i++)
-	    errors[i] = 0;
+	    errors[i] = false;
 
     for (y = 0; y < w; y++) {
 	unsigned long mask = 0, errmask = 0;
@@ -1290,7 +1294,7 @@
     return -1;
 }
 
-static int is_clue(const game_state *state, int x, int y)
+static bool is_clue(const game_state *state, int x, int y)
 {
     int w = state->par.w;
 
@@ -1309,7 +1313,7 @@
                             int x, int y, int button)
 {
     int w = state->par.w;
-    int shift_or_control = button & (MOD_SHFT | MOD_CTRL);
+    bool shift_or_control = button & (MOD_SHFT | MOD_CTRL);
     int tx, ty;
     char buf[80];
 
@@ -1356,15 +1360,15 @@
     if (tx >= 0 && tx < w && ty >= 0 && ty < w) {
         if (button == LEFT_BUTTON) {
 	    if (tx == ui->hx && ty == ui->hy &&
-		ui->hshow && ui->hpencil == 0) {
-                ui->hshow = 0;
+		ui->hshow && !ui->hpencil) {
+                ui->hshow = false;
             } else {
                 ui->hx = tx;
                 ui->hy = ty;
 		ui->hshow = !state->clues->immutable[ty*w+tx];
-                ui->hpencil = 0;
+                ui->hpencil = false;
             }
-            ui->hcursor = 0;
+            ui->hcursor = false;
             return UI_UPDATE;
         }
         if (button == RIGHT_BUTTON) {
@@ -1374,17 +1378,17 @@
             if (state->grid[ty*w+tx] == 0) {
                 if (tx == ui->hx && ty == ui->hy &&
                     ui->hshow && ui->hpencil) {
-                    ui->hshow = 0;
+                    ui->hshow = false;
                 } else {
-                    ui->hpencil = 1;
+                    ui->hpencil = true;
                     ui->hx = tx;
                     ui->hy = ty;
-                    ui->hshow = 1;
+                    ui->hshow = true;
                 }
             } else {
-                ui->hshow = 0;
+                ui->hshow = false;
             }
-            ui->hcursor = 0;
+            ui->hcursor = false;
             return UI_UPDATE;
         }
     } else if (button == LEFT_BUTTON) {
@@ -1408,14 +1412,15 @@
             }
             return NULL;
         }
-        move_cursor(button, &ui->hx, &ui->hy, w, w, 0);
-        ui->hshow = ui->hcursor = 1;
+        move_cursor(button, &ui->hx, &ui->hy, w, w, false);
+        ui->hshow = true;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
     if (ui->hshow &&
         (button == CURSOR_SELECT)) {
-        ui->hpencil = 1 - ui->hpencil;
-        ui->hcursor = 1;
+        ui->hpencil = !ui->hpencil;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
 
@@ -1442,7 +1447,7 @@
 	sprintf(buf, "%c%d,%d,%d",
 		(char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
 
-        if (!ui->hcursor) ui->hshow = 0;
+        if (!ui->hcursor) ui->hshow = false;
 
 	return dupstr(buf);
     }
@@ -1583,7 +1588,7 @@
     ds->drawn = snewn((w+2)*(w+2)*4, long);
     for (i = 0; i < (w+2)*(w+2)*4; i++)
 	ds->drawn[i] = -1;
-    ds->errtmp = snewn((w+2)*(w+2), int);
+    ds->errtmp = snewn((w+2)*(w+2), bool);
 
     return ds;
 }
@@ -2040,8 +2045,9 @@
     game_state *s;
     char *id = NULL, *desc;
     const char *err;
-    int grade = false;
-    int ret, diff, really_show_working = false;
+    bool grade = false;
+    int ret, diff;
+    bool really_show_working = false;
 
     while (--argc > 0) {
         char *p = *++argv;
@@ -2084,7 +2090,7 @@
      * the puzzle internally before doing anything else.
      */
     ret = -1;			       /* placate optimiser */
-    solver_show_working = false;
+    solver_show_working = 0;
     for (diff = 0; diff < DIFFCOUNT; diff++) {
 	memcpy(s->grid, s->clues->immutable, p->w * p->w);
 	ret = solver(p->w, s->clues->clues, s->grid, diff);
--- a/tracks.c
+++ b/tracks.c
@@ -43,7 +43,8 @@
 #define DIFFCONFIG DIFFLIST(CONFIG)
 
 struct game_params {
-    int w, h, diff, single_ones;
+    int w, h, diff;
+    bool single_ones;
 };
 
 static game_params *default_params(void)
@@ -258,7 +259,7 @@
     unsigned int *sflags;       /* size w*h */
     struct numbers *numbers;
     int *num_errors;            /* size w+h */
-    int completed, used_solve, impossible;
+    bool completed, used_solve, impossible;
 };
 
 /* Return the four directions in which a particular edge flag is set, around a square. */
@@ -280,13 +281,13 @@
     return (t ? E_TRACK : 0) | (nt ? E_NOTRACK : 0);
 }
 
-int S_E_ADJ(const game_state *state, int sx, int sy, int d, int *ax, int *ay, unsigned int *ad) {
-    if (d == L && sx > 0)            { *ax = sx-1; *ay = sy;   *ad = R; return 1; }
-    if (d == R && sx < state->p.w-1) { *ax = sx+1; *ay = sy;   *ad = L; return 1; }
-    if (d == U && sy > 0)            { *ax = sx;   *ay = sy-1; *ad = D; return 1; }
-    if (d == D && sy < state->p.h-1) { *ax = sx;   *ay = sy+1; *ad = U; return 1; }
+bool S_E_ADJ(const game_state *state, int sx, int sy, int d, int *ax, int *ay, unsigned int *ad) {
+    if (d == L && sx > 0)            { *ax = sx-1; *ay = sy;   *ad = R; return true; }
+    if (d == R && sx < state->p.w-1) { *ax = sx+1; *ay = sy;   *ad = L; return true; }
+    if (d == U && sy > 0)            { *ax = sx;   *ay = sy-1; *ad = D; return true; }
+    if (d == D && sy < state->p.h-1) { *ax = sx;   *ay = sy+1; *ad = U; return true; }
 
-    return 0;
+    return false;
 }
 
 /* Sets flag (E_TRACK or E_NOTRACK) on a given edge of a square. */
@@ -416,7 +417,7 @@
     return 0; /* no possible directions left. */
 }
 
-static int check_completion(game_state *state, int mark);
+static bool check_completion(game_state *state, bool mark);
 
 static void lay_path(game_state *state, random_state *rs)
 {
@@ -544,7 +545,7 @@
     return progress;
 }
 
-static int check_phantom_moves(const game_state *state) {
+static bool check_phantom_moves(const game_state *state) {
     int x, y, i;
 
     /* Check that this state won't show 'phantom moves' at the start of the
@@ -557,10 +558,10 @@
             if (state->sflags[i] & S_CLUE)
                 continue;
             if (S_E_COUNT(state, x, y, E_TRACK) > 1)
-                return 1; /* found one! */
+                return true; /* found one! */
         }
     }
-    return 0;
+    return false;
 }
 
 static int add_clues(game_state *state, random_state *rs, int diff)
@@ -734,7 +735,7 @@
     }
 
     if (params->single_ones) {
-        int last_was_one = 1, is_one; /* (disallow 1 clue at entry point) */
+        bool last_was_one = true, is_one; /* disallow 1 clue at entry point */
         for (i = 0; i < w+h; i++) {
             is_one = (state->numbers->numbers[i] == 1);
             if (is_one && last_was_one)
@@ -1173,7 +1174,8 @@
 static int solve_check_loop_sub(game_state *state, int x, int y, int dir,
                                 int *dsf, int startc, int endc)
 {
-    int w = state->p.w, h = state->p.h, i = y*w+x, j, k, satisfied = 1;
+    int w = state->p.w, h = state->p.h, i = y*w+x, j, k;
+    bool satisfied = true;
 
     j = (y+DY(dir))*w + (x+DX(dir));
 
@@ -1203,12 +1205,12 @@
             for (k = 0; k < w; k++) {
                 int target = state->numbers->numbers[k];
                 int ntracks = solve_count_col(state, k, S_TRACK);
-                if (ntracks < target) satisfied = 0;
+                if (ntracks < target) satisfied = false;
             }
             for (k = 0; k < h; k++) {
                 int target = state->numbers->numbers[w+k];
                 int ntracks = solve_count_row(state, k, S_TRACK);
-                if (ntracks < target) satisfied = 0;
+                if (ntracks < target) satisfied = false;
             }
             if (!satisfied) {
                 return solve_set_eflag(state, x, y, dir, E_NOTRACK,
@@ -1282,7 +1284,8 @@
 
 static int tracks_solve(game_state *state, int diff)
 {
-    int didsth, x, y, w = state->p.w, h = state->p.h;
+    int x, y, w = state->p.w, h = state->p.h;
+    bool didsth;
 
     debug(("solve..."));
     state->impossible = false;
@@ -1298,15 +1301,15 @@
     }
 
     while (1) {
-        didsth = 0;
+        didsth = false;
 
-        didsth += solve_update_flags(state);
-        didsth += solve_count_clues(state);
-        didsth += solve_check_loop(state);
+        didsth |= solve_update_flags(state);
+        didsth |= solve_count_clues(state);
+        didsth |= solve_check_loop(state);
 
         if (diff >= DIFF_TRICKY) {
-            didsth += solve_check_single(state);
-            didsth += solve_check_loose_ends(state);
+            didsth |= solve_check_single(state);
+            didsth |= solve_check_loose_ends(state);
         }
 
         if (!didsth || state->impossible) break;
@@ -1315,7 +1318,7 @@
     return state->impossible ? -1 : check_completion(state, false) ? 1 : 0;
 }
 
-static char *move_string_diff(const game_state *before, const game_state *after, int issolve)
+static char *move_string_diff(const game_state *before, const game_state *after, bool issolve)
 {
     int w = after->p.w, h = after->p.h, i, j;
     char *move = snewn(w*h*40, char), *p = move;
@@ -1532,9 +1535,10 @@
         return -1;
 }
 
-static int check_completion(game_state *state, int mark)
+static bool check_completion(game_state *state, bool mark)
 {
-    int w = state->p.w, h = state->p.h, x, y, i, target, ret = true;
+    int w = state->p.w, h = state->p.h, x, y, i, target;
+    bool ret = true;
     int ntrack, nnotrack, ntrackcomplete;
     int *dsf, pathclass;
     struct findloopstate *fls;
@@ -1669,12 +1673,12 @@
 /* Code borrowed from Pearl. */
 
 struct game_ui {
-    int dragging, clearing, notrack;
+    bool dragging, clearing, notrack;
     int drag_sx, drag_sy, drag_ex, drag_ey; /* drag start and end grid coords */
     int clickx, clicky;    /* pixel position of initial click */
 
     int curx, cury;        /* grid position of keyboard cursor; uses half-size grid */
-    int cursor_active;     /* true iff cursor is shown */
+    bool cursor_active;     /* true iff cursor is shown */
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1681,7 +1685,9 @@
 {
     game_ui *ui = snew(game_ui);
 
-    ui->clearing = ui->notrack = ui->dragging = 0;
+    ui->clearing = false;
+    ui->notrack = false;
+    ui->dragging = false;
     ui->drag_sx = ui->drag_sy = ui->drag_ex = ui->drag_ey = -1;
     ui->cursor_active = false;
     ui->curx = ui->cury = 1;
@@ -1738,7 +1744,7 @@
 
 struct game_drawstate {
     int sz6, grid_line_all, grid_line_tl, grid_line_br;
-    int started;
+    bool started;
 
     int w, h, sz;
     unsigned int *flags, *flags_drag;
@@ -1765,8 +1771,8 @@
     }
 }
 
-static int ui_can_flip_edge(const game_state *state, int x, int y, int dir,
-                            int notrack)
+static bool ui_can_flip_edge(const game_state *state, int x, int y, int dir,
+                             bool notrack)
 {
     int w = state->p.w /*, h = state->shared->h, sz = state->shared->sz */;
     int x2 = x + DX(dir);
@@ -1805,7 +1811,7 @@
     return true;
 }
 
-static int ui_can_flip_square(const game_state *state, int x, int y, int notrack)
+static bool ui_can_flip_square(const game_state *state, int x, int y, bool notrack)
 {
     int w = state->p.w, trackc;
     unsigned sf;
@@ -1829,7 +1835,7 @@
     return true;
 }
 
-static char *edge_flip_str(const game_state *state, int x, int y, int dir, int notrack, char *buf) {
+static char *edge_flip_str(const game_state *state, int x, int y, int dir, bool notrack, char *buf) {
     unsigned ef = S_E_FLAGS(state, x, y, dir);
     char c;
 
@@ -1842,7 +1848,7 @@
     return dupstr(buf);
 }
 
-static char *square_flip_str(const game_state *state, int x, int y, int notrack, char *buf) {
+static char *square_flip_str(const game_state *state, int x, int y, bool notrack, char *buf) {
     unsigned f = state->sflags[y*state->p.w+x];
     char c;
 
@@ -1934,7 +1940,7 @@
             game_state *dragged = copy_and_apply_drag(state, ui);
             char *ret = move_string_diff(state, dragged, false);
 
-            ui->dragging = 0;
+            ui->dragging = false;
             free_game(dragged);
 
             return ret;
@@ -1944,7 +1950,7 @@
             /* We might still have been dragging (and just done a one-
              * square drag): cancel drag, so undo doesn't make it like
              * a drag-in-progress. */
-            ui->dragging = 0;
+            ui->dragging = false;
 
             /* Click (or tiny drag). Work out which edge we were
              * closest to. */
@@ -2486,7 +2492,8 @@
                         const game_state *state, int dir, const game_ui *ui,
                         float animtime, float flashtime)
 {
-    int i, x, y, force = 0, flashing = 0, w = ds->w, h = ds->h;
+    int i, x, y, flashing = 0, w = ds->w, h = ds->h;
+    bool force = false;
     game_state *drag_state = NULL;
 
     if (!ds->started) {
@@ -2508,7 +2515,7 @@
         draw_update(dr, 0, 0, (w+2)*TILE_SIZE + 2*BORDER, (h+2)*TILE_SIZE + 2*BORDER);
 
         ds->started = true;
-        force = 1;
+        force = true;
     }
 
     for (i = 0; i < w+h; i++) {
--- a/tree234.c
+++ b/tree234.c
@@ -1337,7 +1337,7 @@
 		 * over to it until it is greater than minimum
 		 * size.
 		 */
-		int undersized = (!sub->elems[0]);
+		bool undersized = (!sub->elems[0]);
 		LOG(("  child %d is %ssize\n", ki,
 		     undersized ? "under" : "minimum-"));
 		LOG(("  neighbour is %s\n",
@@ -1400,16 +1400,16 @@
     return ret;
 }
 tree234 *split234(tree234 *t, void *e, cmpfn234 cmp, int rel) {
-    int before;
+    bool before;
     int index;
 
     assert(rel != REL234_EQ);
 
     if (rel == REL234_GT || rel == REL234_GE) {
-	before = 1;
+	before = true;
 	rel = (rel == REL234_GT ? REL234_LE : REL234_LT);
     } else {
-	before = 0;
+	before = false;
     }
     if (!findrelpos234(t, e, cmp, rel, &index))
 	index = 0;
@@ -2012,7 +2012,7 @@
     tree234 *tree3, *tree4;
     for (i = 0; i <= arraylen; i++) {
 	tree3 = copytree234(tree, NULL, NULL);
-	tree4 = splitpos234(tree3, i, 0);
+	tree4 = splitpos234(tree3, i, false);
 	verifytree(tree3, array, i);
 	verifytree(tree4, array+i, arraylen-i);
 	join234(tree3, tree4);
--- a/twiddle.c
+++ b/twiddle.c
@@ -37,17 +37,17 @@
 
 struct game_params {
     int w, h, n;
-    int rowsonly;
-    int orientable;
+    bool rowsonly;
+    bool orientable;
     int movetarget;
 };
 
 struct game_state {
     int w, h, n;
-    int orientable;
+    bool orientable;
     int *grid;
     int completed;
-    int used_solve;		       /* used to suppress completion flash */
+    bool used_solve;		       /* used to suppress completion flash */
     int movecount, movetarget;
     int lastx, lasty, lastr;	       /* coordinates of last rotation */
 };
@@ -106,7 +106,8 @@
 {
     ret->w = ret->h = atoi(string);
     ret->n = 2;
-    ret->rowsonly = ret->orientable = false;
+    ret->rowsonly = false;
+    ret->orientable = false;
     ret->movetarget = 0;
     while (*string && isdigit((unsigned char)*string)) string++;
     if (*string == 'x') {
@@ -220,7 +221,7 @@
  * the centre is good for a user interface, but too inconvenient to
  * use internally.)
  */
-static void do_rotate(int *grid, int w, int h, int n, int orientable,
+static void do_rotate(int *grid, int w, int h, int n, bool orientable,
 		      int x, int y, int dir)
 {
     int i, j;
@@ -283,9 +284,9 @@
     }
 }
 
-static int grid_complete(int *grid, int wh, int orientable)
+static bool grid_complete(int *grid, int wh, bool orientable)
 {
-    int ok = true;
+    bool ok = true;
     int i;
     for (i = 1; i < wh; i++)
 	if (grid[i] < grid[i-1])
@@ -546,7 +547,8 @@
 static char *game_text_format(const game_state *state)
 {
     char *ret, *p, buf[80];
-    int i, x, y, col, o, maxlen;
+    int i, x, y, col, maxlen;
+    bool o = state->orientable;
 
     /*
      * First work out how many characters we need to display each
@@ -558,7 +560,6 @@
 	x = sprintf(buf, "%d", state->grid[i] / 4);
 	if (col < x) col = x;
     }
-    o = (state->orientable ? 1 : 0);
 
     /*
      * Now we know the exact total size of the grid we're going to
@@ -592,7 +593,7 @@
 
 struct game_ui {
     int cur_x, cur_y;
-    int cur_visible;
+    bool cur_visible;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -626,7 +627,7 @@
 }
 
 struct game_drawstate {
-    int started;
+    bool started;
     int w, h, bgcolour;
     int *grid;
     int tilesize;
@@ -652,7 +653,7 @@
             ui->cur_y--;
         if (button == CURSOR_DOWN && (ui->cur_y+n) < (h))
             ui->cur_y++;
-        ui->cur_visible = 1;
+        ui->cur_visible = true;
         return UI_UPDATE;
     }
 
@@ -669,7 +670,7 @@
 	dir = (button == LEFT_BUTTON ? 1 : -1);
 	if (x < 0 || x > w-n || y < 0 || y > h-n)
 	    return NULL;
-        ui->cur_visible = 0;
+        ui->cur_visible = false;
     } else if (IS_CURSOR_SELECT(button)) {
         if (ui->cur_visible) {
             x = ui->cur_x;
@@ -676,7 +677,7 @@
             y = ui->cur_y;
             dir = (button == CURSOR_SELECT2) ? -1 : +1;
         } else {
-            ui->cur_visible = 1;
+            ui->cur_visible = true;
             return UI_UPDATE;
         }
     } else if (button == 'a' || button == 'A' || button==MOD_NUM_KEYPAD+'7') {
@@ -1091,12 +1092,13 @@
     int i, bgcolour;
     struct rotation srot, *rot;
     int lastx = -1, lasty = -1, lastr = -1;
-    int cx, cy, cmoved = 0, n = state->n;
+    int cx, cy, n = state->n;
+    bool cmoved = false;
 
     cx = ui->cur_visible ? ui->cur_x : -state->n;
     cy = ui->cur_visible ? ui->cur_y : -state->n;
     if (cx != ds->cur_x || cy != ds->cur_y)
-        cmoved = 1;
+        cmoved = true;
 
     if (flashtime > 0) {
         int frame = (int)(flashtime / FLASH_FRAME);
@@ -1181,7 +1183,8 @@
      * Now draw each tile.
      */
     for (i = 0; i < state->w * state->h; i++) {
-	int t, cc = 0;
+	int t;
+        bool cc = false;
 	int tx = i % state->w, ty = i / state->w;
 
 	/*
@@ -1201,10 +1204,10 @@
         if (cmoved) {
             /* cursor has moved (or changed visibility)... */
             if (tx == cx || tx == cx+n-1 || ty == cy || ty == cy+n-1)
-                cc = 1; /* ...we're on new cursor, redraw */
+                cc = true; /* ...we're on new cursor, redraw */
             if (tx == ds->cur_x || tx == ds->cur_x+n-1 ||
                 ty == ds->cur_y || ty == ds->cur_y+n-1)
-                cc = 1; /* ...we were on old cursor, redraw */
+                cc = true; /* ...we were on old cursor, redraw */
         }
 
 	if (ds->bgcolour != bgcolour ||   /* always redraw when flashing */
--- a/undead.c
+++ b/undead.c
@@ -224,7 +224,7 @@
     struct path *paths;
     int *grid;
     int *xinfo;
-    int *fixed;
+    bool *fixed;
 };
 
 struct game_state {
@@ -231,12 +231,12 @@
     struct game_common *common;
     int *guess;
     unsigned char *pencils;
-    unsigned char *cell_errors;
-    unsigned char *hint_errors;
-    unsigned char *hints_done;
-    unsigned char count_errors[3];
-    int solved;
-    int cheated;
+    bool *cell_errors;
+    bool *hint_errors;
+    bool *hints_done;
+    bool count_errors[3];
+    bool solved;
+    bool cheated;
 };
 
 static game_state *new_state(const game_params *params) {
@@ -279,15 +279,15 @@
     state->guess = NULL;
     state->pencils = NULL;
 
-    state->cell_errors = snewn(state->common->wh, unsigned char);
+    state->cell_errors = snewn(state->common->wh, bool);
     for (i=0;i<state->common->wh;i++)
         state->cell_errors[i] = false;
-    state->hint_errors = snewn(2*state->common->num_paths, unsigned char);
+    state->hint_errors = snewn(2*state->common->num_paths, bool);
     for (i=0;i<2*state->common->num_paths;i++)
         state->hint_errors[i] = false;
-    state->hints_done = snewn(2 * state->common->num_paths, unsigned char);
+    state->hints_done = snewn(2 * state->common->num_paths, bool);
     memset(state->hints_done, 0,
-           2 * state->common->num_paths * sizeof(unsigned char));
+           2 * state->common->num_paths * sizeof(bool));
     for (i=0;i<3;i++)
         state->count_errors[i] = false;
 
@@ -318,23 +318,23 @@
     else ret->pencils = NULL;
 
     if (state->cell_errors != NULL) {
-        ret->cell_errors = snewn(ret->common->wh,unsigned char);
+        ret->cell_errors = snewn(ret->common->wh,bool);
         memcpy(ret->cell_errors, state->cell_errors,
-               ret->common->wh*sizeof(unsigned char));
+               ret->common->wh*sizeof(bool));
     }
     else ret->cell_errors = NULL;
 
     if (state->hint_errors != NULL) {
-        ret->hint_errors = snewn(2*ret->common->num_paths,unsigned char);
+        ret->hint_errors = snewn(2*ret->common->num_paths,bool);
         memcpy(ret->hint_errors, state->hint_errors,
-               2*ret->common->num_paths*sizeof(unsigned char));
+               2*ret->common->num_paths*sizeof(bool));
     }
     else ret->hint_errors = NULL;
 
     if (state->hints_done != NULL) {
-        ret->hints_done = snewn(2 * state->common->num_paths, unsigned char);
+        ret->hints_done = snewn(2 * state->common->num_paths, bool);
         memcpy(ret->hints_done, state->hints_done,
-               2 * state->common->num_paths * sizeof(unsigned char));
+               2 * state->common->num_paths * sizeof(bool));
     }
     else ret->hints_done = NULL;
 
@@ -438,7 +438,7 @@
     for (i=0;i<2*(state->common->params.w + state->common->params.h);i++) {
         int x,y,dir;
         int j,k,num_monsters;
-        int found;
+        bool found;
         int c,p; 
         found = false;
         /* Check whether inverse path is already in list */
@@ -529,7 +529,7 @@
     int *possible;
 };
 
-int next_list(struct guess *g, int pos) {
+bool next_list(struct guess *g, int pos) {
 
     if (pos == 0) {
         if ((g->guess[pos] == 1 && g->possible[pos] == 1) || 
@@ -636,7 +636,8 @@
         view_count[i] = 0;
     
     do {
-        int mirror, start_view, end_view;
+        bool mirror;
+        int start_view, end_view;
         
         mirror = false;
         start_view = 0;
@@ -646,9 +647,9 @@
                 for (i=0;i<path_guess.length;i++) {
                     if (state->common->paths[counter].p[p] ==
                         state->common->paths[counter].mapping[i]) {
-                        if (path_guess.guess[i] == 1 && mirror == true)
+                        if (path_guess.guess[i] == 1 && mirror)
                             start_view++;
-                        if (path_guess.guess[i] == 2 && mirror == false)
+                        if (path_guess.guess[i] == 2 && !mirror)
                             start_view++;
                         if (path_guess.guess[i] == 4)
                             start_view++;
@@ -665,9 +666,9 @@
                 for (i=0;i<path_guess.length;i++) {
                     if (state->common->paths[counter].p[p] ==
                         state->common->paths[counter].mapping[i]) {
-                        if (path_guess.guess[i] == 1 && mirror == true)
+                        if (path_guess.guess[i] == 1 && mirror)
                             end_view++;
-                        if (path_guess.guess[i] == 2 && mirror == false)
+                        if (path_guess.guess[i] == 2 && !mirror)
                             end_view++;
                         if (path_guess.guess[i] == 4)
                             end_view++;
@@ -781,8 +782,8 @@
     return cNone;
 }
 
-int check_numbers(game_state *state, int *guess) {
-    int valid;
+bool check_numbers(game_state *state, int *guess) {
+    bool valid;
     int i;
     int count_ghosts, count_vampires, count_zombies;
 
@@ -802,9 +803,9 @@
     return valid;
 }
 
-int check_solution(int *g, struct path path) {
+bool check_solution(int *g, struct path path) {
     int i;
-    int mirror;
+    bool mirror;
     int count;
 
     count = 0;
@@ -834,8 +835,8 @@
     return true;
 }
 
-int solve_iterative(game_state *state, struct path *paths) {
-    int solved;
+bool solve_iterative(game_state *state, struct path *paths) {
+    bool solved;
     int p,i,j,count;
 
     int *guess;
@@ -907,8 +908,8 @@
     return solved;
 }
 
-int solve_bruteforce(game_state *state, struct path *paths) {
-    int solved, correct;
+bool solve_bruteforce(game_state *state, struct path *paths) {
+    bool solved, correct;
     int number_solutions;
     int p,i;
 
@@ -978,12 +979,12 @@
     int filling;
     int max_length;
     int count_ghosts, count_vampires, count_zombies;
-    int abort;
+    bool abort;
     float ratio;
     
     /* Variables for solver algorithm */
-    int solved_iterative, solved_bruteforce, contains_inconsistency,
-        count_ambiguous;
+    bool solved_iterative, solved_bruteforce, contains_inconsistency;
+    int count_ambiguous;
     int iterative_depth;
     int *old_guess;
 
@@ -1060,7 +1061,7 @@
 
         /* Initialize fixed flag from common. Not needed for the
          * puzzle generator; initialize it for having clean code */
-        new->common->fixed = snewn(new->common->num_total,int);
+        new->common->fixed = snewn(new->common->num_total, bool);
         for (g=0;g<new->common->num_total;g++)
             new->common->fixed[g] = false;
 
@@ -1156,7 +1157,8 @@
 
         /* Prepare path information needed by the solver (containing all hints) */  
         for (p=0;p<new->common->num_paths;p++) {
-            int mirror,x,y;
+            bool mirror;
+            int x,y;
 
             new->common->paths[p].sightings_start = 0;
             new->common->paths[p].sightings_end = 0;
@@ -1166,8 +1168,8 @@
 
                 if (new->common->paths[p].p[g] == -1) mirror = true;
                 else {
-                    if      (new->guess[new->common->paths[p].p[g]] == 1 && mirror == true)  (new->common->paths[p].sightings_start)++;
-                    else if (new->guess[new->common->paths[p].p[g]] == 2 && mirror == false) (new->common->paths[p].sightings_start)++;
+                    if      (new->guess[new->common->paths[p].p[g]] == 1 && mirror)  (new->common->paths[p].sightings_start)++;
+                    else if (new->guess[new->common->paths[p].p[g]] == 2 && !mirror) (new->common->paths[p].sightings_start)++;
                     else if (new->guess[new->common->paths[p].p[g]] == 4)                    (new->common->paths[p].sightings_start)++;
                 }
             }
@@ -1176,8 +1178,8 @@
             for (g=new->common->paths[p].length-1;g>=0;g--) {
                 if (new->common->paths[p].p[g] == -1) mirror = true;
                 else {
-                    if      (new->guess[new->common->paths[p].p[g]] == 1 && mirror == true)  (new->common->paths[p].sightings_end)++;
-                    else if (new->guess[new->common->paths[p].p[g]] == 2 && mirror == false) (new->common->paths[p].sightings_end)++;
+                    if      (new->guess[new->common->paths[p].p[g]] == 1 && mirror)  (new->common->paths[p].sightings_end)++;
+                    else if (new->guess[new->common->paths[p].p[g]] == 2 && !mirror) (new->common->paths[p].sightings_end)++;
                     else if (new->guess[new->common->paths[p].p[g]] == 4)                    (new->common->paths[p].sightings_end)++;
                 }
             }
@@ -1204,8 +1206,7 @@
         count_ambiguous = 0;
 
         while (true) {
-            int no_change;          
-            no_change = true;
+            bool no_change = true;
             solved_iterative = solve_iterative(new,new->common->paths);
             iterative_depth++;      
             for (p=0;p<new->common->num_total;p++) {
@@ -1355,7 +1356,7 @@
 
     state->guess = snewn(state->common->num_total,int);
     state->pencils = snewn(state->common->num_total,unsigned char);
-    state->common->fixed = snewn(state->common->num_total,int);
+    state->common->fixed = snewn(state->common->num_total, bool);
     for (i=0;i<state->common->num_total;i++) {
         state->guess[i] = 7;
         state->pencils[i] = 0;
@@ -1512,8 +1513,8 @@
     int p;
     int *old_guess;
     int iterative_depth;
-    int solved_iterative, solved_bruteforce, contains_inconsistency,
-        count_ambiguous;
+    bool solved_iterative, solved_bruteforce, contains_inconsistency;
+    int count_ambiguous;
 
     int i;
     char *move, *c;
@@ -1536,8 +1537,7 @@
     
     /* Try to solve the puzzle with the iterative solver */
     while (true) {
-        int no_change;
-        no_change = true;
+        bool no_change = true;
         solved_iterative =
             solve_iterative(solve_state,solve_state->common->paths);
         iterative_depth++;
@@ -1638,8 +1638,8 @@
 
 struct game_ui {
     int hx, hy;                         /* as for solo.c, highlight pos */
-    int hshow, hpencil, hcursor;        /* show state, type, and ?cursor. */
-    int ascii;
+    bool hshow, hpencil, hcursor;       /* show state, type, and ?cursor. */
+    bool ascii;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1646,7 +1646,9 @@
 {
     game_ui *ui = snew(game_ui);
     ui->hx = ui->hy = 0;
-    ui->hpencil = ui->hshow = ui->hcursor = 0;
+    ui->hpencil = false;
+    ui->hshow = false;
+    ui->hcursor = false;
     ui->ascii = false;
     return ui;
 }
@@ -1675,28 +1677,30 @@
     if (ui->hshow && ui->hpencil && !ui->hcursor) {
         int g = newstate->guess[newstate->common->xinfo[ui->hx + ui->hy*(newstate->common->params.w+2)]];
         if (g == 1 || g == 2 || g == 4)
-            ui->hshow = 0;
+            ui->hshow = false;
     }
 }
 
 struct game_drawstate {
-    int tilesize, started, solved;
+    int tilesize;
+    bool started, solved;
     int w, h;
         
     int *monsters;
     unsigned char *pencils;
 
-    unsigned char count_errors[3];
-    unsigned char *cell_errors;
-    unsigned char *hint_errors;
-    unsigned char *hints_done;
+    bool count_errors[3];
+    bool *cell_errors;
+    bool *hint_errors;
+    bool *hints_done;
 
-    int hx, hy, hshow, hpencil; /* as for game_ui. */
-    int hflash;
-    int ascii;
+    int hx, hy;
+    bool hshow, hpencil; /* as for game_ui. */
+    bool hflash;
+    bool ascii;
 };
 
-static int is_clue(const game_state *state, int x, int y)
+static bool is_clue(const game_state *state, int x, int y)
 {
     int h = state->common->params.h, w = state->common->params.w;
 
@@ -1746,27 +1750,27 @@
         return dupstr("M");
     }
     
-    if (ui->hshow == 1 && ui->hpencil == 0) {
+    if (ui->hshow && !ui->hpencil) {
         xi = state->common->xinfo[ui->hx + ui->hy*(state->common->params.w+2)];
         if (xi >= 0 && !state->common->fixed[xi]) {
             if (button == 'g' || button == 'G' || button == '1') {
-                if (!ui->hcursor) ui->hshow = 0;
+                if (!ui->hcursor) ui->hshow = false;
                 sprintf(buf,"G%d",xi);
                 return dupstr(buf);
             }
             if (button == 'v' || button == 'V' || button == '2') {
-                if (!ui->hcursor) ui->hshow = 0;
+                if (!ui->hcursor) ui->hshow = false;
                 sprintf(buf,"V%d",xi);
                 return dupstr(buf);
             }
             if (button == 'z' || button == 'Z' || button == '3') {
-                if (!ui->hcursor) ui->hshow = 0;
+                if (!ui->hcursor) ui->hshow = false;
                 sprintf(buf,"Z%d",xi);
                 return dupstr(buf);
             }
             if (button == 'e' || button == 'E' || button == CURSOR_SELECT2 ||
                 button == '0' || button == '\b' ) {
-                if (!ui->hcursor) ui->hshow = 0;
+                if (!ui->hcursor) ui->hshow = false;
                 sprintf(buf,"E%d",xi);
                 return dupstr(buf);
             }
@@ -1784,37 +1788,50 @@
               case CURSOR_RIGHT:  ui->hx += (ui->hx < ds->w) ? 1 : 0; break;
               case CURSOR_LEFT:   ui->hx -= (ui->hx > 1)     ? 1 : 0; break;
             }
-        ui->hshow = ui->hcursor = 1;
+        ui->hshow = true;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
     if (ui->hshow && button == CURSOR_SELECT) {
-        ui->hpencil = 1 - ui->hpencil;
-        ui->hcursor = 1;
+        ui->hpencil = !ui->hpencil;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
 
-    if (ui->hshow == 1 && ui->hpencil == 1) {
+    if (ui->hshow && ui->hpencil) {
         xi = state->common->xinfo[ui->hx + ui->hy*(state->common->params.w+2)];
         if (xi >= 0 && !state->common->fixed[xi]) {
             if (button == 'g' || button == 'G' || button == '1') {
                 sprintf(buf,"g%d",xi);
-                if (!ui->hcursor) ui->hpencil = ui->hshow = 0;
+                if (!ui->hcursor) {
+                    ui->hpencil = false;
+                    ui->hshow = false;
+                }
                 return dupstr(buf);
             }
             if (button == 'v' || button == 'V' || button == '2') {
                 sprintf(buf,"v%d",xi);
-                if (!ui->hcursor) ui->hpencil = ui->hshow = 0;
+                if (!ui->hcursor) {
+                    ui->hpencil = false;
+                    ui->hshow = false;
+                }
                 return dupstr(buf);
             }
             if (button == 'z' || button == 'Z' || button == '3') {
                 sprintf(buf,"z%d",xi);
-                if (!ui->hcursor) ui->hpencil = ui->hshow = 0;
+                if (!ui->hcursor) {
+                    ui->hpencil = false;
+                    ui->hshow = false;
+                }
                 return dupstr(buf);
             }
             if (button == 'e' || button == 'E' || button == CURSOR_SELECT2 ||
                 button == '0' || button == '\b') {
                 sprintf(buf,"E%d",xi);
-                if (!ui->hcursor) ui->hpencil = ui->hshow = 0;
+                if (!ui->hcursor) {
+                    ui->hpencil = false;
+                    ui->hshow = false;
+                }
                 return dupstr(buf);
             }
         }       
@@ -1824,52 +1841,68 @@
         xi = state->common->xinfo[gx+gy*(state->common->params.w+2)];
         if (xi >= 0 && !state->common->fixed[xi]) {
             g = state->guess[xi];
-            if (ui->hshow == 0) {
+            if (!ui->hshow) {
                 if (button == LEFT_BUTTON) {
-                    ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0;
+                    ui->hshow = true;
+                    ui->hpencil = false;
+                    ui->hcursor = false;
                     ui->hx = gx; ui->hy = gy;
                     return UI_UPDATE;
                 }
                 else if (button == RIGHT_BUTTON && g == 7) {
-                    ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0;
+                    ui->hshow = true;
+                    ui->hpencil = true;
+                    ui->hcursor = false;
                     ui->hx = gx; ui->hy = gy;
                     return UI_UPDATE;
                 }
             }
-            else if (ui->hshow == 1) {
+            else if (ui->hshow) {
                 if (button == LEFT_BUTTON) {
-                    if (ui->hpencil == 0) {
+                    if (!ui->hpencil) {
                         if (gx == ui->hx && gy == ui->hy) {
-                            ui->hshow = 0; ui->hpencil = 0; ui->hcursor = 0;
+                            ui->hshow = false;
+                            ui->hpencil = false;
+                            ui->hcursor = false;
                             ui->hx = 0; ui->hy = 0;
                             return UI_UPDATE;
                         }
                         else {
-                            ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0;
+                            ui->hshow = true;
+                            ui->hpencil = false;
+                            ui->hcursor = false;
                             ui->hx = gx; ui->hy = gy;
                             return UI_UPDATE;
                         }
                     }
                     else {
-                        ui->hshow = 1; ui->hpencil = 0; ui->hcursor = 0;
+                        ui->hshow = true;
+                        ui->hpencil = false;
+                        ui->hcursor = false;
                         ui->hx = gx; ui->hy = gy;
                         return UI_UPDATE;
                     }
                 }
                 else if (button == RIGHT_BUTTON) {
-                    if (ui->hpencil == 0 && g == 7) {
-                        ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0;
+                    if (!ui->hpencil && g == 7) {
+                        ui->hshow = true;
+                        ui->hpencil = true;
+                        ui->hcursor = false;
                         ui->hx = gx; ui->hy = gy;
                         return UI_UPDATE;
                     }
                     else {
                         if (gx == ui->hx && gy == ui->hy) {
-                            ui->hshow = 0; ui->hpencil = 0; ui->hcursor = 0;
+                            ui->hshow = false;
+                            ui->hpencil = false;
+                            ui->hcursor = false;
                             ui->hx = 0; ui->hy = 0;
                             return UI_UPDATE;
                         }
                         else if (g == 7) {
-                            ui->hshow = 1; ui->hpencil = 1; ui->hcursor = 0;
+                            ui->hshow = true;
+                            ui->hpencil = true;
+                            ui->hcursor = false;
                             ui->hx = gx; ui->hy = gy;
                             return UI_UPDATE;
                         }
@@ -1887,8 +1920,8 @@
     return NULL;
 }
 
-int check_numbers_draw(game_state *state, int *guess) {
-    int valid, filled;
+bool check_numbers_draw(game_state *state, int *guess) {
+    bool valid, filled;
     int i,x,y,xy;
     int count_ghosts, count_vampires, count_zombies;
 
@@ -1943,11 +1976,11 @@
     return valid;
 }
 
-int check_path_solution(game_state *state, int p) {
+bool check_path_solution(game_state *state, int p) {
     int i;
-    int mirror;
+    bool mirror;
     int count;
-    int correct;
+    bool correct;
     int unfilled;
 
     count = 0;
@@ -2012,8 +2045,8 @@
 {
     int x,y,n,p,i;
     char c;
-    int correct; 
-    int solver; 
+    bool correct; 
+    bool solver; 
 
     game_state *ret = dup_game(state);
     solver = false;
@@ -2173,17 +2206,19 @@
     for (i=0;i<state->common->num_total;i++)
         ds->pencils[i] = 0;
 
-    ds->cell_errors = snewn(state->common->wh,unsigned char);
+    ds->cell_errors = snewn(state->common->wh,bool);
     for (i=0;i<state->common->wh;i++)
         ds->cell_errors[i] = false;
-    ds->hint_errors = snewn(2*state->common->num_paths,unsigned char);
+    ds->hint_errors = snewn(2*state->common->num_paths,bool);
     for (i=0;i<2*state->common->num_paths;i++)
         ds->hint_errors[i] = false;
-    ds->hints_done = snewn(2 * state->common->num_paths, unsigned char);
+    ds->hints_done = snewn(2 * state->common->num_paths, bool);
     memset(ds->hints_done, 0,
-           2 * state->common->num_paths * sizeof(unsigned char));
+           2 * state->common->num_paths * sizeof(bool));
 
-    ds->hshow = ds->hpencil = ds->hflash = 0;
+    ds->hshow = false;
+    ds->hpencil = false;
+    ds->hflash = false;
     ds->hx = ds->hy = 0;
     return ds;
 }
@@ -2202,7 +2237,7 @@
                                  const game_state *state, const game_ui *ui,
                                  int x, int y) {
 
-    int hon;
+    bool hon;
     int dx,dy;
     dx = BORDER+(x* ds->tilesize)+(TILESIZE/2);
     dy = BORDER+(y* ds->tilesize)+(TILESIZE/2)+TILESIZE;
@@ -2236,7 +2271,7 @@
 }
 
 static void draw_monster(drawing *dr, game_drawstate *ds, int x, int y,
-                         int tilesize, int hflash, int monster)
+                         int tilesize, bool hflash, int monster)
 {
     int black = (hflash ? COL_FLASH : COL_TEXT);
     
@@ -2365,7 +2400,7 @@
 }
 
 static void draw_monster_count(drawing *dr, game_drawstate *ds,
-                               const game_state *state, int c, int hflash) {
+                               const game_state *state, int c, bool hflash) {
     int dx,dy;
     char buf[8];
     char bufm[8];
@@ -2410,7 +2445,7 @@
 
 static void draw_path_hint(drawing *dr, game_drawstate *ds,
                            const struct game_params *params,
-                           int hint_index, int hflash, int hint) {
+                           int hint_index, bool hflash, int hint) {
     int x, y, color, dx, dy, text_dx, text_dy, text_size;
     char buf[4];
 
@@ -2446,7 +2481,7 @@
 
 static void draw_mirror(drawing *dr, game_drawstate *ds,
                         const game_state *state, int x, int y,
-                        int hflash, int mirror) {
+                        bool hflash, int mirror) {
     int dx,dy,mx1,my1,mx2,my2;
     dx = BORDER+(x* ds->tilesize)+(TILESIZE/2);
     dy = BORDER+(y* ds->tilesize)+(TILESIZE/2)+TILESIZE;
@@ -2472,7 +2507,7 @@
 
 static void draw_big_monster(drawing *dr, game_drawstate *ds,
                              const game_state *state, int x, int y,
-                             int hflash, int monster)
+                             bool hflash, int monster)
 {
     int dx,dy;
     char buf[10];
@@ -2516,7 +2551,7 @@
                 if (!ds->ascii) {
                     draw_monster(dr, ds,
                                  dx + TILESIZE/2 * px, dy + TILESIZE/2 * py,
-                                 TILESIZE/2, 0, monsters[py*2+px]);
+                                 TILESIZE/2, false, monsters[py*2+px]);
                 }
                 else {
                     switch (monsters[py*2+px]) {
@@ -2537,10 +2572,10 @@
 
 #define FLASH_TIME 0.7F
 
-static int is_hint_stale(const game_drawstate *ds, int hflash,
-                         const game_state *state, int index)
+static bool is_hint_stale(const game_drawstate *ds, bool hflash,
+                          const game_state *state, int index)
 {
-    int ret = false;
+    bool ret = false;
     if (!ds->started) ret = true;
     if (ds->hflash != hflash) ret = true;
 
@@ -2563,7 +2598,8 @@
                         float animtime, float flashtime)
 {
     int i,j,x,y,xy;
-    int stale, xi, c, hflash, hchanged, changed_ascii;
+    int xi, c;
+    bool stale, hflash, hchanged, changed_ascii;
 
     hflash = (int)(flashtime * 5 / FLASH_TIME) % 2;
 
--- a/unequal.c
+++ b/unequal.c
@@ -55,11 +55,15 @@
     NCOLOURS
 };
 
+typedef enum {
+    MODE_UNEQUAL,      /* Puzzle indicators are 'greater-than'. */
+    MODE_ADJACENT      /* Puzzle indicators are 'adjacent number'. */
+} Mode;
+
 struct game_params {
     int order;          /* Size of latin square */
     int diff;           /* Difficulty */
-    int adjacent;       /* Puzzle indicators are 'adjacent number'
-                            not 'greater-than'. */
+    Mode mode;
 };
 
 #define F_IMMUTABLE     1       /* passed in as game description */
@@ -82,7 +86,9 @@
 #define F_ERROR_MASK (F_ERROR|F_ERROR_UP|F_ERROR_RIGHT|F_ERROR_DOWN|F_ERROR_LEFT)
 
 struct game_state {
-    int order, completed, cheated, adjacent;
+    int order;
+    bool completed, cheated;
+    Mode mode;
     digit *nums;                 /* actual numbers (size order^2) */
     unsigned char *hints;        /* remaining possiblities (size order^3) */
     unsigned int *flags;         /* flags (size order^2) */
@@ -138,7 +144,7 @@
     *ret = unequal_presets[i]; /* structure copy */
 
     sprintf(buf, "%s: %dx%d %s",
-            ret->adjacent ? "Adjacent" : "Unequal",
+            ret->mode == MODE_ADJACENT ? "Adjacent" : "Unequal",
             ret->order, ret->order,
             unequal_diffnames[ret->diff]);
 
@@ -178,9 +184,9 @@
 
     if (*p == 'a') {
         p++;
-        ret->adjacent = 1;
+        ret->mode = MODE_ADJACENT;
     } else
-        ret->adjacent = 0;
+        ret->mode = MODE_UNEQUAL;
 
     if (*p == 'd') {
         int i;
@@ -201,7 +207,7 @@
     char ret[80];
 
     sprintf(ret, "%d", params->order);
-    if (params->adjacent)
+    if (params->mode == MODE_ADJACENT)
         sprintf(ret + strlen(ret), "a");
     if (full)
         sprintf(ret + strlen(ret), "d%c", unequal_diffchars[params->diff]);
@@ -219,7 +225,7 @@
     ret[0].name = "Mode";
     ret[0].type = C_CHOICES;
     ret[0].u.choices.choicenames = ":Unequal:Adjacent";
-    ret[0].u.choices.selected = params->adjacent;
+    ret[0].u.choices.selected = params->mode;
 
     ret[1].name = "Size (s*s)";
     ret[1].type = C_STRING;
@@ -241,7 +247,7 @@
 {
     game_params *ret = snew(game_params);
 
-    ret->adjacent = cfg[0].u.choices.selected;
+    ret->mode = cfg[0].u.choices.selected;
     ret->order = atoi(cfg[1].u.string.sval);
     ret->diff = cfg[2].u.choices.selected;
 
@@ -254,7 +260,7 @@
         return "Order must be between 3 and 32";
     if (params->diff >= DIFFCOUNT)
         return "Unknown difficulty rating";
-    if (params->order < 5 && params->adjacent &&
+    if (params->order < 5 && params->mode == MODE_ADJACENT &&
         params->diff >= DIFF_SET)
         return "Order must be at least 5 for Adjacent puzzles of this difficulty.";
     return NULL;
@@ -271,14 +277,15 @@
     { F_ADJ_LEFT,  F_ADJ_RIGHT, F_ERROR_LEFT,  -1,  0, '<', '|' }
 };
 
-static game_state *blank_game(int order, int adjacent)
+static game_state *blank_game(int order, Mode mode)
 {
     game_state *state = snew(game_state);
     int o2 = order*order, o3 = o2*order;
 
     state->order = order;
-    state->adjacent = adjacent;
-    state->completed = state->cheated = 0;
+    state->mode = mode;
+    state->completed = false;
+    state->cheated = false;
 
     state->nums = snewn(o2, digit);
     state->hints = snewn(o3, unsigned char);
@@ -293,7 +300,7 @@
 
 static game_state *dup_game(const game_state *state)
 {
-    game_state *ret = blank_game(state->order, state->adjacent);
+    game_state *ret = blank_game(state->order, state->mode);
     int o2 = state->order*state->order, o3 = o2*state->order;
 
     memcpy(ret->nums, state->nums, o2 * sizeof(digit));
@@ -313,12 +320,13 @@
 
 #define CHECKG(x,y) grid[(y)*o+(x)]
 
-/* Returns 0 if it finds an error, 1 otherwise. */
-static int check_num_adj(digit *grid, game_state *state,
-                        int x, int y, int me)
+/* Returns false if it finds an error, true if ok. */
+static bool check_num_adj(digit *grid, game_state *state,
+                          int x, int y, bool me)
 {
     unsigned int f = GRID(state, flags, x, y);
-    int ret = 1, i, o = state->order;
+    bool ret = true;
+    int i, o = state->order;
 
     for (i = 0; i < 4; i++) {
         int dx = adjthan[i].dx, dy = adjthan[i].dy, n, dn;
@@ -332,7 +340,7 @@
         assert (n != 0);
         if (dn == 0) continue;
 
-        if (state->adjacent) {
+        if (state->mode == MODE_ADJACENT) {
             int gd = abs(n-dn);
 
             if ((f & adjthan[i].f) && (gd != 1)) {
@@ -339,13 +347,13 @@
                 debug(("check_adj error (%d,%d):%d should be | (%d,%d):%d",
                        x, y, n, x+dx, y+dy, dn));
                 if (me) GRID(state, flags, x, y) |= adjthan[i].fe;
-                ret = 0;
+                ret = false;
             }
             if (!(f & adjthan[i].f) && (gd == 1)) {
                 debug(("check_adj error (%d,%d):%d should not be | (%d,%d):%d",
                        x, y, n, x+dx, y+dy, dn));
                 if (me) GRID(state, flags, x, y) |= adjthan[i].fe;
-                ret = 0;
+                ret = false;
             }
 
         } else {
@@ -353,7 +361,7 @@
                 debug(("check_adj error (%d,%d):%d not > (%d,%d):%d",
                        x, y, n, x+dx, y+dy, dn));
                 if (me) GRID(state, flags, x, y) |= adjthan[i].fe;
-                ret = 0;
+                ret = false;
             }
         }
     }
@@ -360,12 +368,13 @@
     return ret;
 }
 
-/* Returns 0 if it finds an error, 1 otherwise. */
-static int check_num_error(digit *grid, game_state *state,
-                           int x, int y, int mark_errors)
+/* Returns false if it finds an error, true if ok. */
+static bool check_num_error(digit *grid, game_state *state,
+                            int x, int y, bool mark_errors)
 {
     int o = state->order;
-    int xx, yy, val = CHECKG(x,y), ret = 1;
+    int xx, yy, val = CHECKG(x,y);
+    bool ret = true;
 
     assert(val != 0);
 
@@ -372,13 +381,13 @@
     /* check for dups in same column. */
     for (yy = 0; yy < state->order; yy++) {
         if (yy == y) continue;
-        if (CHECKG(x,yy) == val) ret = 0;
+        if (CHECKG(x,yy) == val) ret = false;
     }
 
     /* check for dups in same row. */
     for (xx = 0; xx < state->order; xx++) {
         if (xx == x) continue;
-        if (CHECKG(xx,y) == val) ret = 0;
+        if (CHECKG(xx,y) == val) ret = false;
     }
 
     if (!ret) {
@@ -392,7 +401,7 @@
  *               0 for 'incomplete'
  *               1 for 'complete and correct'
  */
-static int check_complete(digit *grid, game_state *state, int mark_errors)
+static int check_complete(digit *grid, game_state *state, bool mark_errors)
 {
     int x, y, ret = 1, o = state->order;
 
@@ -469,7 +478,7 @@
             *p++ = n > 0 ? n2c(n, state->order) : '.';
 
             if (x < (state->order-1)) {
-                if (state->adjacent) {
+                if (state->mode == MODE_ADJACENT) {
                     *p++ = (GRID(state, flags, x, y) & F_ADJ_RIGHT) ? '|' : ' ';
                 } else {
                     if (GRID(state, flags, x, y) & F_ADJ_RIGHT)
@@ -485,7 +494,7 @@
 
         if (y < (state->order-1)) {
             for (x = 0; x < state->order; x++) {
-                if (state->adjacent) {
+                if (state->mode == MODE_ADJACENT) {
                     *p++ = (GRID(state, flags, x, y) & F_ADJ_DOWN) ? '-' : ' ';
                 } else {
                     if (GRID(state, flags, x, y) & F_ADJ_DOWN)
@@ -561,7 +570,8 @@
     ctx->links = NULL;
     ctx->state = state;
 
-    if (state->adjacent) return ctx; /* adjacent mode doesn't use links. */
+    if (state->mode == MODE_ADJACENT)
+        return ctx; /* adjacent mode doesn't use links. */
 
     for (x = 0; x < o; x++) {
         for (y = 0; y < o; y++) {
@@ -684,7 +694,8 @@
              * adjacent possibles reflect the adjacent/non-adjacent clue. */
 
             for (i = 0; i < 4; i++) {
-                int isadjacent = (GRID(ctx->state, flags, x, y) & adjthan[i].f);
+                bool isadjacent =
+                    (GRID(ctx->state, flags, x, y) & adjthan[i].f);
 
                 nx = x + adjthan[i].dx, ny = y + adjthan[i].dy;
                 if (nx < 0 || ny < 0 || nx >= o || ny >= o)
@@ -697,7 +708,7 @@
                     if (isadjacent && (gd == 1)) continue;
                     if (!isadjacent && (gd != 1)) continue;
 
-                    if (cube(nx, ny, n+1) == false)
+                    if (!cube(nx, ny, n+1))
                         continue; /* already discounted this possibility. */
 
 #ifdef STANDALONE_SOLVER
@@ -731,7 +742,8 @@
     for (x = 0; x < o; x++) {
         for (y = 0; y < o; y++) {
             for (i = 0; i < 4; i++) {
-                int isadjacent = (GRID(ctx->state, flags, x, y) & adjthan[i].f);
+                bool isadjacent =
+                    (GRID(ctx->state, flags, x, y) & adjthan[i].f);
 
                 nx = x + adjthan[i].dx, ny = y + adjthan[i].dy;
                 if (nx < 0 || ny < 0 || nx >= o || ny >= o)
@@ -745,7 +757,7 @@
                 memset(scratch, 0, o*sizeof(int));
 
                 for (n = 0; n < o; n++) {
-                    if (cube(x, y, n+1) == false) continue;
+                    if (!cube(x, y, n+1)) continue;
 
                     for (nn = 0; nn < o; nn++) {
                         if (n == nn) continue;
@@ -762,7 +774,7 @@
                  * currently set but are not indicated in scratch. */
                 for (n = 0; n < o; n++) {
                     if (scratch[n] == 1) continue;
-                    if (cube(nx, ny, n+1) == false) continue;
+                    if (!cube(nx, ny, n+1)) continue;
 
 #ifdef STANDALONE_SOLVER
                     if (solver_show_working) {
@@ -786,7 +798,7 @@
 static int solver_easy(struct latin_solver *solver, void *vctx)
 {
     struct solver_ctx *ctx = (struct solver_ctx *)vctx;
-    if (ctx->state->adjacent)
+    if (ctx->state->mode == MODE_ADJACENT)
 	return solver_adjacent(solver, vctx);
     else
 	return solver_links(solver, vctx);
@@ -795,7 +807,7 @@
 static int solver_set(struct latin_solver *solver, void *vctx)
 {
     struct solver_ctx *ctx = (struct solver_ctx *)vctx;
-    if (ctx->state->adjacent)
+    if (ctx->state->mode == MODE_ADJACENT)
 	return solver_adjacent_set(solver, vctx);
     else
 	return 0;
@@ -866,8 +878,8 @@
     return soln;
 }
 
-/* returns non-zero if it placed (or could have placed) clue. */
-static int gg_place_clue(game_state *state, int ccode, digit *latin, int checkonly)
+/* returns true if it placed (or could have placed) clue. */
+static bool gg_place_clue(game_state *state, int ccode, digit *latin, bool checkonly)
 {
     int loc = ccode / 5, which = ccode % 5;
     int x = loc % state->order, y = loc / state->order;
@@ -883,7 +895,7 @@
             }
 #endif
             assert(state->nums[loc] == latin[loc]);
-            return 0;
+            return false;
         }
         if (!checkonly) {
             state->nums[loc] = latin[loc];
@@ -891,31 +903,31 @@
     } else {                    /* add flag */
         int lx, ly, lloc;
 
-        if (state->adjacent)
-            return 0; /* never add flag clues in adjacent mode (they're always
-                         all present) */
+        if (state->mode == MODE_ADJACENT)
+            return false; /* never add flag clues in adjacent mode
+                             (they're always all present) */
 
         if (state->flags[loc] & adjthan[which].f)
-            return 0; /* already has flag. */
+            return false; /* already has flag. */
 
         lx = x + adjthan[which].dx;
         ly = y + adjthan[which].dy;
         if (lx < 0 || ly < 0 || lx >= state->order || ly >= state->order)
-            return 0; /* flag compares to off grid */
+            return false; /* flag compares to off grid */
 
         lloc = loc + adjthan[which].dx + adjthan[which].dy*state->order;
         if (latin[loc] <= latin[lloc])
-            return 0; /* flag would be incorrect */
+            return false; /* flag would be incorrect */
 
         if (!checkonly) {
             state->flags[loc] |= adjthan[which].f;
         }
     }
-    return 1;
+    return true;
 }
 
-/* returns non-zero if it removed (or could have removed) the clue. */
-static int gg_remove_clue(game_state *state, int ccode, int checkonly)
+/* returns true if it removed (or could have removed) the clue. */
+static bool gg_remove_clue(game_state *state, int ccode, bool checkonly)
 {
     int loc = ccode / 5, which = ccode % 5;
 #ifdef STANDALONE_SOLVER
@@ -925,7 +937,7 @@
     assert(loc < state->order*state->order);
 
     if (which == 4) {           /* remove number. */
-        if (state->nums[loc] == 0) return 0;
+        if (state->nums[loc] == 0) return false;
         if (!checkonly) {
 #ifdef STANDALONE_SOLVER
             if (solver_show_working)
@@ -935,10 +947,10 @@
             state->nums[loc] = 0;
         }
     } else {                    /* remove flag */
-        if (state->adjacent)
-            return 0; /* never remove clues in adjacent mode. */
+        if (state->mode == MODE_ADJACENT)
+            return false; /* never remove clues in adjacent mode. */
 
-        if (!(state->flags[loc] & adjthan[which].f)) return 0;
+        if (!(state->flags[loc] & adjthan[which].f)) return false;
         if (!checkonly) {
 #ifdef STANDALONE_SOLVER
             if (solver_show_working)
@@ -948,7 +960,7 @@
             state->flags[loc] &= ~adjthan[which].f;
         }
     }
-    return 1;
+    return true;
 }
 
 static int gg_best_clue(game_state *state, int *scratch, digit *latin)
@@ -965,7 +977,7 @@
 #endif
 
     for (i = ls; i-- > 0 ;) {
-        if (!gg_place_clue(state, scratch[i], latin, 1)) continue;
+        if (!gg_place_clue(state, scratch[i], latin, true)) continue;
 
         loc = scratch[i] / 5;
         for (j = nposs = 0; j < state->order; j++) {
@@ -1026,8 +1038,8 @@
         if (solver_state(copy, difficulty) == 1) break;
 
         best = gg_best_clue(copy, scratch, latin);
-        gg_place_clue(new, scratch[best], latin, 0);
-        gg_place_clue(copy, scratch[best], latin, 0);
+        gg_place_clue(new, scratch[best], latin, false);
+        gg_place_clue(copy, scratch[best], latin, false);
     }
     free_game(copy);
 #ifdef STANDALONE_SOLVER
@@ -1044,12 +1056,12 @@
                        int difficulty)
 {
     int o = new->order, o2 = o*o, lscratch = o2*5, i;
-    game_state *copy = blank_game(new->order, new->adjacent);
+    game_state *copy = blank_game(new->order, new->mode);
 
     /* For each symbol (if it exists in new), try and remove it and
      * solve again; if we couldn't solve without it put it back. */
     for (i = 0; i < lscratch; i++) {
-        if (!gg_remove_clue(new, scratch[i], 0)) continue;
+        if (!gg_remove_clue(new, scratch[i], false)) continue;
 
         memcpy(copy->nums,  new->nums,  o2 * sizeof(digit));
         memcpy(copy->flags, new->flags, o2 * sizeof(unsigned int));
@@ -1056,8 +1068,8 @@
         gg_solved++;
         if (solver_state(copy, difficulty) != 1) {
             /* put clue back, we can't solve without it. */
-            int ret = gg_place_clue(new, scratch[i], latin, 0);
-            assert(ret == 1);
+            bool ret = gg_place_clue(new, scratch[i], latin, false);
+            assert(ret);
         } else {
 #ifdef STANDALONE_SOLVER
             if (solver_show_working)
@@ -1108,7 +1120,7 @@
     int o2 = params->order * params->order, ntries = 1;
     int *scratch, lscratch = o2*5;
     char *ret, buf[80];
-    game_state *state = blank_game(params->order, params->adjacent);
+    game_state *state = blank_game(params->order, params->mode);
 
     /* Generate a list of 'things to strip' (randomised later) */
     scratch = snewn(lscratch, int);
@@ -1131,7 +1143,7 @@
     memset(state->nums, 0, o2 * sizeof(digit));
     memset(state->flags, 0, o2 * sizeof(unsigned int));
 
-    if (state->adjacent) {
+    if (state->mode == MODE_ADJACENT) {
         /* All adjacency flags are always present. */
         add_adjacent_flags(state, sq);
     }
@@ -1197,7 +1209,7 @@
 static game_state *load_game(const game_params *params, const char *desc,
                              const char **why_r)
 {
-    game_state *state = blank_game(params->order, params->adjacent);
+    game_state *state = blank_game(params->order, params->mode);
     const char *p = desc;
     int i = 0, n, o = params->order, x, y;
     const char *why = NULL;
@@ -1254,7 +1266,7 @@
                     if (nx < 0 || ny < 0 || nx >= o || ny >= o) {
                         why = "Flags go off grid"; goto fail;
                     }
-                    if (params->adjacent) {
+                    if (params->mode == MODE_ADJACENT) {
                         /* if one cell is adjacent to another, the other must
                          * also be adjacent to the first. */
                         if (!(GRID(state, flags, nx, ny) & adjthan[n].fo)) {
@@ -1348,7 +1360,7 @@
 
 struct game_ui {
     int hx, hy;                         /* as for solo.c, highlight pos */
-    int hshow, hpencil, hcursor;        /* show state, type, and ?cursor. */
+    bool hshow, hpencil, hcursor;       /* show state, type, and ?cursor. */
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1356,7 +1368,9 @@
     game_ui *ui = snew(game_ui);
 
     ui->hx = ui->hy = 0;
-    ui->hpencil = ui->hshow = ui->hcursor = 0;
+    ui->hpencil = false;
+    ui->hshow = false;
+    ui->hcursor = false;
 
     return ui;
 }
@@ -1383,18 +1397,21 @@
      * pencil mode. */
     if (ui->hshow && ui->hpencil && !ui->hcursor &&
         GRID(newstate, nums, ui->hx, ui->hy) != 0) {
-        ui->hshow = 0;
+        ui->hshow = false;
     }
 }
 
 struct game_drawstate {
-    int tilesize, order, started, adjacent;
+    int tilesize, order;
+    bool started;
+    Mode mode;
     digit *nums;                /* copy of nums, o^2 */
     unsigned char *hints;       /* copy of hints, o^3 */
     unsigned int *flags;        /* o^2 */
 
-    int hx, hy, hshow, hpencil; /* as for game_ui. */
-    int hflash;
+    int hx, hy;
+    bool hshow, hpencil;        /* as for game_ui. */
+    bool hflash;
 };
 
 static char *interpret_move(const game_state *state, game_ui *ui,
@@ -1403,7 +1420,7 @@
 {
     int x = FROMCOORD(ox), y = FROMCOORD(oy), n;
     char buf[80];
-    int shift_or_control = button & (MOD_SHFT | MOD_CTRL);
+    bool shift_or_control = button & (MOD_SHFT | MOD_CTRL);
 
     button &= ~MOD_MASK;
 
@@ -1432,29 +1449,29 @@
         if (button == LEFT_BUTTON) {
             /* normal highlighting for non-immutable squares */
             if (GRID(state, flags, x, y) & F_IMMUTABLE)
-                ui->hshow = 0;
+                ui->hshow = false;
             else if (x == ui->hx && y == ui->hy &&
-                     ui->hshow && ui->hpencil == 0)
-                ui->hshow = 0;
+                     ui->hshow && !ui->hpencil)
+                ui->hshow = false;
             else {
-                ui->hx = x; ui->hy = y; ui->hpencil = 0;
-                ui->hshow = 1;
+                ui->hx = x; ui->hy = y; ui->hpencil = false;
+                ui->hshow = true;
             }
-            ui->hcursor = 0;
+            ui->hcursor = false;
             return UI_UPDATE;
         }
         if (button == RIGHT_BUTTON) {
             /* pencil highlighting for non-filled squares */
             if (GRID(state, nums, x, y) != 0)
-                ui->hshow = 0;
+                ui->hshow = false;
             else if (x == ui->hx && y == ui->hy &&
                      ui->hshow && ui->hpencil)
-                ui->hshow = 0;
+                ui->hshow = false;
             else {
-                ui->hx = x; ui->hy = y; ui->hpencil = 1;
-                ui->hshow = 1;
+                ui->hx = x; ui->hy = y; ui->hpencil = true;
+                ui->hshow = true;
             }
-            ui->hcursor = 0;
+            ui->hcursor = false;
             return UI_UPDATE;
         }
     }
@@ -1461,9 +1478,11 @@
 
     if (IS_CURSOR_MOVE(button)) {
 	if (shift_or_control) {
-	    int nx = ui->hx, ny = ui->hy, i, self;
+	    int nx = ui->hx, ny = ui->hy, i;
+            bool self;
 	    move_cursor(button, &nx, &ny, ds->order, ds->order, false);
-	    ui->hshow = ui->hcursor = 1;
+	    ui->hshow = true;
+            ui->hcursor = true;
 
 	    for (i = 0; i < 4 && (nx != ui->hx + adjthan[i].dx ||
 				  ny != ui->hy + adjthan[i].dy); ++i);
@@ -1476,7 +1495,7 @@
 		  GRID(state, flags, nx,     ny    ) & adjthan[i].fo))
 		return UI_UPDATE; /* no clue to toggle */
 
-	    if (state->adjacent)
+	    if (state->mode == MODE_ADJACENT)
 		self = (adjthan[i].dx >= 0 && adjthan[i].dy >= 0);
 	    else
 		self = (GRID(state, flags, ui->hx, ui->hy) & adjthan[i].f);
@@ -1491,13 +1510,14 @@
 	    return dupstr(buf);
 	} else {
 	    move_cursor(button, &ui->hx, &ui->hy, ds->order, ds->order, false);
-	    ui->hshow = ui->hcursor = 1;
+	    ui->hshow = true;
+            ui->hcursor = true;
 	    return UI_UPDATE;
 	}
     }
     if (ui->hshow && IS_CURSOR_SELECT(button)) {
-        ui->hpencil = 1 - ui->hpencil;
-        ui->hcursor = 1;
+        ui->hpencil = !ui->hpencil;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
 
@@ -1519,7 +1539,7 @@
         sprintf(buf, "%c%d,%d,%d",
                 (char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
 
-        if (!ui->hcursor) ui->hshow = 0;
+        if (!ui->hcursor) ui->hshow = false;
 
         return dupstr(buf);
     }
@@ -1552,7 +1572,7 @@
                 HINT(ret, x, y, i) = 0;
 
             /* real change to grid; check for completion */
-            if (!ret->completed && check_complete(ret->nums, ret, 1) > 0)
+            if (!ret->completed && check_complete(ret->nums, ret, true) > 0)
                 ret->completed = true;
         }
         return ret;
@@ -1571,7 +1591,7 @@
             p++;
         }
         if (*p) goto badmove;
-        rc = check_complete(ret->nums, ret, 1);
+        rc = check_complete(ret->nums, ret, true);
 	assert(rc > 0);
         return ret;
     } else if (move[0] == 'M') {
@@ -1586,7 +1606,7 @@
         return ret;
     } else if (move[0] == 'H') {
         ret = solver_hint(state, NULL, DIFF_EASY, DIFF_EASY);
-        check_complete(ret->nums, ret, 1);
+        check_complete(ret->nums, ret, true);
         return ret;
     } else if (move[0] == 'F' && sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 &&
 	       x >= 0 && x < state->order && y >= 0 && y < state->order) {
@@ -1659,7 +1679,7 @@
 
     ds->tilesize = 0;
     ds->order = state->order;
-    ds->adjacent = state->adjacent;
+    ds->mode = state->mode;
 
     ds->nums = snewn(o2, digit);
     ds->hints = snewn(o3, unsigned char);
@@ -1669,7 +1689,10 @@
     memset(ds->flags, 0, o2*sizeof(unsigned int));
 
     ds->hx = ds->hy = 0;
-    ds->started = ds->hshow = ds->hpencil = ds->hflash = 0;
+    ds->started = false;
+    ds->hshow = false;
+    ds->hpencil = false;
+    ds->hflash = false;
 
     return ds;
 }
@@ -1771,9 +1794,10 @@
 
 static void draw_furniture(drawing *dr, game_drawstate *ds,
                            const game_state *state, const game_ui *ui,
-                           int x, int y, int hflash)
+                           int x, int y, bool hflash)
 {
-    int ox = COORD(x), oy = COORD(y), bg, hon;
+    int ox = COORD(x), oy = COORD(y), bg;
+    bool hon;
     unsigned int f = GRID(state, flags, x, y);
 
     bg = hflash ? COL_HIGHLIGHT : COL_BACKGROUND;
@@ -1802,7 +1826,7 @@
     draw_update(dr, ox, oy, TILE_SIZE, TILE_SIZE);
 
     /* Draw the adjacent clue signs. */
-    if (ds->adjacent)
+    if (ds->mode == MODE_ADJACENT)
         draw_adjs(dr, ds, ox, oy, f, COL_BACKGROUND, COL_GRID);
     else
         draw_gts(dr, ds, ox, oy, f, COL_BACKGROUND, COL_TEXT);
@@ -1866,13 +1890,14 @@
                         int dir, const game_ui *ui,
                         float animtime, float flashtime)
 {
-    int x, y, i, hchanged = 0, stale, hflash = 0;
+    int x, y, i;
+    bool hchanged = false, stale, hflash = false;
 
     debug(("highlight old (%d,%d), new (%d,%d)", ds->hx, ds->hy, ui->hx, ui->hy));
 
     if (flashtime > 0 &&
         (flashtime <= FLASH_TIME/3 || flashtime >= FLASH_TIME*2/3))
-         hflash = 1;
+         hflash = true;
 
     if (!ds->started) {
         draw_rect(dr, 0, 0, DRAW_SIZE, DRAW_SIZE, COL_BACKGROUND);
@@ -1880,30 +1905,30 @@
     }
     if (ds->hx != ui->hx || ds->hy != ui->hy ||
         ds->hshow != ui->hshow || ds->hpencil != ui->hpencil)
-        hchanged = 1;
+        hchanged = true;
 
     for (x = 0; x < ds->order; x++) {
         for (y = 0; y < ds->order; y++) {
             if (!ds->started)
-                stale = 1;
+                stale = true;
             else if (hflash != ds->hflash)
-                stale = 1;
+                stale = true;
             else
-                stale = 0;
+                stale = false;
 
             if (hchanged) {
                 if ((x == ui->hx && y == ui->hy) ||
                     (x == ds->hx && y == ds->hy))
-                    stale = 1;
+                    stale = true;
             }
 
             if (GRID(state, nums, x, y) != GRID(ds, nums, x, y)) {
                 GRID(ds, nums, x, y) = GRID(state, nums, x, y);
-                stale = 1;
+                stale = true;
             }
             if (GRID(state, flags, x, y) != GRID(ds, flags, x, y)) {
                 GRID(ds, flags, x, y) = GRID(state, flags, x, y);
-                stale = 1;
+                stale = true;
             }
             if (GRID(ds, nums, x, y) == 0) {
                 /* We're not a number square (therefore we might
@@ -1911,7 +1936,7 @@
                 for (i = 0; i < ds->order; i++) {
                     if (HINT(state, x, y, i) != HINT(ds, x, y, i)) {
                         HINT(ds, x, y, i) = HINT(state, x, y, i);
-                        stale = 1;
+                        stale = true;
                     }
                 }
             }
@@ -1928,7 +1953,7 @@
     ds->hshow = ui->hshow;
     ds->hpencil = ui->hpencil;
 
-    ds->started = 1;
+    ds->started = true;
     ds->hflash = hflash;
 }
 
@@ -1993,7 +2018,7 @@
                       FONT_VARIABLE, TILE_SIZE/2, ALIGN_VCENTRE | ALIGN_HCENTRE,
                       ink, str);
 
-            if (state->adjacent)
+            if (state->mode == MODE_ADJACENT)
                 draw_adjs(dr, ds, ox, oy, GRID(state, flags, x, y), -1, ink);
             else
                 draw_gts(dr, ds, ox, oy, GRID(state, flags, x, y), -1, ink);
@@ -2145,7 +2170,7 @@
 
 static void check(game_params *p)
 {
-    const char *msg = validate_params(p, 1);
+    const char *msg = validate_params(p, true);
     if (msg) {
         fprintf(stderr, "%s: %s", quis, msg);
         exit(1);
@@ -2160,7 +2185,7 @@
     check(p);
 
     solver_show_working = debug;
-    desc = new_game_desc(p, rs, &aux, 0);
+    desc = new_game_desc(p, rs, &aux, false);
     diff = solve(p, desc, debug);
     sfree(aux);
     sfree(desc);
@@ -2183,12 +2208,12 @@
     tt_start = tt_now = time(NULL);
 
     printf("Soak-generating an %s %dx%d grid, difficulty %s.\n",
-           p->adjacent ? "adjacent" : "unequal",
+           p->mode == MODE_ADJACENT ? "adjacent" : "unequal",
            p->order, p->order, unequal_diffnames[p->diff]);
 
     while (1) {
         p->diff = realdiff;
-        desc = new_game_desc(p, rs, &aux, 0);
+        desc = new_game_desc(p, rs, &aux, false);
         st = new_game(NULL, p, desc);
         solver_state(st, DIFF_RECURSIVE);
         free_game(st);
--- a/unfinished/group.c
+++ b/unfinished/group.c
@@ -78,15 +78,16 @@
 #define TOCHAR(c,id) (E_FROM_FRONT(c,id) + ('a'-1))
 
 struct game_params {
-    int w, diff, id;
+    int w, diff;
+    bool id;
 };
 
 struct game_state {
     game_params par;
     digit *grid;
-    unsigned char *immutable;
+    bool *immutable;
     int *pencil;		       /* bitmaps using bits 1<<1..1<<n */
-    int completed, cheated;
+    bool completed, cheated;
     digit *sequence;                   /* sequence of group elements shown */
 
     /*
@@ -849,11 +850,11 @@
 
     state->par = *params;	       /* structure copy */
     state->grid = snewn(a, digit);
-    state->immutable = snewn(a, unsigned char);
+    state->immutable = snewn(a, bool);
     state->pencil = snewn(a, int);
     for (i = 0; i < a; i++) {
 	state->grid[i] = 0;
-	state->immutable[i] = 0;
+	state->immutable[i] = false;
 	state->pencil[i] = 0;
     }
     state->sequence = snewn(w, digit);
@@ -868,7 +869,8 @@
 	if (state->grid[i] != 0)
 	    state->immutable[i] = true;
 
-    state->completed = state->cheated = false;
+    state->completed = false;
+    state->cheated = false;
 
     return state;
 }
@@ -881,12 +883,12 @@
     ret->par = state->par;	       /* structure copy */
 
     ret->grid = snewn(a, digit);
-    ret->immutable = snewn(a, unsigned char);
+    ret->immutable = snewn(a, bool);
     ret->pencil = snewn(a, int);
     ret->sequence = snewn(w, digit);
     ret->dividers = snewn(w, int);
     memcpy(ret->grid, state->grid, a*sizeof(digit));
-    memcpy(ret->immutable, state->immutable, a*sizeof(unsigned char));
+    memcpy(ret->immutable, state->immutable, a*sizeof(bool));
     memcpy(ret->pencil, state->pencil, a*sizeof(int));
     memcpy(ret->sequence, state->sequence, w*sizeof(digit));
     memcpy(ret->dividers, state->dividers, w*sizeof(int));
@@ -1001,7 +1003,7 @@
      * This indicates whether the current highlight is a
      * pencil-mark one or a real one.
      */
-    int hpencil;
+    bool hpencil;
     /*
      * This indicates whether or not we're showing the highlight
      * (used to be hx = hy = -1); important so that when we're
@@ -1009,13 +1011,13 @@
      * fixed position. When hshow = 1, pressing a valid number
      * or letter key or Space will enter that number or letter in the grid.
      */
-    int hshow;
+    bool hshow;
     /*
      * This indicates whether we're using the highlight as a cursor;
      * it means that it doesn't vanish on a keypress, and that it is
      * allowed on immutable squares.
      */
-    int hcursor;
+    bool hcursor;
     /*
      * This indicates whether we're dragging a table header to
      * reposition an entire row or column.
@@ -1031,7 +1033,9 @@
     game_ui *ui = snew(game_ui);
 
     ui->hx = ui->hy = 0;
-    ui->hpencil = ui->hshow = ui->hcursor = 0;
+    ui->hpencil = false;
+    ui->hshow = false;
+    ui->hcursor = false;
     ui->drag = 0;
 
     return ui;
@@ -1063,7 +1067,7 @@
      */
     if (ui->hshow && ui->hpencil && !ui->hcursor &&
         newstate->grid[ui->hy * w + ui->hx] != 0) {
-        ui->hshow = 0;
+        ui->hshow = false;
     }
     if (ui->hshow && ui->odn > 1) {
         /*
@@ -1075,12 +1079,12 @@
         for (i = 0; i < ui->odn; i++) {
             if (oldstate->sequence[ui->ohx + i*ui->odx] !=
                 newstate->sequence[ui->ohx + i*ui->odx]) {
-                ui->hshow = 0;
+                ui->hshow = false;
                 break;
             }
             if (oldstate->sequence[ui->ohy + i*ui->ody] !=
                 newstate->sequence[ui->ohy + i*ui->ody]) {
-                ui->hshow = 0;
+                ui->hshow = false;
                 break;
             }
         }
@@ -1132,17 +1136,18 @@
 struct game_drawstate {
     game_params par;
     int w, tilesize;
-    int started;
+    bool started;
     long *tiles, *legend, *pencil, *errors;
     long *errtmp;
     digit *sequence;
 };
 
-static int check_errors(const game_state *state, long *errors)
+static bool check_errors(const game_state *state, long *errors)
 {
     int w = state->par.w, a = w*w;
     digit *grid = state->grid;
-    int i, j, k, x, y, errs = false;
+    int i, j, k, x, y;
+    bool errs = false;
 
     /*
      * To verify that we have a valid group table, it suffices to
@@ -1304,8 +1309,8 @@
             ty = state->sequence[ty];
             if (button == LEFT_BUTTON) {
                 if (tx == ui->hx && ty == ui->hy &&
-                    ui->hshow && ui->hpencil == 0) {
-                    ui->hshow = 0;
+                    ui->hshow && !ui->hpencil) {
+                    ui->hshow = false;
                 } else {
                     ui->hx = tx;
                     ui->hy = ty;
@@ -1314,9 +1319,9 @@
                     ui->odx = ui->ody = 0;
                     ui->odn = 1;
                     ui->hshow = !state->immutable[ty*w+tx];
-                    ui->hpencil = 0;
+                    ui->hpencil = false;
                 }
-                ui->hcursor = 0;
+                ui->hcursor = false;
                 return UI_UPDATE;
             }
             if (button == RIGHT_BUTTON) {
@@ -1326,9 +1331,9 @@
                 if (state->grid[ty*w+tx] == 0) {
                     if (tx == ui->hx && ty == ui->hy &&
                         ui->hshow && ui->hpencil) {
-                        ui->hshow = 0;
+                        ui->hshow = false;
                     } else {
-                        ui->hpencil = 1;
+                        ui->hpencil = true;
                         ui->hx = tx;
                         ui->hy = ty;
                         ui->ohx = otx;
@@ -1335,12 +1340,12 @@
                         ui->ohy = oty;
                         ui->odx = ui->ody = 0;
                         ui->odn = 1;
-                        ui->hshow = 1;
+                        ui->hshow = true;
                     }
                 } else {
-                    ui->hshow = 0;
+                    ui->hshow = false;
                 }
-                ui->hcursor = 0;
+                ui->hcursor = false;
                 return UI_UPDATE;
             }
         } else if (tx >= 0 && tx < w && ty == -1) {
@@ -1373,16 +1378,17 @@
     if (IS_CURSOR_MOVE(button)) {
         int cx = find_in_sequence(state->sequence, w, ui->hx);
         int cy = find_in_sequence(state->sequence, w, ui->hy);
-        move_cursor(button, &cx, &cy, w, w, 0);
+        move_cursor(button, &cx, &cy, w, w, false);
         ui->hx = state->sequence[cx];
         ui->hy = state->sequence[cy];
-        ui->hshow = ui->hcursor = 1;
+        ui->hshow = true;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
     if (ui->hshow &&
         (button == CURSOR_SELECT)) {
-        ui->hpencil = 1 - ui->hpencil;
-        ui->hcursor = 1;
+        ui->hpencil = !ui->hpencil;
+        ui->hcursor = true;
         return UI_UPDATE;
     }
 
@@ -1433,7 +1439,7 @@
         }
         movebuf = sresize(movebuf, buflen+1, char);
 
-        if (!ui->hcursor) ui->hshow = 0;
+        if (!ui->hcursor) ui->hshow = false;
 
 	return movebuf;
     }
@@ -1473,7 +1479,7 @@
                sscanf(move+1, "%d,%d,%d%n", &x, &y, &n, &pos) == 3 &&
                n >= 0 && n <= w) {
         const char *mp = move + 1 + pos;
-        int pencil = (move[0] == 'P');
+        bool pencil = (move[0] == 'P');
         ret = dup_game(from);
 
         while (1) {
@@ -1902,7 +1908,7 @@
                 tile |= DF_HIGHLIGHT;
             } else if (ui->hshow) {
                 int i = abs(x - ui->ohx);
-                int highlight = 0;
+                bool highlight = false;
                 if (ui->odn > 1) {
                     /*
                      * When a diagonal multifill selection is shown,
@@ -1913,7 +1919,7 @@
                     if (i >= 0 && i < ui->odn &&
                         x == ui->ohx + i*ui->odx &&
                         y == ui->ohy + i*ui->ody)
-                        highlight = 1;
+                        highlight = true;
                 } else {
                     /*
                      * For a single square, we move its highlight
@@ -2110,8 +2116,9 @@
     char *id = NULL, *desc;
     const char *err;
     digit *grid;
-    int grade = false;
-    int ret, diff, really_show_working = false;
+    bool grade = false;
+    int ret, diff;
+    bool really_show_working = false;
 
     while (--argc > 0) {
         char *p = *++argv;
@@ -2156,7 +2163,7 @@
      * the puzzle internally before doing anything else.
      */
     ret = -1;			       /* placate optimiser */
-    solver_show_working = false;
+    solver_show_working = 0;
     for (diff = 0; diff < DIFFCOUNT; diff++) {
 	memcpy(grid, s->grid, p->w * p->w);
 	ret = solver(&s->par, grid, diff);
--- a/unfinished/separate.c
+++ b/unfinished/separate.c
@@ -207,7 +207,7 @@
      * tracks whether or not the connected components containing
      * yx1 and yx2 are known to be distinct.
      */
-    unsigned char *disconnect;
+    bool *disconnect;
 
     /*
      * Temporary space used only inside particular solver loops.
@@ -227,7 +227,7 @@
     sc->dsf = snew_dsf(wh);
     sc->size = snewn(wh, int);
     sc->contents = snewn(wh * k, int);
-    sc->disconnect = snewn(wh*wh, unsigned char);
+    sc->disconnect = snewn(wh*wh, bool);
     sc->tmp = snewn(wh, int);
 
     return sc;
@@ -312,7 +312,8 @@
      * Mark the components as disconnected from each other in the
      * disconnect matrix.
      */
-    sc->disconnect[yx1*wh+yx2] = sc->disconnect[yx2*wh+yx1] = 1;
+    sc->disconnect[yx1*wh+yx2] = true;
+    sc->disconnect[yx2*wh+yx1] = true;
 }
 
 void solver_init(struct solver_scratch *sc)
@@ -328,16 +329,16 @@
      */
     dsf_init(sc->dsf, wh);
     for (i = 0; i < wh; i++) sc->size[i] = 1;
-    memset(sc->disconnect, 0, wh*wh);
+    memset(sc->disconnect, 0, wh*wh * sizeof(bool));
 }
 
 int solver_attempt(struct solver_scratch *sc, const unsigned char *grid,
-		   unsigned char *gen_lock)
+		   bool *gen_lock)
 {
     int w = sc->w, h = sc->h, k = sc->k;
     int wh = w*h;
     int i, x, y;
-    int done_something_overall = false;
+    bool done_something_overall = false;
 
     /*
      * Set up the contents array from the grid.
@@ -348,7 +349,7 @@
 	sc->contents[dsf_canonify(sc->dsf, i)*k+grid[i]] = i;
 
     while (1) {
-	int done_something = false;
+	bool done_something = false;
 
 	/*
 	 * Go over the grid looking for reasons to add to the
@@ -406,8 +407,8 @@
 		     * based deductions.
 		     */
 		    if (gen_lock) {
-			gen_lock[sc->contents[yx*k+i]] = 1;
-			gen_lock[sc->contents[yx2*k+i]] = 1;
+			gen_lock[sc->contents[yx*k+i]] = true;
+			gen_lock[sc->contents[yx2*k+i]] = true;
 		    }
 		}
 	    }
@@ -500,7 +501,7 @@
     unsigned char *shuffled;
     int i, j, m, retries;
     int *permutation;
-    unsigned char *gen_lock;
+    bool *gen_lock;
     extern int *divvy_rectangle(int w, int h, int k, random_state *rs);
 
     sc = solver_scratch_new(w, h, k);
@@ -507,7 +508,7 @@
     grid = snewn(wh, unsigned char);
     shuffled = snewn(k, unsigned char);
     permutation = snewn(wh, int);
-    gen_lock = snewn(wh, unsigned char);
+    gen_lock = snewn(wh, bool);
 
     do {
 	int *dsf = divvy_rectangle(w, h, k, rs);
@@ -547,7 +548,7 @@
 	 * on for deductions. This is gradually updated by
 	 * solver_attempt().
 	 */
-	memset(gen_lock, 0, wh);
+	memset(gen_lock, 0, wh * sizeof(bool));
 
 	/*
 	 * Now repeatedly fill the grid with letters, and attempt
--- a/unfinished/slide.c
+++ b/unfinished/slide.c
@@ -128,7 +128,7 @@
 
 struct game_immutable_state {
     int refcount;
-    unsigned char *forcefield;
+    bool *forcefield;
 };
 
 struct game_solution {
@@ -145,7 +145,7 @@
     int lastmoved, lastmoved_pos;      /* for move counting */
     int movecount;
     int completed;
-    int cheated;
+    bool cheated;
     struct game_immutable_state *imm;
     struct game_solution *soln;
     int soln_index;
@@ -287,7 +287,7 @@
 }
 
 static char *board_text_format(int w, int h, unsigned char *data,
-			       unsigned char *forcefield)
+			       bool *forcefield)
 {
     int wh = w*h;
     int *dsf = snew_dsf(wh);
@@ -406,13 +406,14 @@
  * which is a pointer to a dynamically allocated array.
  */
 static int solve_board(int w, int h, unsigned char *board,
-		       unsigned char *forcefield, int tx, int ty,
+		       bool *forcefield, int tx, int ty,
 		       int movelimit, int **moveout)
 {
     int wh = w*h;
     struct board *b, *b2, *b3;
-    int *next, *anchors, *which;
-    int *movereached, *movequeue, mqhead, mqtail;
+    int *next, *which;
+    bool *anchors, *movereached;
+    int *movequeue, mqhead, mqtail;
     tree234 *sorted, *queue;
     int i, j, dir;
     int qlen, lastdist;
@@ -453,9 +454,9 @@
     qlen = 1;
 
     next = snewn(wh, int);
-    anchors = snewn(wh, int);
+    anchors = snewn(wh, bool);
     which = snewn(wh, int);
-    movereached = snewn(wh, int);
+    movereached = snewn(wh, bool);
     movequeue = snewn(wh, int);
     lastdist = -1;
 
@@ -637,11 +638,12 @@
 
 static void generate_board(int w, int h, int *rtx, int *rty, int *minmoves,
 			   random_state *rs, unsigned char **rboard,
-			   unsigned char **rforcefield, int movelimit)
+			   bool **rforcefield, int movelimit)
 {
     int wh = w*h;
-    unsigned char *board, *board2, *forcefield;
-    unsigned char *tried_merge;
+    unsigned char *board, *board2;
+    bool *forcefield;
+    bool *tried_merge;
     int *dsf;
     int *list, nlist, pos;
     int tx, ty;
@@ -653,17 +655,17 @@
      * border of walls.
      */
     board = snewn(wh, unsigned char);
-    forcefield = snewn(wh, unsigned char);
+    forcefield = snewn(wh, bool);
     board2 = snewn(wh, unsigned char);
     memset(board, ANCHOR, wh);
-    memset(forcefield, false, wh);
+    memset(forcefield, 0, wh * sizeof(bool));
     for (i = 0; i < w; i++)
 	board[i] = board[i+w*(h-1)] = WALL;
     for (i = 0; i < h; i++)
 	board[i*w] = board[i*w+(w-1)] = WALL;
 
-    tried_merge = snewn(wh * wh, unsigned char);
-    memset(tried_merge, 0, wh*wh);
+    tried_merge = snewn(wh * wh, bool);
+    memset(tried_merge, 0, wh*wh * sizeof(bool));
     dsf = snew_dsf(wh);
 
     /*
@@ -680,7 +682,8 @@
      */
     tx = w-2;
     ty = h-3;
-    forcefield[ty*w+tx+1] = forcefield[(ty+1)*w+tx+1] = true;
+    forcefield[ty*w+tx+1] = true;
+    forcefield[(ty+1)*w+tx+1] = true;
     board[ty*w+tx+1] = board[(ty+1)*w+tx+1] = EMPTY;
 
     /*
@@ -799,7 +802,8 @@
 	     * Didn't work. Revert the merge.
 	     */
 	    memcpy(board, board2, wh);
-	    tried_merge[c1 * wh + c2] = tried_merge[c2 * wh + c1] = true;
+	    tried_merge[c1 * wh + c2] = true;
+            tried_merge[c2 * wh + c1] = true;
 	} else {
 	    int c;
 
@@ -808,10 +812,10 @@
 	    dsf_merge(dsf, c1, c2);
 	    c = dsf_canonify(dsf, c1);
 	    for (i = 0; i < wh; i++)
-		tried_merge[c*wh+i] = (tried_merge[c1*wh+i] |
+		tried_merge[c*wh+i] = (tried_merge[c1*wh+i] ||
 				       tried_merge[c2*wh+i]);
 	    for (i = 0; i < wh; i++)
-		tried_merge[i*wh+c] = (tried_merge[i*wh+c1] |
+		tried_merge[i*wh+c] = (tried_merge[i*wh+c1] ||
 				       tried_merge[i*wh+c2]);
 	}
     }
@@ -837,7 +841,8 @@
 {
     int w = params->w, h = params->h, wh = w*h;
     int tx, ty, minmoves;
-    unsigned char *board, *forcefield;
+    unsigned char *board;
+    bool *forcefield;
     char *ret, *p;
     int i;
 
@@ -863,7 +868,8 @@
 	    i++;
 	} else {
 	    int count = 1;
-	    int b = board[i], f = forcefield[i];
+	    int b = board[i];
+            bool f = forcefield[i];
 	    int c = (b == ANCHOR ? 'a' :
 		     b == MAINANCHOR ? 'm' :
 		     b == EMPTY ? 'e' :
@@ -889,12 +895,13 @@
 static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h, wh = w*h;
-    int *active, *link;
+    bool *active;
+    int *link;
     int mains = 0;
     int i, tx, ty, minmoves;
     char *ret;
 
-    active = snewn(wh, int);
+    active = snewn(wh, bool);
     link = snewn(wh, int);
     i = 0;
 
@@ -1011,12 +1018,12 @@
     state->movecount = 0;
     state->imm = snew(struct game_immutable_state);
     state->imm->refcount = 1;
-    state->imm->forcefield = snewn(wh, unsigned char);
+    state->imm->forcefield = snewn(wh, bool);
 
     i = 0;
 
     while (*desc && *desc != ',') {
-	int f = false;
+	bool f = false;
 
 	assert(i < wh);
 
@@ -1176,11 +1183,11 @@
 }
 
 struct game_ui {
-    int dragging;
+    bool dragging;
     int drag_anchor;
     int drag_offset_x, drag_offset_y;
     int drag_currpos;
-    unsigned char *reachable;
+    bool *reachable;
     int *bfs_queue;		       /* used as scratch in interpret_move */
 };
 
@@ -1192,8 +1199,8 @@
     ui->dragging = false;
     ui->drag_anchor = ui->drag_currpos = -1;
     ui->drag_offset_x = ui->drag_offset_y = -1;
-    ui->reachable = snewn(wh, unsigned char);
-    memset(ui->reachable, 0, wh);
+    ui->reachable = snewn(wh, bool);
+    memset(ui->reachable, 0, wh * sizeof(bool));
     ui->bfs_queue = snewn(wh, int);
 
     return ui;
@@ -1235,7 +1242,7 @@
     int tilesize;
     int w, h;
     unsigned long *grid;	       /* what's currently displayed */
-    int started;
+    bool started;
 };
 
 static char *interpret_move(const game_state *state, game_ui *ui,
@@ -1274,7 +1281,7 @@
 	 * the anchor, to find all the places to which this block
 	 * can be dragged.
 	 */
-	memset(ui->reachable, false, wh);
+	memset(ui->reachable, 0, wh * sizeof(bool));
 	qhead = qtail = 0;
 	ui->reachable[i] = true;
 	ui->bfs_queue[qtail++] = i;
@@ -1393,7 +1400,7 @@
 	ui->dragging = false;
 	ui->drag_anchor = ui->drag_currpos = -1;
 	ui->drag_offset_x = ui->drag_offset_y = -1;
-	memset(ui->reachable, 0, wh);
+	memset(ui->reachable, 0, wh * sizeof(bool));
 
 	return str;
     } else if (button == ' ' && state->soln) {
@@ -1415,8 +1422,8 @@
     return NULL;
 }
 
-static int move_piece(int w, int h, const unsigned char *src,
-		      unsigned char *dst, unsigned char *ff, int from, int to)
+static bool move_piece(int w, int h, const unsigned char *src,
+                       unsigned char *dst, bool *ff, int from, int to)
 {
     int wh = w*h;
     int i, j;
@@ -2141,9 +2148,9 @@
     board = snewn(wh, unsigned char);
     memcpy(board, state->board, wh);
     if (ui->dragging) {
-	int mpret = move_piece(w, h, state->board, board,
-			       state->imm->forcefield,
-			       ui->drag_anchor, ui->drag_currpos);
+	bool mpret = move_piece(w, h, state->board, board,
+                                state->imm->forcefield,
+                                ui->drag_anchor, ui->drag_currpos);
 	assert(mpret);
     }
 
@@ -2359,8 +2366,9 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
-    int count = false;
+    char *id = NULL, *desc;
+    const char *err;
+    bool count = false;
     int ret;
     int *moves;
 
@@ -2413,7 +2421,7 @@
 	    return 0;
 	}
 	while (1) {
-	    int moveret;
+	    bool moveret;
 	    char *text = board_text_format(s->w, s->h, s->board,
 					   s->imm->forcefield);
 	    game_state *s2;
--- a/unfinished/sokoban.c
+++ b/unfinished/sokoban.c
@@ -131,7 +131,7 @@
     game_params p;
     unsigned char *grid;
     int px, py;
-    int completed;
+    bool completed;
 };
 
 static game_params *default_params(void)
@@ -300,7 +300,7 @@
  */
 
 static void sokoban_generate(int w, int h, unsigned char *grid, int moves,
-			     int nethack, random_state *rs)
+			     bool nethack, random_state *rs)
 {
     struct pull {
 	int ox, oy, nx, ny, score;
@@ -940,7 +940,7 @@
 struct game_drawstate {
     game_params p;
     int tilesize;
-    int started;
+    bool started;
     unsigned short *grid;
 };
 
@@ -1099,7 +1099,8 @@
 {
     int w = state->p.w, h = state->p.h;
     int px = state->px, py = state->py;
-    int dx, dy, nx, ny, nbx, nby, type, m, i, freebarrels, freetargets;
+    int dx, dy, nx, ny, nbx, nby, type, m, i;
+    bool freebarrels, freetargets;
     game_state *ret;
 
     if (*move < '1' || *move == '5' || *move > '9' || move[1])
--- a/unruly.c
+++ b/unruly.c
@@ -52,7 +52,7 @@
 #include "puzzles.h"
 
 #ifdef STANDALONE_SOLVER
-int solver_verbose = false;
+bool solver_verbose = false;
 #endif
 
 enum {
@@ -77,7 +77,7 @@
 
 struct game_params {
     int w2, h2;        /* full grid width and height respectively */
-    int unique;        /* should row and column patterns be unique? */
+    bool unique;       /* should row and column patterns be unique? */
     int diff;
 };
 #define DIFFLIST(A)                             \
@@ -135,11 +135,11 @@
 
 struct game_state {
     int w2, h2;
-    int unique;
+    bool unique;
     char *grid;
-    unsigned char *immutable;
+    bool *immutable;
 
-    int completed, cheated;
+    bool completed, cheated;
 };
 
 static game_params *default_params(void)
@@ -344,7 +344,7 @@
     return NULL;
 }
 
-static game_state *blank_state(int w2, int h2, int unique)
+static game_state *blank_state(int w2, int h2, bool unique)
 {
     game_state *state = snew(game_state);
     int s = w2 * h2;
@@ -353,10 +353,10 @@
     state->h2 = h2;
     state->unique = unique;
     state->grid = snewn(s, char);
-    state->immutable = snewn(s, unsigned char);
+    state->immutable = snewn(s, bool);
 
     memset(state->grid, EMPTY, s);
-    memset(state->immutable, false, s);
+    memset(state->immutable, 0, s*sizeof(bool));
 
     state->completed = state->cheated = false;
 
@@ -409,7 +409,7 @@
     game_state *ret = blank_state(w2, h2, state->unique);
 
     memcpy(ret->grid, state->grid, s);
-    memcpy(ret->immutable, state->immutable, s);
+    memcpy(ret->immutable, state->immutable, s*sizeof(bool));
 
     ret->completed = state->completed;
     ret->cheated = state->cheated;
@@ -517,7 +517,7 @@
 }
 
 static int unruly_solver_check_threes(game_state *state, int *rowcount,
-                                      int *colcount, int horizontal,
+                                      int *colcount, bool horizontal,
                                       char check, char block)
 {
     int w2 = state->w2, h2 = state->h2;
@@ -610,7 +610,7 @@
 }
 
 static int unruly_solver_check_uniques(game_state *state, int *rowcount,
-                                       int horizontal, char check, char block,
+                                       bool horizontal, char check, char block,
                                        struct unruly_scratch *scratch)
 {
     int w2 = state->w2, h2 = state->h2;
@@ -691,7 +691,7 @@
     return ret;
 }
 
-static int unruly_solver_fill_row(game_state *state, int i, int horizontal,
+static int unruly_solver_fill_row(game_state *state, int i, bool horizontal,
                                   int *rowcount, int *colcount, char fill)
 {
     int ret = 0;
@@ -733,7 +733,7 @@
 }
 
 static int unruly_solver_check_complete_nums(game_state *state,
-                                             int *complete, int horizontal,
+                                             int *complete, bool horizontal,
                                              int *rowcount, int *colcount,
                                              char fill)
 {
@@ -788,7 +788,7 @@
 }
 
 static int unruly_solver_check_near_complete(game_state *state,
-                                             int *complete, int horizontal,
+                                             int *complete, bool horizontal,
                                              int *rowcount, int *colcount,
                                              char fill)
 {
@@ -947,7 +947,7 @@
     return ret;
 }
 
-static int unruly_validate_rows(const game_state *state, int horizontal,
+static int unruly_validate_rows(const game_state *state, bool horizontal,
                                 char check, int *errors)
 {
     int w2 = state->w2, h2 = state->h2;
@@ -987,7 +987,7 @@
     return ret;
 }
 
-static int unruly_validate_unique(const game_state *state, int horizontal,
+static int unruly_validate_unique(const game_state *state, bool horizontal,
                                   int *errors)
 {
     int w2 = state->w2, h2 = state->h2;
@@ -1011,7 +1011,7 @@
         if (nfull != nc)
             continue;
         for (r2 = r+1; r2 < nr; r2++) {
-            int match = true;
+            bool match = true;
             for (c = 0; c < nc; c++)
                 if (state->grid[r*rmult + c*cmult] !=
                     state->grid[r2*rmult + c*cmult])
@@ -1051,12 +1051,12 @@
 }
 
 static int unruly_validate_counts(const game_state *state,
-                                  struct unruly_scratch *scratch, int *errors)
+                                  struct unruly_scratch *scratch, bool *errors)
 {
     int w2 = state->w2, h2 = state->h2;
     int w = w2/2, h = h2/2;
-    char below = false;
-    char above = false;
+    bool below = false;
+    bool above = false;
     int i;
 
     /* See if all rows/columns are satisfied. If one is exceeded,
@@ -1063,7 +1063,7 @@
      * mark it as an error (if required)
      */
 
-    char hasscratch = true;
+    bool hasscratch = true;
     if (!scratch) {
         scratch = unruly_new_scratch(state);
         hasscratch = false;
@@ -1215,8 +1215,8 @@
  * Generator *
  * ********* */
 
-static int unruly_fill_game(game_state *state, struct unruly_scratch *scratch,
-                            random_state *rs)
+static bool unruly_fill_game(game_state *state, struct unruly_scratch *scratch,
+                             random_state *rs)
 {
 
     int w2 = state->w2, h2 = state->h2;
@@ -1273,7 +1273,7 @@
 {
 #ifdef STANDALONE_SOLVER
     char *debug;
-    int temp_verbose = false;
+    bool temp_verbose = false;
 #endif
 
     int w2 = params->w2, h2 = params->h2;
@@ -1361,7 +1361,7 @@
          * See if the game has accidentally come out too easy.
          */
         if (params->diff > 0) {
-            int ok;
+            bool ok;
             game_state *solver;
 
             solver = dup_game(state);
@@ -1369,7 +1369,7 @@
 
             unruly_solve_game(solver, scratch, params->diff - 1);
 
-            ok = unruly_validate_counts(solver, scratch, NULL);
+            ok = unruly_validate_counts(solver, scratch, NULL) > 0;
 
             free_game(solver);
             unruly_free_scratch(scratch);
@@ -1420,7 +1420,7 @@
 
 struct game_ui {
     int cx, cy;
-    char cursor;
+    bool cursor;
 };
 
 static game_ui *new_ui(const game_state *state)
@@ -1455,10 +1455,10 @@
 struct game_drawstate {
     int tilesize;
     int w2, h2;
-    int started;
+    bool started;
 
     int *gridfs;
-    int *rowfs;
+    bool *rowfs;
 
     int *grid;
 };
@@ -1477,7 +1477,7 @@
     ds->started = false;
 
     ds->gridfs = snewn(s, int);
-    ds->rowfs = snewn(2 * (w2 + h2), int);
+    ds->rowfs = snewn(2 * (w2 + h2), bool);
 
     ds->grid = snewn(s, int);
     for (i = 0; i < s; i++)
@@ -1525,7 +1525,7 @@
 
     /* Keyboard move */
     if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->cx, &ui->cy, w2, h2, 0);
+        move_cursor(button, &ui->cx, &ui->cy, w2, h2, false);
         ui->cursor = true;
         return UI_UPDATE;
     }
@@ -1797,7 +1797,7 @@
         ds->gridfs[i] = 0;
     unruly_validate_all_rows(state, ds->gridfs);
     for (i = 0; i < 2 * (h2 + w2); i++)
-        ds->rowfs[i] = 0;
+        ds->rowfs[i] = false;
     unruly_validate_counts(state, NULL, ds->rowfs);
 
     for (y = 0; y < h2; y++) {
--- a/untangle.c
+++ b/untangle.c
@@ -95,7 +95,7 @@
     int *crosses;		       /* mark edges which are crossed */
 #endif
     struct graph *graph;
-    int completed, cheated, just_solved;
+    bool completed, cheated, just_solved;
 };
 
 static int edgecmpC(const void *av, const void *bv)
@@ -298,7 +298,7 @@
  * between b1 and b2, intersect. We count it as an intersection if
  * any of the endpoints lies _on_ the other line.
  */
-static int cross(point a1, point a2, point b1, point b2)
+static bool cross(point a1, point a2, point b1, point b2)
 {
     long b1x, b1y, b2x, b2y, px, py;
     int64 d1, d2, d3;
@@ -420,7 +420,7 @@
     add234(edges, e);
 }
 
-static int isedge(tree234 *edges, int a, int b)
+static bool isedge(tree234 *edges, int a, int b)
 {
     edge e;
 
@@ -540,7 +540,7 @@
     edges = newtree234(edgecmp);
     vlist = snewn(n, vertex);
     while (1) {
-	int added = false;
+        bool added = false;
 
 	for (i = 0; i < n; i++) {
 	    v = index234(vertices, i);
@@ -759,7 +759,7 @@
 
 static void mark_crossings(game_state *state)
 {
-    int ok = true;
+    bool ok = true;
     int i, j;
     edge *e, *e2;
 
@@ -1036,8 +1036,8 @@
 struct game_ui {
     int dragpoint;		       /* point being dragged; -1 if none */
     point newpoint;		       /* where it's been dragged to so far */
-    int just_dragged;		       /* reset in game_changed_state */
-    int just_moved;		       /* _set_ in game_changed_state */
+    bool just_dragged;                 /* reset in game_changed_state */
+    bool just_moved;                   /* _set_ in game_changed_state */
     float anim_length;
 };
 
@@ -1296,7 +1296,8 @@
     int w, h;
     edge *e;
     int i, j;
-    int bg, points_moved;
+    int bg;
+    bool points_moved;
 
     /*
      * There's no terribly sensible way to do partial redraws of
--- a/windows.c
+++ b/windows.c
@@ -61,7 +61,7 @@
 #endif /* NO_HTMLHELP */
 enum { NONE, HLP, CHM } help_type;
 char *help_path;
-int help_has_contents;
+bool help_has_contents;
 
 #ifndef FILENAME_MAX
 #define	FILENAME_MAX	(260)
@@ -229,15 +229,17 @@
     HFONT cfgfont;
     HBRUSH oldbr;
     HPEN oldpen;
-    int help_running;
+    bool help_running;
     enum { DRAWING, PRINTING, NOTHING } drawstatus;
     DOCINFO di;
-    int printcount, printw, printh, printsolns, printcurr, printcolour;
+    int printcount, printw, printh;
+    bool printsolns, printcurr, printcolour;
     float printscale;
     int printoffsetx, printoffsety;
     float printpixelscale;
     int fontstart;
-    int linewidth, linedotted;
+    int linewidth;
+    bool linedotted;
     drawing *dr;
     int xmin, ymin;
     float puzz_scale;
@@ -495,7 +497,7 @@
 	DeleteObject(br);
 }
 
-static void win_set_pen(frontend *fe, int colour, int thin)
+static void win_set_pen(frontend *fe, int colour, bool thin)
 {
     HPEN pen;
     assert(fe->drawstatus != NOTHING);
@@ -1361,12 +1363,12 @@
  * furniture (wx,wy).
  */
 
-static int check_window_resize(frontend *fe, int cx, int cy,
-                               int *px, int *py,
-                               int *wx, int *wy)
+static bool check_window_resize(frontend *fe, int cx, int cy,
+                                int *px, int *py, int *wx, int *wy)
 {
     RECT r;
-    int x, y, sy = get_statusbar_height(fe), changed = 0;
+    int x, y, sy = get_statusbar_height(fe);
+    bool changed = false;
 
     /* disallow making window thinner than menu bar */
     x = max(cx, fe->xmin);
@@ -1388,7 +1390,7 @@
         AdjustWindowRectEx(&r, WINFLAGS, true, 0);
         *wx = r.right - r.left;
         *wy = r.bottom - r.top;
-        changed = 1;
+        changed = true;
     }
 
     *px = x;
@@ -1576,8 +1578,8 @@
  * permissible.
  */
 static midend *midend_for_new_game(frontend *fe, const game *cgame,
-                                   char *arg, int maybe_game_id,
-                                   int maybe_save_file, char **error)
+                                   char *arg, bool maybe_game_id,
+                                   bool maybe_save_file, char **error)
 {
     midend *me = NULL;
 
@@ -2013,7 +2015,7 @@
 	    SetDlgItemTextA(hwnd, IDC_ABOUT_VERSION, ver);
 	}
 #endif
-	return true;
+	return 1;
 
       case WM_COMMAND:
 	if (LOWORD(wParam) == IDOK)
@@ -2270,7 +2272,7 @@
 	    create_config_controls(fe);
 	}
 #endif
-	return true;
+	return 1;
 
       case WM_COMMAND:
 	/*
@@ -2398,7 +2400,7 @@
     hdc = GetDC(fe->hwnd);
     SetMapMode(hdc, MM_TEXT);
 
-    fe->dlg_done = false;
+    fe->dlg_done = 0;
 
     fe->cfgfont = CreateFont(-MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72),
 			     0, 0, 0, 0,
@@ -2513,7 +2515,7 @@
 #endif
 }
 
-static int get_config(frontend *fe, int which)
+static bool get_config(frontend *fe, int which)
 {
 #ifdef _WIN32_WCE
     fe->cfg_which = which;
@@ -2552,7 +2554,7 @@
     hdc = GetDC(fe->hwnd);
     SetMapMode(hdc, MM_TEXT);
 
-    fe->dlg_done = false;
+    fe->dlg_done = 0;
 
     fe->cfgfont = CreateFont(-MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72),
 			     0, 0, 0, 0,
@@ -2691,7 +2693,7 @@
 	    mkctrl(fe, col1l, col2r, y, y+height, "BUTTON",
 		   BS_NOTIFY | BS_AUTOCHECKBOX | WS_TABSTOP,
 		   0, i->name, (j->ctlid = id++));
-	    CheckDlgButton(fe->cfgbox, j->ctlid, (i->u.boolean.bval != 0));
+	    CheckDlgButton(fe->cfgbox, j->ctlid, i->u.boolean.bval);
 	    y += height;
 	    break;
 
@@ -2871,7 +2873,7 @@
  * new window size.
  */
 
-static void adjust_game_size(frontend *fe, RECT *proposed, int isedge,
+static void adjust_game_size(frontend *fe, RECT *proposed, bool isedge,
                              int *wx_r, int *wy_r)
 {
     RECT cr, wr;
@@ -2958,7 +2960,7 @@
     update_copy_menu_greying(fe);
 }
 
-static int is_alt_pressed(void)
+static bool is_alt_pressed(void)
 {
     BYTE keystate[256];
     int r = GetKeyboardState(keystate);
@@ -3432,12 +3434,13 @@
       case WM_SIZING:
         {
             RECT *sr = (RECT *)lParam;
-            int wx, wy, isedge = 0;
+            int wx, wy;
+            bool isedge = false;
 
             if (wParam == WMSZ_TOP ||
                 wParam == WMSZ_RIGHT ||
                 wParam == WMSZ_BOTTOM ||
-                wParam == WMSZ_LEFT) isedge = 1;
+                wParam == WMSZ_LEFT) isedge = true;
             adjust_game_size(fe, sr, isedge, &wx, &wy);
 
             /* Given the window size the puzzles constrain
@@ -3632,7 +3635,7 @@
     p = cmdline; q = outputline; outputargc = 0;
 
     while (*p) {
-	int quote;
+	bool quote;
 
 	/* Skip whitespace searching for start of argument. */
 	while (*p && isspace(*p)) p++;
@@ -3642,7 +3645,7 @@
 	outputargv[outputargc] = q;
 	outputargstart[outputargc] = p;
 	outputargc++;
-	quote = 0;
+	quote = false;
 
 	/* Copy data into the argument until it's finished. */
 	while (*p) {
@@ -3676,7 +3679,7 @@
 
 		    if (quotes > 0) {
 			/* Outside a quote segment, a quote starts one. */
-			if (!quote) quotes--, quote = 1;
+			if (!quote) quotes--, quote = true;
 
 			/* Now we produce (n+1)/3 literal quotes... */
 			for (i = 3; i <= quotes+1; i += 3) *q++ = '"';