#define TITLE(upper,title,func,lower) #title,
#define ENCODE(upper,title,func,lower) #lower
#define CONFIG(upper,title,func,lower) ":" #title
-enum { DIFFLIST(ENUM) DIFF_IMPOSSIBLE = diff_impossible, DIFF_AMBIGUOUS = diff_ambiguous, DIFF_UNFINISHED = diff_unfinished };
+enum { DIFFLIST(ENUM) DIFFCOUNT, DIFF_IMPOSSIBLE = diff_impossible, DIFF_AMBIGUOUS = diff_ambiguous, DIFF_UNFINISHED = diff_unfinished };
static char const *const unequal_diffnames[] = { DIFFLIST(TITLE) };
static char const unequal_diffchars[] = DIFFLIST(ENCODE);
-#define DIFFCOUNT lenof(unequal_diffchars)
#define DIFFCONFIG DIFFLIST(CONFIG)
#define DEFAULT_PRESET 0
if (solver_show_working) {
printf("%*slink elimination, (%d,%d) > (%d,%d):\n",
solver_recurse_depth*4, "",
- link->gx, link->gy, link->lx, link->ly);
+ link->gx+1, link->gy+1, link->lx+1, link->ly+1);
printf("%*s ruling out %d at (%d,%d)\n",
solver_recurse_depth*4, "",
- j+1, link->gx, link->gy);
+ j+1, link->gx+1, link->gy+1);
}
#endif
cube(link->gx, link->gy, j+1) = FALSE;
if (solver_show_working) {
printf("%*slink elimination, (%d,%d) > (%d,%d):\n",
solver_recurse_depth*4, "",
- link->gx, link->gy, link->lx, link->ly);
+ link->gx+1, link->gy+1, link->lx+1, link->ly+1);
printf("%*s ruling out %d at (%d,%d)\n",
solver_recurse_depth*4, "",
- j+1, link->lx, link->ly);
+ j+1, link->lx+1, link->ly+1);
}
#endif
cube(link->lx, link->ly, j+1) = FALSE;
if (solver_show_working) {
printf("%*sadjacent elimination, (%d,%d):%d %s (%d,%d):\n",
solver_recurse_depth*4, "",
- x, y, grid(x, y), isadjacent ? "|" : "!|", nx, ny);
+ x+1, y+1, grid(x, y), isadjacent ? "|" : "!|", nx+1, ny+1);
printf("%*s ruling out %d at (%d,%d)\n",
- solver_recurse_depth*4, "", n+1, nx, ny);
+ solver_recurse_depth*4, "", n+1, nx+1, ny+1);
}
#endif
cube(nx, ny, n+1) = FALSE;
for (x = 0; x < o; x++) {
for (y = 0; y < o; y++) {
- for (i = 0; i < o; i++) {
+ for (i = 0; i < 4; i++) {
int isadjacent = (GRID(ctx->state, flags, x, y) & adjthan[i].f);
nx = x + adjthan[i].dx, ny = y + adjthan[i].dy;
if (solver_show_working) {
printf("%*sadjacent possible elimination, (%d,%d) %s (%d,%d):\n",
solver_recurse_depth*4, "",
- x, y, isadjacent ? "|" : "!|", nx, ny);
+ x+1, y+1, isadjacent ? "|" : "!|", nx+1, ny+1);
printf("%*s ruling out %d at (%d,%d)\n",
- solver_recurse_depth*4, "", n+1, nx, ny);
+ solver_recurse_depth*4, "", n+1, nx+1, ny+1);
}
#endif
cube(nx, ny, n+1) = FALSE;
#ifdef STANDALONE_SOLVER
if (state->nums[loc] != latin[loc]) {
printf("inconsistency for (%d,%d): state %d latin %d\n",
- x, y, state->nums[loc], latin[loc]);
+ x+1, y+1, state->nums[loc], latin[loc]);
}
#endif
assert(state->nums[loc] == latin[loc]);
#ifdef STANDALONE_SOLVER
if (solver_show_working)
printf("gg_remove_clue: removing %d at (%d,%d)",
- state->nums[loc], x, y);
+ state->nums[loc], x+1, y+1);
#endif
state->nums[loc] = 0;
}
#ifdef STANDALONE_SOLVER
if (solver_show_working)
printf("gg_remove_clue: removing %c at (%d,%d)",
- adjthan[which].c, x, y);
+ adjthan[which].c, x+1, y+1);
#endif
state->flags[loc] &= ~adjthan[which].f;
}
{
int ls = state->order * state->order * 5;
int maxposs = 0, minclues = 5, best = -1, i, j;
- int nposs, nclues, loc, x, y;
+ int nposs, nclues, loc;
#ifdef STANDALONE_SOLVER
if (solver_show_working) {
if (!gg_place_clue(state, scratch[i], latin, 1)) continue;
loc = scratch[i] / 5;
- x = loc % state->order; y = loc / state->order;
for (j = nposs = 0; j < state->order; j++) {
if (state->hints[loc*state->order + j]) nposs++;
}
(nposs == maxposs && nclues < minclues)) {
best = i; maxposs = nposs; minclues = nclues;
#ifdef STANDALONE_SOLVER
- if (solver_show_working)
+ if (solver_show_working) {
+ int x = loc % state->order, y = loc / state->order;
printf("gg_best_clue: b%d (%d,%d) new best [%d poss, %d clues].\n",
- best, x, y, nposs, nclues);
+ best, x+1, y+1, nposs, nclues);
+ }
#endif
}
}
if (!(solved->flags[r] & F_IMMUTABLE))
solved->nums[r] = 0;
}
- r = solver_state(solved, DIFFCOUNT);
+ r = solver_state(solved, DIFFCOUNT-1); /* always use full solver */
if (r > 0) ret = latin_desc(solved->nums, solved->order);
free_game(solved);
return ret;
static void draw_gt(drawing *dr, int ox, int oy,
int dx1, int dy1, int dx2, int dy2, int col)
{
- draw_line(dr, ox, oy, ox+dx1, oy+dy1, col);
- draw_line(dr, ox+dx1, oy+dy1, ox+dx1+dx2, oy+dy1+dy2, col);
+ int coords[12];
+ int xdx = (dx1+dx2 ? 0 : 1), xdy = (dx1+dx2 ? 1 : 0);
+ coords[0] = ox + xdx;
+ coords[1] = oy + xdy;
+ coords[2] = ox + xdx + dx1;
+ coords[3] = oy + xdy + dy1;
+ coords[4] = ox + xdx + dx1 + dx2;
+ coords[5] = oy + xdy + dy1 + dy2;
+ coords[6] = ox - xdx + dx1 + dx2;
+ coords[7] = oy - xdy + dy1 + dy2;
+ coords[8] = ox - xdx + dx1;
+ coords[9] = oy - xdy + dy1;
+ coords[10] = ox - xdx;
+ coords[11] = oy - xdy;
+ draw_polygon(dr, coords, 6, col, col);
}
static void draw_gts(drawing *dr, game_drawstate *ds, int ox, int oy,
- unsigned int f, int col)
+ unsigned int f, int bg, int fg)
{
int g = GAP_SIZE, g2 = (g+1)/2, g4 = (g+1)/4;
/* Draw all the greater-than signs emanating from this tile. */
if (f & F_ADJ_UP) {
+ if (bg >= 0) draw_rect(dr, ox, oy - g, TILE_SIZE, g, bg);
draw_gt(dr, ox+g2, oy-g4, g2, -g2, g2, g2,
- (f & F_ERROR_UP) ? COL_ERROR : col);
+ (f & F_ERROR_UP) ? COL_ERROR : fg);
draw_update(dr, ox, oy-g, TILE_SIZE, g);
}
if (f & F_ADJ_RIGHT) {
+ if (bg >= 0) draw_rect(dr, ox + TILE_SIZE, oy, g, TILE_SIZE, bg);
draw_gt(dr, ox+TILE_SIZE+g4, oy+g2, g2, g2, -g2, g2,
- (f & F_ERROR_RIGHT) ? COL_ERROR : col);
+ (f & F_ERROR_RIGHT) ? COL_ERROR : fg);
draw_update(dr, ox+TILE_SIZE, oy, g, TILE_SIZE);
}
if (f & F_ADJ_DOWN) {
+ if (bg >= 0) draw_rect(dr, ox, oy + TILE_SIZE, TILE_SIZE, g, bg);
draw_gt(dr, ox+g2, oy+TILE_SIZE+g4, g2, g2, g2, -g2,
- (f & F_ERROR_DOWN) ? COL_ERROR : col);
+ (f & F_ERROR_DOWN) ? COL_ERROR : fg);
draw_update(dr, ox, oy+TILE_SIZE, TILE_SIZE, g);
}
if (f & F_ADJ_LEFT) {
+ if (bg >= 0) draw_rect(dr, ox - g, oy, g, TILE_SIZE, bg);
draw_gt(dr, ox-g4, oy+g2, -g2, g2, g2, g2,
- (f & F_ERROR_LEFT) ? COL_ERROR : col);
+ (f & F_ERROR_LEFT) ? COL_ERROR : fg);
draw_update(dr, ox-g, oy, g, TILE_SIZE);
}
}
static void draw_adjs(drawing *dr, game_drawstate *ds, int ox, int oy,
- unsigned int f, int col)
+ unsigned int f, int bg, int fg)
{
int g = GAP_SIZE, g38 = 3*(g+1)/8, g4 = (g+1)/4;
if (f & (F_ADJ_RIGHT|F_ERROR_RIGHT)) {
if (f & F_ADJ_RIGHT) {
draw_rect(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE,
- (f & F_ERROR_RIGHT) ? COL_ERROR : col);
+ (f & F_ERROR_RIGHT) ? COL_ERROR : fg);
} else {
draw_rect_outline(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE, COL_ERROR);
}
- } else {
- draw_rect(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE, COL_BACKGROUND);
+ } else if (bg >= 0) {
+ draw_rect(dr, ox+TILE_SIZE+g38, oy, g4, TILE_SIZE, bg);
}
draw_update(dr, ox+TILE_SIZE, oy, g, TILE_SIZE);
if (f & (F_ADJ_DOWN|F_ERROR_DOWN)) {
if (f & F_ADJ_DOWN) {
draw_rect(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4,
- (f & F_ERROR_DOWN) ? COL_ERROR : col);
+ (f & F_ERROR_DOWN) ? COL_ERROR : fg);
} else {
draw_rect_outline(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4, COL_ERROR);
}
- } else {
- draw_rect(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4, COL_BACKGROUND);
+ } else if (bg >= 0) {
+ draw_rect(dr, ox, oy+TILE_SIZE+g38, TILE_SIZE, g4, bg);
}
draw_update(dr, ox, oy+TILE_SIZE, TILE_SIZE, g);
}
/* Draw the adjacent clue signs. */
if (ds->adjacent)
- draw_adjs(dr, ds, ox, oy, f, COL_GRID);
+ draw_adjs(dr, ds, ox, oy, f, COL_BACKGROUND, COL_GRID);
else
- draw_gts(dr, ds, ox, oy, f, COL_TEXT);
+ draw_gts(dr, ds, ox, oy, f, COL_BACKGROUND, COL_TEXT);
}
static void draw_num(drawing *dr, game_drawstate *ds, int x, int y)
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;
FONT_VARIABLE, TILE_SIZE/2, ALIGN_VCENTRE | ALIGN_HCENTRE,
ink, str);
- if (ds->adjacent)
- draw_adjs(dr, ds, ox, oy, GRID(state, flags, x, y), ink);
+ if (state->adjacent)
+ draw_adjs(dr, ds, ox, oy, GRID(state, flags, x, y), -1, ink);
else
- draw_gts(dr, ds, ox, oy, GRID(state, flags, x, y), ink);
+ draw_gts(dr, ds, ox, oy, GRID(state, flags, x, y), -1, ink);
}
}
}
game_redraw,
game_anim_length,
game_flash_length,
+ game_status,
TRUE, FALSE, game_print_size, game_print,
FALSE, /* wants_statusbar */
FALSE, game_timing_state,