diff options
| author | Simon Tatham <anakin@pobox.com> | 2005-04-25 14:03:53 +0000 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 2005-04-25 14:03:53 +0000 |
| commit | a163926ed5b74c23211ccd4b3f3e58401d8f720b (patch) | |
| tree | 087acc48f7686d59296a679b627bb79a17a323c4 | |
| parent | 6bf62f457799bfa1b608dec6f08e2e97e9ea561f (diff) | |
| download | puzzles-a163926ed5b74c23211ccd4b3f3e58401d8f720b.zip puzzles-a163926ed5b74c23211ccd4b3f3e58401d8f720b.tar.gz puzzles-a163926ed5b74c23211ccd4b3f3e58401d8f720b.tar.bz2 puzzles-a163926ed5b74c23211ccd4b3f3e58401d8f720b.tar.xz | |
Various changes prompted by my boss taking an interest:
- added a compilation option -DSTANDALONE_SOLVER which makes both
of Solo's internal solvers accessible from the command line.
- fix a bug in nsolve turned up by testing in this mode: it failed
to iterate at all! Oddly, this massive improvement to the
effectiveness of nsolve hasn't emptied the generated grids by
very much.
- add an extra mode of reasoning to my to-do list (which is the
dual of one already there, so I'm kicking myself).
[originally from svn r5670]
| -rw-r--r-- | solo.c | 111 |
1 files changed, 105 insertions, 6 deletions
@@ -698,8 +698,10 @@ static int nsolve_elim(struct nsolve_usage *usage, int start, int step) x = y / cr; y %= cr; - nsolve_place(usage, x, y, n); - return TRUE; + if (!usage->grid[YUNTRANS(y)*cr+x]) { + nsolve_place(usage, x, y, n); + return TRUE; + } } return FALSE; @@ -746,6 +748,8 @@ static int nsolve(int c, int r, digit *grid) * not. */ while (1) { + cont: + /* * Blockwise positional elimination. */ @@ -754,7 +758,7 @@ static int nsolve(int c, int r, digit *grid) for (n = 1; n <= cr; n++) if (!usage->blk[(y*c+(x/r))*cr+n-1] && nsolve_elim(usage, cubepos(x,y,n), r*cr)) - continue; + goto cont; /* * Row-wise positional elimination. @@ -763,7 +767,7 @@ static int nsolve(int c, int r, digit *grid) for (n = 1; n <= cr; n++) if (!usage->row[y*cr+n-1] && nsolve_elim(usage, cubepos(0,y,n), cr*cr)) - continue; + goto cont; /* * Column-wise positional elimination. */ @@ -771,7 +775,7 @@ static int nsolve(int c, int r, digit *grid) for (n = 1; n <= cr; n++) if (!usage->col[x*cr+n-1] && nsolve_elim(usage, cubepos(x,0,n), cr)) - continue; + goto cont; /* * Numeric elimination. @@ -780,7 +784,7 @@ static int nsolve(int c, int r, digit *grid) for (y = 0; y < cr; y++) if (!usage->grid[YUNTRANS(y)*cr+x] && nsolve_elim(usage, cubepos(x,y,1), 1)) - continue; + goto cont; /* * If we reach here, we have made no deductions in this @@ -1526,3 +1530,98 @@ const struct game thegame = { game_flash_length, game_wants_statusbar, }; + +#ifdef STANDALONE_SOLVER + +void frontend_default_colour(frontend *fe, float *output) {} +void draw_text(frontend *fe, int x, int y, int fonttype, int fontsize, + int align, int colour, char *text) {} +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) {} +void clip(frontend *fe, int x, int y, int w, int h) {} +void unclip(frontend *fe) {} +void start_draw(frontend *fe) {} +void draw_update(frontend *fe, int x, int y, int w, int h) {} +void end_draw(frontend *fe) {} + +#include <stdarg.h> + +void fatal(char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "fatal error: "); + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + fprintf(stderr, "\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + game_params *p; + game_state *s; + int recurse = FALSE; + char *id = NULL, *seed, *err; + int y, x; + + while (--argc > 0) { + char *p = *++argv; + if (!strcmp(p, "-r")) { + recurse = TRUE; + } else if (!strcmp(p, "-n")) { + recurse = FALSE; + } else if (*p == '-') { + fprintf(stderr, "%s: unrecognised option `%s'\n", argv[0]); + return 1; + } else { + id = p; + } + } + + if (!id) { + fprintf(stderr, "usage: %s [-n | -r] <game_id>\n", argv[0]); + return 1; + } + + seed = strchr(id, ':'); + if (!seed) { + fprintf(stderr, "%s: game id expects a colon in it\n", argv[0]); + return 1; + } + *seed++ = '\0'; + + p = decode_params(id); + err = validate_seed(p, seed); + if (err) { + fprintf(stderr, "%s: %s\n", argv[0], err); + return 1; + } + s = new_game(p, seed); + + if (recurse) { + int ret = rsolve(p->c, p->r, s->grid, NULL, 2); + if (ret > 1) { + printf("multiple solutions detected; only first one output\n"); + } + } else { + nsolve(p->c, p->r, s->grid); + } + + for (y = 0; y < p->c * p->r; y++) { + for (x = 0; x < p->c * p->r; x++) { + printf("%2.0d", s->grid[y * p->c * p->r + x]); + } + printf("\n"); + } + printf("\n"); + + return 0; +} + +#endif |