Make errors in option parsing actually _do_ something in interactive mode.
[sgt/puzzles] / mines.c
diff --git a/mines.c b/mines.c
index 746106b..73aea0b 100644 (file)
--- a/mines.c
+++ b/mines.c
@@ -22,6 +22,7 @@ enum {
     COL_1, COL_2, COL_3, COL_4, COL_5, COL_6, COL_7, COL_8,
     COL_MINE, COL_BANG, COL_CROSS, COL_FLAG, COL_FLAGBASE, COL_QUERY,
     COL_HIGHLIGHT, COL_LOWLIGHT,
+    COL_WRONGNUMBER,
     NCOLOURS
 };
 
@@ -58,7 +59,7 @@ struct mine_layout {
 
 struct game_state {
     int w, h, n, dead, won;
-    int used_solve, just_used_solve;
+    int used_solve;
     struct mine_layout *layout;               /* real mine positions */
     signed char *grid;                        /* player knowledge */
     /*
@@ -275,14 +276,16 @@ static char *validate_params(game_params *params, int full)
 /*
  * Count the bits in a word. Only needs to cope with 16 bits.
  */
-static int bitcount16(int word)
+static int bitcount16(int inword)
 {
+    unsigned int word = inword;
+
     word = ((word & 0xAAAA) >> 1) + (word & 0x5555);
     word = ((word & 0xCCCC) >> 2) + (word & 0x3333);
     word = ((word & 0xF0F0) >> 4) + (word & 0x0F0F);
     word = ((word & 0xFF00) >> 8) + (word & 0x00FF);
 
-    return word;
+    return (int)word;
 }
 
 /*
@@ -2167,7 +2170,7 @@ static game_state *new_game(midend *me, game_params *params, char *desc)
     state->h = params->h;
     state->n = params->n;
     state->dead = state->won = FALSE;
-    state->used_solve = state->just_used_solve = FALSE;
+    state->used_solve = FALSE;
 
     wh = state->w * state->h;
 
@@ -2272,7 +2275,6 @@ static game_state *dup_game(game_state *state)
     ret->dead = state->dead;
     ret->won = state->won;
     ret->used_solve = state->used_solve;
-    ret->just_used_solve = state->just_used_solve;
     ret->layout = state->layout;
     ret->layout->refcount++;
     ret->grid = snewn(ret->w * ret->h, signed char);
@@ -2573,13 +2575,12 @@ static game_state *execute_move(game_state *from, char *move)
                    ret->grid[yy*ret->w+xx] = v;
                }
            }
-       ret->used_solve = ret->just_used_solve = TRUE;
+       ret->used_solve = TRUE;
        ret->won = TRUE;
 
        return ret;
     } else {
        ret = dup_game(from);
-       ret->just_used_solve = FALSE;
 
        while (*move) {
            if (move[0] == 'F' &&
@@ -2636,7 +2637,7 @@ static void game_set_size(drawing *dr, game_drawstate *ds,
     ds->tilesize = tilesize;
 }
 
-static float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, int *ncolours)
 {
     float *ret = snewn(3 * NCOLOURS, float);
 
@@ -2710,6 +2711,10 @@ static float *game_colours(frontend *fe, game_state *state, int *ncolours)
     ret[COL_LOWLIGHT * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 2.0 / 3.0;
     ret[COL_LOWLIGHT * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 2.0 / 3.0;
 
+    ret[COL_WRONGNUMBER * 3 + 0] = 1.0F;
+    ret[COL_WRONGNUMBER * 3 + 1] = 0.6F;
+    ret[COL_WRONGNUMBER * 3 + 2] = 0.6F;
+
     *ncolours = NCOLOURS;
     return ret;
 }
@@ -2814,6 +2819,10 @@ static void draw_tile(drawing *dr, game_drawstate *ds,
         * Exception is that for value 65 (mine we've just trodden
         * on), we clear the square to COL_BANG.
         */
+        if (v & 32) {
+            bg = COL_WRONGNUMBER;
+            v &= ~32;
+        }
         draw_rect(dr, x, y, TILE_SIZE, TILE_SIZE,
                  (v == 65 ? COL_BANG :
                    bg == COL_BACKGROUND ? COL_BACKGROUND2 : bg));
@@ -2960,6 +2969,26 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
            if (state->layout->mines && state->layout->mines[y*ds->w+x])
                mines++;
 
+            if (v >= 0 && v <= 8) {
+                /*
+                 * Count up the flags around this tile, and if
+                 * there are too _many_, highlight the tile.
+                 */
+                int dx, dy, flags = 0;
+
+                for (dy = -1; dy <= +1; dy++)
+                    for (dx = -1; dx <= +1; dx++) {
+                        int nx = x+dx, ny = y+dy;
+                        if (nx >= 0 && nx < ds->w &&
+                            ny >= 0 && ny < ds->h &&
+                            state->grid[ny*ds->w+nx] == -1)
+                            flags++;
+                    }
+
+                if (flags > v)
+                    v |= 32;
+            }
+
            if ((v == -2 || v == -3) &&
                (abs(x-ui->hx) <= ui->hradius && abs(y-ui->hy) <= ui->hradius))
                v -= 20;
@@ -3021,11 +3050,6 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
-static int game_wants_statusbar(void)
-{
-    return TRUE;
-}
-
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     if (state->dead || state->won || ui->completed || !state->layout->mines)
@@ -3046,7 +3070,7 @@ static void game_print(drawing *dr, game_state *state, int tilesize)
 #endif
 
 const struct game thegame = {
-    "Mines", "games.mines",
+    "Mines", "games.mines", "mines",
     default_params,
     game_fetch_preset,
     decode_params,
@@ -3077,7 +3101,7 @@ const struct game thegame = {
     game_anim_length,
     game_flash_length,
     FALSE, FALSE, game_print_size, game_print,
-    game_wants_statusbar,
+    TRUE,                             /* wants_statusbar */
     TRUE, game_timing_state,
     BUTTON_BEATS(LEFT_BUTTON, RIGHT_BUTTON),
 };
@@ -3095,41 +3119,8 @@ const struct game thegame = {
  * 9x9:4,4,004000007c00010022080
  * $ ./mineobfusc 9x9:4,4,004000007c00010022080
  * 9x9:4,4,mb071b49fbd1cb6a0d5868
- *
- * gcc -DSTANDALONE_OBFUSCATOR -o mineobfusc mines.c malloc.c random.c tree234.c misc.c
  */
 
-#include <stdarg.h>
-
-void frontend_default_colour(frontend *fe, float *output) {}
-void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize,
-               int align, int colour, char *text) {}
-void draw_rect(drawing *dr, int x, int y, int w, int h, int colour) {}
-void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour) {}
-void draw_polygon(drawing *dr, int *coords, int npoints,
-                  int fillcolour, int outlinecolour) {}
-void clip(drawing *dr, int x, int y, int w, int h) {}
-void unclip(drawing *dr) {}
-void start_draw(drawing *dr) {}
-void draw_update(drawing *dr, int x, int y, int w, int h) {}
-void end_draw(drawing *dr) {}
-void midend_supersede_game_desc(midend *me, char *desc, char *privdesc) {}
-void status_bar(drawing *dr, char *text) {}
-
-void fatal(char *fmt, ...)
-{
-    va_list ap;
-
-    fprintf(stderr, "fatal error: ");
-
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-
-    fprintf(stderr, "\n");
-    exit(1);
-}
-
 int main(int argc, char **argv)
 {
     game_params *p;