`Fifteen' was getting the parity wrong on any size of board where
[sgt/puzzles] / net.c
diff --git a/net.c b/net.c
index 268fbca..3c28ccc 100644 (file)
--- a/net.c
+++ b/net.c
@@ -12,6 +12,7 @@
 #include "tree234.h"
 
 const char *const game_name = "Net";
+const int game_can_configure = TRUE;
 
 #define PI 3.141592653589793238462643383279502884197169399
 
@@ -182,6 +183,73 @@ game_params *dup_params(game_params *params)
     return ret;
 }
 
+config_item *game_configure(game_params *params)
+{
+    config_item *ret;
+    char buf[80];
+
+    ret = snewn(5, config_item);
+
+    ret[0].name = "Width";
+    ret[0].type = C_STRING;
+    sprintf(buf, "%d", params->width);
+    ret[0].sval = dupstr(buf);
+    ret[0].ival = 0;
+
+    ret[1].name = "Height";
+    ret[1].type = C_STRING;
+    sprintf(buf, "%d", params->height);
+    ret[1].sval = dupstr(buf);
+    ret[1].ival = 0;
+
+    ret[2].name = "Walls wrap around";
+    ret[2].type = C_BOOLEAN;
+    ret[2].sval = NULL;
+    ret[2].ival = params->wrapping;
+
+    ret[3].name = "Barrier probability";
+    ret[3].type = C_STRING;
+    sprintf(buf, "%g", params->barrier_probability);
+    ret[3].sval = dupstr(buf);
+    ret[3].ival = 0;
+
+    ret[4].name = NULL;
+    ret[4].type = C_END;
+    ret[4].sval = NULL;
+    ret[4].ival = 0;
+
+    return ret;
+}
+
+game_params *custom_params(config_item *cfg)
+{
+    game_params *ret = snew(game_params);
+
+    ret->width = atoi(cfg[0].sval);
+    ret->height = atoi(cfg[1].sval);
+    ret->wrapping = cfg[2].ival;
+    ret->barrier_probability = (float)atof(cfg[3].sval);
+
+    return ret;
+}
+
+char *validate_params(game_params *params)
+{
+    if (params->width <= 0 && params->height <= 0)
+       return "Width and height must both be greater than zero";
+    if (params->width <= 0)
+       return "Width must be greater than zero";
+    if (params->height <= 0)
+       return "Height must be greater than zero";
+    if (params->width <= 1 && params->height <= 1)
+       return "At least one of width and height must be greater than one";
+    if (params->barrier_probability < 0)
+       return "Barrier probability may not be negative";
+    if (params->barrier_probability > 1)
+       return "Barrier probability may not be greater than 1";
+    return NULL;
+}
+
 /* ----------------------------------------------------------------------
  * Randomly select a new game seed.
  */
@@ -215,8 +283,8 @@ game_state *new_game(game_params *params, char *seed)
     tree234 *possibilities, *barriers;
     int w, h, x, y, nbarriers;
 
-    assert(params->width > 2);
-    assert(params->height > 2);
+    assert(params->width > 0 && params->height > 0);
+    assert(params->width > 1 || params->height > 1);
 
     /*
      * Create a blank game state.
@@ -296,11 +364,15 @@ game_state *new_game(game_params *params, char *seed)
      * closed loops. []
      */
     possibilities = newtree234(xyd_cmp);
-    
-    add234(possibilities, new_xyd(state->cx, state->cy, R));
-    add234(possibilities, new_xyd(state->cx, state->cy, U));
-    add234(possibilities, new_xyd(state->cx, state->cy, L));
-    add234(possibilities, new_xyd(state->cx, state->cy, D));
+
+    if (state->cx+1 < state->width)
+       add234(possibilities, new_xyd(state->cx, state->cy, R));
+    if (state->cy-1 >= 0)
+       add234(possibilities, new_xyd(state->cx, state->cy, U));
+    if (state->cx-1 >= 0)
+       add234(possibilities, new_xyd(state->cx, state->cy, L));
+    if (state->cy+1 < state->height)
+       add234(possibilities, new_xyd(state->cx, state->cy, D));
 
     while (count234(possibilities) > 0) {
        int i;
@@ -1189,6 +1261,24 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
             }
         }
 
+    /*
+     * Update the status bar.
+     */
+    {
+       char statusbuf[256];
+       int i, n, a;
+
+       n = state->width * state->height;
+       for (i = a = 0; i < n; i++)
+           if (active[i])
+               a++;
+
+       sprintf(statusbuf, "%sActive: %d/%d",
+               (state->completed ? "COMPLETED! " : ""), a, n);
+
+       status_bar(fe, statusbuf);
+    }
+
     sfree(active);
 }
 
@@ -1231,3 +1321,8 @@ float game_flash_length(game_state *oldstate, game_state *newstate)
 
     return 0.0F;
 }
+
+int game_wants_statusbar(void)
+{
+    return TRUE;
+}