X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/7463d8efc4bd8876450d2ae7f52f2ae72e3c70ab..HEAD:/tents.c diff --git a/tents.c b/tents.c index c0ea0eb..ef5debc 100644 --- a/tents.c +++ b/tents.c @@ -459,7 +459,7 @@ static int tents_solve(int w, int h, const char *grid, int *numbers, char *soln, struct solver_scratch *sc, int diff) { int x, y, d, i, j; - char *mrow, *mrow1, *mrow2, *trow, *trow1, *trow2; + char *mrow, *trow, *trow1, *trow2; /* * Set up solver data. @@ -746,8 +746,6 @@ static int tents_solve(int w, int h, const char *grid, int *numbers, * hasn't been set up yet. */ mrow = sc->mrows; - mrow1 = sc->mrows + len; - mrow2 = sc->mrows + 2*len; trow = sc->trows; trow1 = sc->trows + len; trow2 = sc->trows + 2*len; @@ -1210,6 +1208,10 @@ static char *validate_desc(game_params *params, char *desc) desc++; } + if (area < w * h + 1) + return "Not enough data to fill grid"; + else if (area > w * h + 1) + return "Too much data to fill grid"; for (i = 0; i < w+h; i++) { if (!*desc) @@ -1465,6 +1467,7 @@ static int drag_xform(game_ui *ui, int x, int y, int v) ymin = min(ui->dsy, ui->dey); ymax = max(ui->dsy, ui->dey); +#ifndef STYLUS_BASED /* * Left-dragging has no effect, so we treat a left-drag as a * single click on dsx,dsy. @@ -1473,6 +1476,7 @@ static int drag_xform(game_ui *ui, int x, int y, int v) xmin = xmax = ui->dsx; ymin = ymax = ui->dsy; } +#endif if (x < xmin || x > xmax || y < ymin || y > ymax) return v; /* no change outside drag area */ @@ -1485,11 +1489,18 @@ static int drag_xform(game_ui *ui, int x, int y, int v) * Results of a simple click. Left button sets blanks to * tents; right button sets blanks to non-tents; either * button clears a non-blank square. + * If stylus-based however, it loops instead. */ if (ui->drag_button == LEFT_BUTTON) +#ifdef STYLUS_BASED + v = (v == BLANK ? TENT : (v == TENT ? NONTENT : BLANK)); + else + v = (v == BLANK ? NONTENT : (v == NONTENT ? TENT : BLANK)); +#else v = (v == BLANK ? TENT : BLANK); else v = (v == BLANK ? NONTENT : BLANK); +#endif } else { /* * Results of a drag. Left-dragging has no effect. @@ -1499,13 +1510,17 @@ static int drag_xform(game_ui *ui, int x, int y, int v) if (ui->drag_button == RIGHT_BUTTON) v = (v == BLANK ? NONTENT : v); else +#ifdef STYLUS_BASED + v = (v == BLANK ? NONTENT : v); +#else /* do nothing */; +#endif } return v; } -static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds, +static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds, int x, int y, int button) { int w = state->p.w, h = state->p.h; @@ -1964,11 +1979,14 @@ static int *find_errors(game_state *state, char *grid) * Also, that approach fares badly when you introduce the * additional requirement that incomplete grids should have * errors highlighted only when they can be proved to be errors - * - so that a tree surrounded by BLANK squares should not be - * marked as erroneous (it would be patronising, since the - * overwhelming likelihood is not that the player has forgotten - * to put a tree there but that they have merely not put one - * there _yet), but one surrounded by NONTENTs should. + * - so that trees should not be marked as having too few tents + * if there are enough BLANK squares remaining around them that + * could be turned into the missing tents (to do so would be + * patronising, since the overwhelming likelihood is not that + * the player has forgotten to put a tree there but that they + * have merely not put one there _yet_). However, tents with too + * few trees can be marked immediately, since those are + * definitely player error. * * So I adopt an alternative approach, which is to consider the * bipartite adjacency graph between trees and tents @@ -2392,7 +2410,7 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, * currently active drag: we transform dsx,dsy but not anything * else. (This seems to strike a good compromise between having * the error highlights respond instantly to single clicks, but - * not give constant feedback during a right-drag.) + * not giving constant feedback during a right-drag.) */ if (ui && ui->drag_button >= 0) { tmpgrid = snewn(w*h, char); @@ -2445,7 +2463,7 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, * changed) the numbers. */ for (x = 0; x < w; x++) { - if (ds->numbersdrawn[x] != errors[w*h+x]) { + if (printing || ds->numbersdrawn[x] != errors[w*h+x]) { char buf[80]; draw_rect(dr, COORD(x), COORD(h)+1, TILESIZE, BRBORDER-1, COL_BACKGROUND); @@ -2454,11 +2472,12 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, FONT_VARIABLE, TILESIZE/2, ALIGN_HCENTRE|ALIGN_VNORMAL, (errors[w*h+x] ? COL_ERROR : COL_GRID), buf); draw_update(dr, COORD(x), COORD(h)+1, TILESIZE, BRBORDER-1); - ds->numbersdrawn[x] = errors[w*h+x]; + if (!printing) + ds->numbersdrawn[x] = errors[w*h+x]; } } for (y = 0; y < h; y++) { - if (ds->numbersdrawn[w+y] != errors[w*h+w+y]) { + if (printing || ds->numbersdrawn[w+y] != errors[w*h+w+y]) { char buf[80]; draw_rect(dr, COORD(w)+1, COORD(y), BRBORDER-1, TILESIZE, COL_BACKGROUND); @@ -2467,7 +2486,8 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, FONT_VARIABLE, TILESIZE/2, ALIGN_HRIGHT|ALIGN_VCENTRE, (errors[w*h+w+y] ? COL_ERROR : COL_GRID), buf); draw_update(dr, COORD(w)+1, COORD(y), BRBORDER-1, TILESIZE); - ds->numbersdrawn[w+y] = errors[w*h+w+y]; + if (!printing) + ds->numbersdrawn[w+y] = errors[w*h+w+y]; } } @@ -2502,6 +2522,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; @@ -2572,6 +2597,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,