return i;
}
-struct game_aux_info {
- int c, r;
- digit *grid;
-};
+static char *encode_solve_move(int cr, digit *grid)
+{
+ int i, len;
+ char *ret, *p, *sep;
+
+ /*
+ * It's surprisingly easy to work out _exactly_ how long this
+ * string needs to be. To decimal-encode all the numbers from 1
+ * to n:
+ *
+ * - every number has a units digit; total is n.
+ * - all numbers above 9 have a tens digit; total is max(n-9,0).
+ * - all numbers above 99 have a hundreds digit; total is max(n-99,0).
+ * - and so on.
+ */
+ len = 0;
+ for (i = 1; i <= cr; i *= 10)
+ len += max(cr - i + 1, 0);
+ len += cr; /* don't forget the commas */
+ len *= cr; /* there are cr rows of these */
+
+ /*
+ * Now len is one bigger than the total size of the
+ * comma-separated numbers (because we counted an
+ * additional leading comma). We need to have a leading S
+ * and a trailing NUL, so we're off by one in total.
+ */
+ len++;
+
+ ret = snewn(len, char);
+ p = ret;
+ *p++ = 'S';
+ sep = "";
+ for (i = 0; i < cr*cr; i++) {
+ p += sprintf(p, "%s%d", sep, grid[i]);
+ sep = ",";
+ }
+ *p++ = '\0';
+ assert(p - ret == len);
+
+ return ret;
+}
static char *new_game_desc(game_params *params, random_state *rs,
- game_aux_info **aux, int interactive)
+ char **aux, int interactive)
{
int c = params->c, r = params->r, cr = c*r;
int area = cr*cr;
assert(check_valid(c, r, grid));
/*
- * Save the solved grid in the aux_info.
+ * Save the solved grid in aux.
*/
{
- game_aux_info *ai = snew(game_aux_info);
- ai->c = c;
- ai->r = r;
- ai->grid = snewn(cr * cr, digit);
- memcpy(ai->grid, grid, cr * cr * sizeof(digit));
/*
* We might already have written *aux the last time we
* went round this loop, in which case we should free
- * the old aux_info before overwriting it with the new
- * one.
+ * the old aux before overwriting it with the new one.
*/
if (*aux) {
- sfree((*aux)->grid);
sfree(*aux);
}
- *aux = ai;
+
+ *aux = encode_solve_move(cr, grid);
}
/*
return desc;
}
-static void game_free_aux_info(game_aux_info *aux)
-{
- sfree(aux->grid);
- sfree(aux);
-}
-
static char *validate_desc(game_params *params, char *desc)
{
int area = params->r * params->r * params->c * params->c;
}
static char *solve_game(game_state *state, game_state *currstate,
- game_aux_info *ai, char **error)
+ char *ai, char **error)
{
int c = state->c, r = state->r, cr = c*r;
- int i, len;
- char *ret, *p, *sep;
+ char *ret;
digit *grid;
- int grid_needs_freeing;
+ int rsolve_ret;
/*
- * If we already have the solution in the aux_info, save
- * ourselves some time.
+ * If we already have the solution in ai, save ourselves some
+ * time.
*/
- if (ai) {
-
- assert(c == ai->c);
- assert(r == ai->r);
- grid = ai->grid;
- grid_needs_freeing = FALSE;
+ if (ai)
+ return dupstr(ai);
- } else {
- int rsolve_ret;
-
- grid = snewn(cr*cr, digit);
- memcpy(grid, state->grid, cr*cr);
- rsolve_ret = rsolve(c, r, grid, NULL, 2);
-
- if (rsolve_ret != 1) {
- sfree(grid);
- if (rsolve_ret == 0)
- *error = "No solution exists for this puzzle";
- else
- *error = "Multiple solutions exist for this puzzle";
- return NULL;
- }
+ grid = snewn(cr*cr, digit);
+ memcpy(grid, state->grid, cr*cr);
+ rsolve_ret = rsolve(c, r, grid, NULL, 2);
- grid_needs_freeing = TRUE;
+ if (rsolve_ret != 1) {
+ sfree(grid);
+ if (rsolve_ret == 0)
+ *error = "No solution exists for this puzzle";
+ else
+ *error = "Multiple solutions exist for this puzzle";
+ return NULL;
}
- /*
- * It's surprisingly easy to work out _exactly_ how long this
- * string needs to be. To decimal-encode all the numbers from 1
- * to n:
- *
- * - every number has a units digit; total is n.
- * - all numbers above 9 have a tens digit; total is max(n-9,0).
- * - all numbers above 99 have a hundreds digit; total is max(n-99,0).
- * - and so on.
- */
- len = 0;
- for (i = 1; i <= cr; i *= 10)
- len += max(cr - i + 1, 0);
- len += cr; /* don't forget the commas */
- len *= cr; /* there are cr rows of these */
-
- /*
- * Now len is one bigger than the total size of the
- * comma-separated numbers (because we counted an
- * additional leading comma). We need to have a leading S
- * and a trailing NUL, so we're off by one in total.
- */
- len++;
-
- ret = snewn(len, char);
- p = ret;
- *p++ = 'S';
- sep = "";
- for (i = 0; i < cr*cr; i++) {
- p += sprintf(p, "%s%d", sep, grid[i]);
- sep = ",";
- }
- *p++ = '\0';
- assert(p - ret == len);
+ ret = encode_solve_move(cr, grid);
- if (grid_needs_freeing)
- sfree(grid);
+ sfree(grid);
return ret;
}
sfree(ui);
}
+static char *encode_ui(game_ui *ui)
+{
+ return NULL;
+}
+
+static void decode_ui(game_ui *ui, char *encoding)
+{
+}
+
static void game_changed_state(game_ui *ui, game_state *oldstate,
game_state *newstate)
{
return NULL;
sprintf(buf, "%c%d,%d,%d",
- ui->hpencil && n > 0 ? 'P' : 'R', ui->hx, ui->hy, n);
+ (char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
ui->hx = ui->hy = -1;
*/
#define SIZE(cr) ((cr) * TILE_SIZE + 2*BORDER + 1)
-#define GETTILESIZE(cr, w) ( (w-1) / (cr+1) )
+#define GETTILESIZE(cr, w) ( (double)(w-1) / (double)(cr+1) )
static void game_size(game_params *params, game_drawstate *ds,
int *x, int *y, int expand)
{
int c = params->c, r = params->r, cr = c*r;
- int ts;
+ double ts;
ts = min(GETTILESIZE(cr, *x), GETTILESIZE(cr, *y));
if (expand)
- ds->tilesize = ts;
+ ds->tilesize = (int)(ts+0.5);
else
- ds->tilesize = min(ts, PREFERRED_TILE_SIZE);
+ ds->tilesize = min((int)ts, PREFERRED_TILE_SIZE);
*x = SIZE(cr);
*y = SIZE(cr);
coords[3] = cy;
coords[4] = cx;
coords[5] = cy+ch/2;
- draw_polygon(fe, coords, 3, TRUE, COL_HIGHLIGHT);
+ draw_polygon(fe, coords, 3, COL_HIGHLIGHT, COL_HIGHLIGHT);
}
/* new number needs drawing? */
TRUE, game_configure, custom_params,
validate_params,
new_game_desc,
- game_free_aux_info,
validate_desc,
new_game,
dup_game,
TRUE, game_text_format,
new_ui,
free_ui,
+ encode_ui,
+ decode_ui,
game_changed_state,
interpret_move,
execute_move,
void draw_rect(frontend *fe, int x, int y, int w, int h, int colour) {}
void draw_line(frontend *fe, int x1, int y1, int x2, int y2, int colour) {}
void draw_polygon(frontend *fe, int *coords, int npoints,
- int fill, int colour) {}
+ int fillcolour, int outlinecolour) {}
void clip(frontend *fe, int x, int y, int w, int h) {}
void unclip(frontend *fe) {}
void start_draw(frontend *fe) {}