X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/d7b7d7cd124ab1acb8dc834a5701390c67cd7b9e..ed375bd341a1d52ffd27a3245980bcb970b10848:/lightup.c diff --git a/lightup.c b/lightup.c index b2c9b28..5fe95b0 100644 --- a/lightup.c +++ b/lightup.c @@ -727,6 +727,7 @@ static void place_lights(game_state *state, random_state *rs) debug_state(state); assert(!"place_lights failed to resolve overlapping lights!"); } + sfree(numindices); } /* Fills in all black squares with numbers of adjacent lights. */ @@ -764,7 +765,7 @@ static int try_solve_light(game_state *state, int ox, int oy, unsigned int flags, int lights) { ll_data lld; - int sx,sy,n = 0; + int sx = 0, sy = 0, n = 0; if (lights > 0) return 0; if (flags & F_BLACK) return 0; @@ -1016,9 +1017,9 @@ static void try_rule_out(game_state *state, int x, int y, get_surrounds(state, x, y, &s); for (i = 0; i < s.npoints; i++) { - if (!GRID(state,flags,s.points[i].x,s.points[i].y) & F_NUMBERED) + if (!(GRID(state,flags,s.points[i].x,s.points[i].y) & F_NUMBERED)) continue; - /* we have an adjacent clue square; find /it's/ surrounds + /* we have an adjacent clue square; find /its/ surrounds * and count the remaining lights it needs. */ get_surrounds(state,s.points[i].x,s.points[i].y,&ss); curr_lights = 0; @@ -1401,6 +1402,7 @@ static int strip_unused_nums(game_state *state) } } } + debug(("Stripped %d unused numbers.\n", n)); return n; } @@ -1474,7 +1476,7 @@ static char *new_game_desc(game_params *params, random_state *rs, char **aux, int interactive) { game_state *news = new_state(params), *copys; - int nsol, i, j, run, x, y, wh = params->w*params->h, num; + int i, j, run, x, y, wh = params->w*params->h, num; char *ret, *p; int *numindices; @@ -1498,8 +1500,7 @@ static char *new_game_desc(game_params *params, random_state *rs, /* Take a copy, remove numbers we didn't use and check there's * still a unique solution; if so, use the copy subsequently. */ copys = dup_game(news); - nsol = strip_unused_nums(copys); - debug(("Stripped %d unused numbers.\n", nsol)); + strip_unused_nums(copys); if (!puzzle_is_good(copys, params->difficulty)) { debug(("Stripped grid is not good, reverting.\n")); free_game(copys); @@ -1705,6 +1706,11 @@ done: return move; } +static int game_can_format_as_text_now(game_params *params) +{ + return TRUE; +} + /* 'borrowed' from slant.c, mainly. I could have printed it one * character per cell (like debug_state) but that comes out tiny. * 'L' is used for 'light here' because 'O' looks too much like '0' @@ -1835,27 +1841,20 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds, cx = FROMCOORD(x); cy = FROMCOORD(y); action = (button == LEFT_BUTTON) ? FLIP_LIGHT : FLIP_IMPOSSIBLE; - } else if (button == CURSOR_SELECT || + } else if (IS_CURSOR_SELECT(button) || button == 'i' || button == 'I' || button == ' ' || button == '\r' || button == '\n') { - ui->cur_visible = 1; - cx = ui->cur_x; - cy = ui->cur_y; - action = (button == 'i' || button == 'I') ? - FLIP_IMPOSSIBLE : FLIP_LIGHT; - } else if (button == CURSOR_UP || button == CURSOR_DOWN || - button == CURSOR_RIGHT || button == CURSOR_LEFT) { - int dx = 0, dy = 0; - switch (button) { - case CURSOR_UP: dy = -1; break; - case CURSOR_DOWN: dy = 1; break; - case CURSOR_RIGHT: dx = 1; break; - case CURSOR_LEFT: dx = -1; break; - default: assert(!"shouldn't get here"); + if (ui->cur_visible) { + /* Only allow cursor-effect operations if the cursor is visible + * (otherwise you have no idea which square it might be affecting) */ + cx = ui->cur_x; + cy = ui->cur_y; + action = (button == 'i' || button == 'I' || button == CURSOR_SELECT2) ? + FLIP_IMPOSSIBLE : FLIP_LIGHT; } - ui->cur_x += dx; ui->cur_y += dy; - ui->cur_x = min(max(ui->cur_x, 0), state->w - 1); - ui->cur_y = min(max(ui->cur_y, 0), state->h - 1); + ui->cur_visible = 1; + } else if (IS_CURSOR_MOVE(button)) { + move_cursor(button, &ui->cur_x, &ui->cur_y, state->w, state->h, 0); ui->cur_visible = 1; nullret = empty; } else @@ -1870,11 +1869,19 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds, if (flags & F_BLACK) return nullret; if (action == FLIP_LIGHT) { +#ifdef STYLUS_BASED + if (flags & F_IMPOSSIBLE || flags & F_LIGHT) c = 'I'; else c = 'L'; +#else if (flags & F_IMPOSSIBLE) return nullret; c = 'L'; +#endif } else { +#ifdef STYLUS_BASED + if (flags & F_IMPOSSIBLE || flags & F_LIGHT) c = 'L'; else c = 'I'; +#else if (flags & F_LIGHT) return nullret; c = 'I'; +#endif } sprintf(buf, "%c%d,%d", (int)c, cx, cy); break; @@ -1956,7 +1963,7 @@ static void game_set_size(drawing *dr, game_drawstate *ds, ds->crad = 3*(tilesize-1)/8; } -static float *game_colours(frontend *fe, game_state *state, int *ncolours) +static float *game_colours(frontend *fe, int *ncolours) { float *ret = snewn(3 * NCOLOURS, float); int i; @@ -2059,7 +2066,7 @@ static void tile_redraw(drawing *dr, game_drawstate *ds, game_state *state, draw_rect(dr, dx, dy, TILE_SIZE, TILE_SIZE, COL_BLACK); if (ds_flags & DF_NUMBERED) { int ccol = (ds_flags & DF_NUMBERWRONG) ? COL_ERROR : COL_LIGHT; - char str[10]; + char str[32]; /* We know that this won't change over the course of the game * so it's OK to ignore this when calculating whether or not @@ -2077,10 +2084,19 @@ static void tile_redraw(drawing *dr, game_drawstate *ds, game_state *state, int lcol = (ds_flags & DF_OVERLAP) ? COL_ERROR : COL_LIGHT; draw_circle(dr, dx + TILE_SIZE/2, dy + TILE_SIZE/2, TILE_RADIUS, lcol, COL_BLACK); - } else if (ds_flags & DF_IMPOSSIBLE) { - int rlen = TILE_SIZE / 4; - draw_rect(dr, dx + TILE_SIZE/2 - rlen/2, dy + TILE_SIZE/2 - rlen/2, - rlen, rlen, COL_BLACK); + } else if ((ds_flags & DF_IMPOSSIBLE)) { + static int draw_blobs_when_lit = -1; + if (draw_blobs_when_lit < 0) { + char *env = getenv("LIGHTUP_LIT_BLOBS"); + draw_blobs_when_lit = (!env || (env[0] == 'y' || + env[0] == 'Y')); + } + if (!(ds_flags & DF_LIT) || draw_blobs_when_lit) { + int rlen = TILE_SIZE / 4; + draw_rect(dr, dx + TILE_SIZE/2 - rlen/2, + dy + TILE_SIZE/2 - rlen/2, + rlen, rlen, COL_BLACK); + } } } @@ -2144,9 +2160,9 @@ static float game_flash_length(game_state *oldstate, game_state *newstate, return 0.0F; } -static int game_wants_statusbar(void) +static int game_status(game_state *state) { - return FALSE; + return state->completed ? +1 : 0; } static int game_timing_state(game_state *state, game_ui *ui) @@ -2162,8 +2178,8 @@ static void game_print_size(game_params *params, float *x, float *y) * I'll use 6mm squares by default. */ game_compute_size(params, 600, &pw, &ph); - *x = pw / 100.0; - *y = ph / 100.0; + *x = pw / 100.0F; + *y = ph / 100.0F; } static void game_print(drawing *dr, game_state *state, int tilesize) @@ -2175,8 +2191,7 @@ static void game_print(drawing *dr, game_state *state, int tilesize) /* Ick: fake up `ds->tilesize' for macro expansion purposes */ game_drawstate ads, *ds = &ads; - ads.tilesize = tilesize; - ds->crad = 3*(tilesize-1)/8; + game_set_size(dr, ds, NULL, tilesize); /* * Border. @@ -2204,7 +2219,7 @@ static void game_print(drawing *dr, game_state *state, int tilesize) if (ds_flags & DF_BLACK) { draw_rect(dr, dx, dy, TILE_SIZE, TILE_SIZE, ink); if (ds_flags & DF_NUMBERED) { - char str[10]; + char str[32]; sprintf(str, "%d", GRID(state, lights, x, y)); draw_text(dr, dx + TILE_SIZE/2, dy + TILE_SIZE/2, FONT_VARIABLE, TILE_SIZE*3/5, @@ -2222,7 +2237,7 @@ static void game_print(drawing *dr, game_state *state, int tilesize) #endif const struct game thegame = { - "Light Up", "games.lightup", + "Light Up", "games.lightup", "lightup", default_params, game_fetch_preset, decode_params, @@ -2237,7 +2252,7 @@ const struct game thegame = { dup_game, free_game, TRUE, solve_game, - TRUE, game_text_format, + TRUE, game_can_format_as_text_now, game_text_format, new_ui, free_ui, encode_ui, @@ -2252,10 +2267,11 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_status, TRUE, FALSE, game_print_size, game_print, - game_wants_statusbar, + FALSE, /* wants_statusbar */ FALSE, game_timing_state, - 0, /* mouse_priorities */ + 0, /* flags */ }; #ifdef STANDALONE_SOLVER