chiark / gitweb /
Allow marking of clues as exhausted in Unequal.
authorJonas Kölker <jonaskoelker@yahoo.com>
Thu, 1 Oct 2015 16:26:50 +0000 (18:26 +0200)
committerSimon Tatham <anakin@pobox.com>
Sat, 3 Oct 2015 16:12:20 +0000 (17:12 +0100)
puzzles.but
unequal.c

index 3af651659dc211e2e344b38be630f1f224a7323e..2c8f91b143e3ffe69246fe94cef9a966acea613b 100644 (file)
@@ -2330,6 +2330,11 @@ pencil mark), and typing a number in is entered in the square in the
 appropriate way; typing in a 0 or using the space bar will clear a
 filled square. 
 
+Left-clicking a clue will mark it as done (grey it out), or unmark it
+if it is already marked.  Holding Control or Shift and pressing an
+arrow key likewise marks any clue adjacent to the cursor in the given
+direction.
+
 (All the actions described in \k{common-actions} are also available.)
 
 \H{unequal-parameters} \I{parameters, for Unequal}Unequal parameters
index 54300e1288609819dcd3ef2cae604caf0a175a43..1c8984a14eceb790543fc8484e42c8b9ce79b0b7 100644 (file)
--- a/unequal.c
+++ b/unequal.c
@@ -51,7 +51,7 @@ enum {
     COL_BACKGROUND,
     COL_GRID,
     COL_TEXT, COL_GUESS, COL_ERROR, COL_PENCIL,
-    COL_HIGHLIGHT, COL_LOWLIGHT,
+    COL_HIGHLIGHT, COL_LOWLIGHT, COL_SPENT = COL_LOWLIGHT,
     NCOLOURS
 };
 
