shithub: puzzles

Download patch

ref: 6179e8df56000bc8f558129a8475cf977c06a249
parent: a79fc469516bd5bad28cf6ac025e25ffa20794d6
author: Jonas Kölker <jonaskoelker@yahoo.com>
date: Thu Oct 1 14:26:50 EDT 2015

Allow marking of clues as exhausted in Unequal.

--- a/puzzles.but
+++ b/puzzles.but
@@ -2330,6 +2330,11 @@
 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
--- a/unequal.c
+++ b/unequal.c
@@ -51,7 +51,7 @@
     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,7 +72,13 @@
 #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)
 
 struct game_state {
@@ -1381,11 +1387,32 @@
 {
     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 @@
     }
 
     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 @@
         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 @@
     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 @@
 
     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 @@
 
     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 @@
 
     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);
         }