Changed my mind about midend_is_solved: I've now reprototyped it as
[sgt/puzzles] / bridges.c
index 5bb73f4..5860e0c 100644 (file)
--- a/bridges.c
+++ b/bridges.c
@@ -513,7 +513,6 @@ static int island_impossible(struct island *is, int strict)
 {
     int curr = island_countbridges(is), nspc = is->count - curr, nsurrspc;
     int i, poss;
-    grid_type v;
     struct island *is_orth;
 
     if (nspc < 0) {
@@ -533,7 +532,6 @@ static int island_impossible(struct island *is, int strict)
         int ifree, dx = is->adj.points[i].dx;
 
         if (!is->adj.points[i].off) continue;
-        v = GRID(is->state, is->adj.points[i].x, is->adj.points[i].y);
         poss = POSSIBLES(is->state, dx,
                          is->adj.points[i].x, is->adj.points[i].y);
         if (poss == 0) continue;
@@ -542,9 +540,24 @@ static int island_impossible(struct island *is, int strict)
         assert(is_orth);
 
         ifree = is_orth->count - island_countbridges(is_orth);
-        if (ifree > 0)
-            nsurrspc += min(ifree, MAXIMUM(is->state, dx,
-                                           is->adj.points[i].x, is->adj.points[i].y));
+        if (ifree > 0) {
+           /*
+            * ifree is the number of bridges unfilled in the other
+            * island, which is clearly an upper bound on the number
+            * of extra bridges this island may run to it.
+            *
+            * Another upper bound is the number of bridges unfilled
+            * on the specific line between here and there. We must
+            * take the minimum of both.
+            */
+           int bmax = MAXIMUM(is->state, dx,
+                              is->adj.points[i].x, is->adj.points[i].y);
+           int bcurr = GRIDCOUNT(is->state,
+                                 is->adj.points[i].x, is->adj.points[i].y,
+                                 dx ? G_LINEH : G_LINEV);
+           assert(bcurr <= bmax);
+            nsurrspc += min(ifree, bmax - bcurr);
+       }
     }
     if (nsurrspc < nspc) {
         debug(("island at (%d,%d) impossible: surr. islands %d spc, need %d.\n",
@@ -2700,6 +2713,11 @@ static float game_flash_length(game_state *oldstate, game_state *newstate,
     return 0.0F;
 }
 
+static int game_status(game_state *state)
+{
+    return state->completed ? +1 : 0;
+}
+
 static int game_timing_state(game_state *state, game_ui *ui)
 {
     return TRUE;
@@ -2720,7 +2738,7 @@ static void game_print(drawing *dr, game_state *state, int ts)
     int ink = print_mono_colour(dr, 0);
     int paper = print_mono_colour(dr, 1);
     int x, y, cx, cy, i, nl;
-    int loff = ts/8;
+    int loff;
     grid_type grid;
 
     /* Ick: fake up `ds->tilesize' for macro expansion purposes */
@@ -2730,6 +2748,7 @@ static void game_print(drawing *dr, game_state *state, int ts)
     /* I don't think this wants a border. */
 
     /* Bridges */
+    loff = ts / (8 * sqrt((state->params.maxb - 1)));
     print_line_width(dr, ts / 12);
     for (x = 0; x < state->w; x++) {
         for (y = 0; y < state->h; y++) {
@@ -2739,20 +2758,14 @@ static void game_print(drawing *dr, game_state *state, int ts)
 
             if (grid & G_ISLAND) continue;
             if (grid & G_LINEV) {
-                if (nl > 1) {
-                    draw_line(dr, cx+ts/2-loff, cy, cx+ts/2-loff, cy+ts, ink);
-                    draw_line(dr, cx+ts/2+loff, cy, cx+ts/2+loff, cy+ts, ink);
-                } else {
-                    draw_line(dr, cx+ts/2,      cy, cx+ts/2,      cy+ts, ink);
-                }
+                for (i = 0; i < nl; i++)
+                    draw_line(dr, cx+ts/2+(2*i-nl+1)*loff, cy,
+                              cx+ts/2+(2*i-nl+1)*loff, cy+ts, ink);
             }
             if (grid & G_LINEH) {
-                if (nl > 1) {
-                    draw_line(dr, cx, cy+ts/2-loff, cx+ts, cy+ts/2-loff, ink);
-                    draw_line(dr, cx, cy+ts/2+loff, cx+ts, cy+ts/2+loff, ink);
-                } else {
-                    draw_line(dr, cx, cy+ts/2,      cx+ts,      cy+ts/2, ink);
-                }
+                for (i = 0; i < nl; i++)
+                    draw_line(dr, cx, cy+ts/2+(2*i-nl+1)*loff,
+                              cx+ts, cy+ts/2+(2*i-nl+1)*loff, ink);
             }
         }
     }
@@ -2808,6 +2821,7 @@ const struct game thegame = {
     game_redraw,
     game_anim_length,
     game_flash_length,
+    game_status,
     TRUE, FALSE, game_print_size, game_print,
     FALSE,                            /* wants_statusbar */
     FALSE, game_timing_state,