@@ -72,6 +72,12 @@ struct game_params {
 #define F_ERROR_RIGHT   128
 #define F_ERROR_DOWN    256
 #define F_ERROR_LEFT    512
+#define F_SPENT_UP      1024
+#define F_SPENT_RIGHT   2048
+#define F_SPENT_DOWN    4096
+#define F_SPENT_LEFT    8192
+
+#define ADJ_TO_SPENT(x) ((x) << 9)
 
 #define F_ERROR_MASK (F_ERROR|F_ERROR_UP|F_ERROR_RIGHT|F_ERROR_DOWN|F_ERROR_LEFT)
 
@@ -1381,11 +1387,32 @@ static char *interpret_move(const game_state *state, game_ui *ui,
 {
     int x = FROMCOORD(ox), y = FROMCOORD(oy), n;
     char buf[80];
+    int shift_or_control = button & (MOD_SHFT | MOD_CTRL);
 
     button &= ~MOD_MASK;
 
-    if (x >= 0 && x < ds->order && ((ox - COORD(x)) <= TILE_SIZE) &&
-        y >= 0 && y < ds->order && ((oy - COORD(y)) <= TILE_SIZE)) {
+    if (x >= 0 && x < ds->order && y >= 0 && y < ds->order && IS_MOUSE_DOWN(button)) {
+       if (oy - COORD(y) > TILE_SIZE && ox - COORD(x) > TILE_SIZE)
+           return NULL;
+
+       if (oy - COORD(y) > TILE_SIZE) {
+           if (GRID(state, flags, x, y) & F_ADJ_DOWN)
+               sprintf(buf, "F%d,%d,%d", x, y, F_SPENT_DOWN);
+           else if (y + 1 < ds->order && GRID(state, flags, x, y + 1) & F_ADJ_UP)
+               sprintf(buf, "F%d,%d,%d", x, y + 1, F_SPENT_UP);
+           else return NULL;
+           return dupstr(buf);
+       }
+
+       if (ox - COORD(x) > TILE_SIZE) {
+           if (GRID(state, flags, x, y) & F_ADJ_RIGHT)
+               sprintf(buf, "F%d,%d,%d", x, y, F_SPENT_RIGHT);
+           else if (x + 1 < ds->order && GRID(state, flags, x + 1, y) & F_ADJ_LEFT)
+               sprintf(buf, "F%d,%d,%d", x + 1, y, F_SPENT_LEFT);
+           else return NULL;
+           return dupstr(buf);
+       }
+
         if (button == LEFT_BUTTON) {
             /* normal highlighting for non-immutable squares */
             if (GRID(state, flags, x, y) & F_IMMUTABLE)
@@ -1417,9 +1444,39 @@ static char *interpret_move(const game_state *state, game_ui *ui,
     }
 
     if (IS_CURSOR_MOVE(button)) {
-        move_cursor(button, &ui->hx, &ui->hy, ds->order, ds->order, 0);
-        ui->hshow = ui->hcursor = 1;
-        return "";
+       if (shift_or_control) {
+           int nx = ui->hx, ny = ui->hy, i, self;
+           move_cursor(button, &nx, &ny, ds->order, ds->order, FALSE);
+           ui->hshow = ui->hcursor = 1;
+
+           for (i = 0; i < 4 && (nx != ui->hx + adjthan[i].dx ||
+                                 ny != ui->hy + adjthan[i].dy); ++i);
+
+           if (i == 4)
+               return ""; /* invalid direction, i.e. out of the board */
+
+           if (!(GRID(state, flags, ui->hx, ui->hy) & adjthan[i].f ||
+                 GRID(state, flags, nx,     ny    ) & adjthan[i].fo))
+               return ""; /* no clue to toggle */
+
+           if (state->adjacent)
+               self = (adjthan[i].dx >= 0 && adjthan[i].dy >= 0);
+           else
+               self = (GRID(state, flags, ui->hx, ui->hy) & adjthan[i].f);
+
+           if (self)
+               sprintf(buf, "F%d,%d,%d", ui->hx, ui->hy,
+                       ADJ_TO_SPENT(adjthan[i].f));
+           else
+               sprintf(buf, "F%d,%d,%d", nx, ny,
+                       ADJ_TO_SPENT(adjthan[i].fo));
+
+           return dupstr(buf);
+       } else {
+           move_cursor(button, &ui->hx, &ui->hy, ds->order, ds->order, FALSE);
+           ui->hshow = ui->hcursor = 1;
+           return "";
+       }
     }
     if (ui->hshow && IS_CURSOR_SELECT(button)) {
         ui->hpencil = 1 - ui->hpencil;
@@ -1512,6 +1569,11 @@ static game_state *execute_move(const game_state *state, const char *move)
         return ret;
     } else if (move[0] == 'H') {
         return solver_hint(state, NULL, DIFF_EASY, DIFF_EASY);
+    } 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) {
+       ret = dup_game(state);
+       GRID(ret, flags, x, y) ^= n;
+       return ret;
     }
 
 badmove:
@@ -1621,6 +1683,9 @@ static void draw_gt(drawing *dr, int ox, int oy,
     draw_polygon(dr, coords, 6, col, col);
 }
 
+#define COLOUR(direction) (f & (F_ERROR_##direction) ? COL_ERROR : \
+                          f & (F_SPENT_##direction) ? COL_SPENT : fg)
+
 static void draw_gts(drawing *dr, game_drawstate *ds, int ox, int oy,
                      unsigned int f, int bg, int fg)
 {
@@ -1630,26 +1695,22 @@ static void draw_gts(drawing *dr, game_drawstate *ds, int ox, int oy,
 
     if (f & F_ADJ_UP) {
        if (bg >= 0) draw_rect(dr, ox, oy - g, TILE_SIZE, g, bg);
-        draw_gt(dr, ox+g2, oy-g4, g2, -g2, g2, g2,
-               (f & F_ERROR_UP) ? COL_ERROR : fg);
+        draw_gt(dr, ox+g2, oy-g4, g2, -g2, g2, g2, COLOUR(UP));
         draw_update(dr, ox, oy-g, TILE_SIZE, g);
     }
     if (f & F_ADJ_RIGHT) {
        if (bg >= 0) draw_rect(dr, ox + TILE_SIZE, oy, g, TILE_SIZE, bg);
-        draw_gt(dr, ox+TILE_SIZE+g4, oy+g2, g2, g2, -g2, g2,
-                (f & F_ERROR_RIGHT) ? COL_ERROR : fg);
+        draw_gt(dr, ox+TILE_SIZE+g4, oy+g2, g2, g2, -g2, g2, COLOUR(RIGHT));
         draw_update(dr, ox+TILE_SIZE, oy, g, TILE_SIZE);
     }
     if (f & F_ADJ_DOWN) {
        if (bg >= 0) draw_rect(dr, ox, oy + TILE_SIZE, TILE_SIZE, g, bg);
-        draw_gt(dr, ox+g2, oy+TILE_SIZE+g4, g2, g2, g2, -g2,
-               (f & F_ERROR_DOWN) ? COL_ERROR : fg);
+        draw_gt(dr, ox+g2, oy+TILE_SIZE+g4, g2, g2, g2, -g2, COLOUR(DOWN));
         draw_update(dr, ox, oy+TILE_SIZE, TILE_SIZE, g);
     }
     if (f & F_ADJ_LEFT) {
        if (bg >= 0) draw_rect(dr, ox - g, oy, g, TILE_SIZE, bg);
-        draw_gt(dr, ox-g4, oy+g2, -g2, g2, g2, g2,
-                (f & F_ERROR_LEFT) ? COL_ERROR : fg);
+        draw_gt(dr, ox-g4, oy+g2, -g2, g2, g2, g2, COLOUR(LEFT));
         draw_update(dr, ox-g, oy, g, TILE_SIZE);
     }
 }
@@ -1668,8 +1729,7 @@ static void draw_adjs(drawing *dr, game_drawstate *ds, int ox, int oy,
 
     if (f & (F_ADJ_RIGHT|F_ERROR_RIGHT)) {
         if (f & F_ADJ_RIGHT) {
-            draw_rect(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE,
-                      (f & F_ERROR_RIGHT) ? COL_ERROR : fg);
+            draw_rect(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE, COLOUR(RIGHT));
         } else {
             draw_rect_outline(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE, COL_ERROR);
         }
@@ -1680,8 +1740,7 @@ static void draw_adjs(drawing *dr, game_drawstate *ds, int ox, int oy,
 
     if (f & (F_ADJ_DOWN|F_ERROR_DOWN)) {
         if (f & F_ADJ_DOWN) {
-            draw_rect(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4,
-                      (f & F_ERROR_DOWN) ? COL_ERROR : fg);
+            draw_rect(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4, COLOUR(DOWN));
         } else {
             draw_rect_outline(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4, COL_ERROR);
         }