diff options
Diffstat (limited to 'loopy.c')
| -rw-r--r-- | loopy.c | 185 |
1 files changed, 91 insertions, 94 deletions
@@ -1097,7 +1097,7 @@ static char *game_text_format(const game_state *state) assert(state->grid_type == 0); /* Work out the basic size unit */ - f = g->faces; /* first face */ + f = g->faces[0]; /* first face */ assert(f->order == 4); /* The dots are ordered clockwise, so the two opposite * corners are guaranteed to span the square */ @@ -1120,7 +1120,7 @@ static char *game_text_format(const game_state *state) /* Fill in edge info */ for (i = 0; i < g->num_edges; i++) { - grid_edge *e = g->edges + i; + grid_edge *e = g->edges[i]; /* Cell coordinates, from (0,0) to (w-1,h-1) */ int x1 = (e->dot1->x - g->lowest_x) / cell_size; int x2 = (e->dot2->x - g->lowest_x) / cell_size; @@ -1148,7 +1148,7 @@ static char *game_text_format(const game_state *state) for (i = 0; i < g->num_faces; i++) { int x1, x2, y1, y2; - f = g->faces + i; + f = g->faces[i]; assert(f->order == 4); /* Cell coordinates, from (0,0) to (w-1,h-1) */ x1 = (f->dots[0]->x - g->lowest_x) / cell_size; @@ -1228,26 +1228,26 @@ static bool solver_set_line(solver_state *sstate, int i, #endif g = state->game_grid; - e = g->edges + i; + e = g->edges[i]; /* Update the cache for both dots and both faces affected by this. */ if (line_new == LINE_YES) { - sstate->dot_yes_count[e->dot1 - g->dots]++; - sstate->dot_yes_count[e->dot2 - g->dots]++; + sstate->dot_yes_count[e->dot1->index]++; + sstate->dot_yes_count[e->dot2->index]++; if (e->face1) { - sstate->face_yes_count[e->face1 - g->faces]++; + sstate->face_yes_count[e->face1->index]++; } if (e->face2) { - sstate->face_yes_count[e->face2 - g->faces]++; + sstate->face_yes_count[e->face2->index]++; } } else { - sstate->dot_no_count[e->dot1 - g->dots]++; - sstate->dot_no_count[e->dot2 - g->dots]++; + sstate->dot_no_count[e->dot1->index]++; + sstate->dot_no_count[e->dot2->index]++; if (e->face1) { - sstate->face_no_count[e->face1 - g->faces]++; + sstate->face_no_count[e->face1->index]++; } if (e->face2) { - sstate->face_no_count[e->face2 - g->faces]++; + sstate->face_no_count[e->face2->index]++; } } @@ -1271,10 +1271,10 @@ static bool merge_dots(solver_state *sstate, int edge_index) { int i, j, len; grid *g = sstate->state->game_grid; - grid_edge *e = g->edges + edge_index; + grid_edge *e = g->edges[edge_index]; - i = e->dot1 - g->dots; - j = e->dot2 - g->dots; + i = e->dot1->index; + j = e->dot2->index; i = dsf_canonify(sstate->dotdsf, i); j = dsf_canonify(sstate->dotdsf, j); @@ -1332,12 +1332,12 @@ static int dot_order(const game_state* state, int dot, char line_type) { int n = 0; grid *g = state->game_grid; - grid_dot *d = g->dots + dot; + grid_dot *d = g->dots[dot]; int i; for (i = 0; i < d->order; i++) { grid_edge *e = d->edges[i]; - if (state->lines[e - g->edges] == line_type) + if (state->lines[e->index] == line_type) ++n; } return n; @@ -1349,12 +1349,12 @@ static int face_order(const game_state* state, int face, char line_type) { int n = 0; grid *g = state->game_grid; - grid_face *f = g->faces + face; + grid_face *f = g->faces[face]; int i; for (i = 0; i < f->order; i++) { grid_edge *e = f->edges[i]; - if (state->lines[e - g->edges] == line_type) + if (state->lines[e->index] == line_type) ++n; } return n; @@ -1375,10 +1375,10 @@ static bool dot_setall(solver_state *sstate, int dot, return false; g = state->game_grid; - d = g->dots + dot; + d = g->dots[dot]; for (i = 0; i < d->order; i++) { - int line_index = d->edges[i] - g->edges; + int line_index = d->edges[i]->index; if (state->lines[line_index] == old_type) { r = solver_set_line(sstate, line_index, new_type); assert(r); @@ -1402,10 +1402,10 @@ static bool face_setall(solver_state *sstate, int face, return false; g = state->game_grid; - f = g->faces + face; + f = g->faces[face]; for (i = 0; i < f->order; i++) { - int line_index = f->edges[i] - g->edges; + int line_index = f->edges[i]->index; if (state->lines[line_index] == old_type) { r = solver_set_line(sstate, line_index, new_type); assert(r); @@ -1434,7 +1434,7 @@ static void add_full_clues(game_state *state, random_state *rs) * algorithm does work, and there aren't any GREY faces still there. */ memset(clues, 0, g->num_faces); for (i = 0; i < g->num_edges; i++) { - grid_edge *e = g->edges + i; + grid_edge *e = g->edges[i]; grid_face *f1 = e->face1; grid_face *f2 = e->face2; enum face_colour c1 = FACE_COLOUR(f1); @@ -1442,8 +1442,8 @@ static void add_full_clues(game_state *state, random_state *rs) assert(c1 != FACE_GREY); assert(c2 != FACE_GREY); if (c1 != c2) { - if (f1) clues[f1 - g->faces]++; - if (f2) clues[f2 - g->faces]++; + if (f1) clues[f1->index]++; + if (f2) clues[f2->index]++; } } sfree(board); @@ -1725,8 +1725,8 @@ static bool check_completion(game_state *state) /* Build the dsf. */ for (i = 0; i < g->num_edges; i++) { if (state->lines[i] == LINE_YES) { - grid_edge *e = g->edges + i; - int d1 = e->dot1 - g->dots, d2 = e->dot2 - g->dots; + grid_edge *e = g->edges[i]; + int d1 = e->dot1->index, d2 = e->dot2->index; dsf_merge(dsf, d1, d2); } } @@ -1751,10 +1751,10 @@ static bool check_completion(game_state *state) int unknown = dot_order(state, i, LINE_UNKNOWN); if ((yes == 1 && unknown == 0) || (yes >= 3)) { /* violation, so mark all YES edges as errors */ - grid_dot *d = g->dots + i; + grid_dot *d = g->dots[i]; int j; for (j = 0; j < d->order; j++) { - int e = d->edges[j] - g->edges; + int e = d->edges[j]->index; if (state->lines[e] == LINE_YES) state->line_errors[e] = true; } @@ -1817,8 +1817,8 @@ static bool check_completion(game_state *state) */ for (i = 0; i < g->num_edges; i++) { if (state->lines[i] == LINE_YES) { - grid_edge *e = g->edges + i; - int d1 = e->dot1 - g->dots; /* either endpoint is good enough */ + grid_edge *e = g->edges[i]; + int d1 = e->dot1->index; /* either endpoint is good enough */ int comp = dsf_canonify(dsf, d1); if ((component_state[comp] == COMP_PATH && -1 != largest_comp) || @@ -1916,11 +1916,10 @@ static int dline_index_from_dot(grid *g, grid_dot *d, int i) if (i2 == d->order) i2 = 0; e2 = d->edges[i2]; #endif - ret = 2 * (e - g->edges) + ((e->dot1 == d) ? 1 : 0); + ret = 2 * (e->index) + ((e->dot1 == d) ? 1 : 0); #ifdef DEBUG_DLINES printf("dline_index_from_dot: d=%d,i=%d, edges [%d,%d] - %d\n", - (int)(d - g->dots), i, (int)(e - g->edges), - (int)(e2 - g->edges), ret); + (int)(d->index), i, (int)(e->index), (int)(e2 ->index), ret); #endif return ret; } @@ -1939,11 +1938,10 @@ static int dline_index_from_face(grid *g, grid_face *f, int i) if (i2 < 0) i2 += f->order; e2 = f->edges[i2]; #endif - ret = 2 * (e - g->edges) + ((e->dot1 == d) ? 1 : 0); + ret = 2 * (e->index) + ((e->dot1 == d) ? 1 : 0); #ifdef DEBUG_DLINES printf("dline_index_from_face: f=%d,i=%d, edges [%d,%d] - %d\n", - (int)(f - g->faces), i, (int)(e - g->edges), - (int)(e2 - g->edges), ret); + (int)(f->index), i, (int)(e->index), (int)(e2->index), ret); #endif return ret; } @@ -2001,9 +1999,9 @@ static bool dline_set_opp_atleastone(solver_state *sstate, opp2 = opp + 1; if (opp2 == N) opp2 = 0; /* Check if opp, opp2 point to LINE_UNKNOWNs */ - if (state->lines[d->edges[opp] - g->edges] != LINE_UNKNOWN) + if (state->lines[d->edges[opp]->index] != LINE_UNKNOWN) continue; - if (state->lines[d->edges[opp2] - g->edges] != LINE_UNKNOWN) + if (state->lines[d->edges[opp2]->index] != LINE_UNKNOWN) continue; /* Found opposite UNKNOWNS and they're next to each other */ opp_dline_index = dline_index_from_dot(g, d, opp); @@ -2025,18 +2023,18 @@ static bool face_setall_identical(solver_state *sstate, int face_index, bool retval = false; game_state *state = sstate->state; grid *g = state->game_grid; - grid_face *f = g->faces + face_index; + grid_face *f = g->faces[face_index]; int N = f->order; int i, j; int can1, can2; bool inv1, inv2; for (i = 0; i < N; i++) { - int line1_index = f->edges[i] - g->edges; + int line1_index = f->edges[i]->index; if (state->lines[line1_index] != LINE_UNKNOWN) continue; for (j = i + 1; j < N; j++) { - int line2_index = f->edges[j] - g->edges; + int line2_index = f->edges[j]->index; if (state->lines[line2_index] != LINE_UNKNOWN) continue; @@ -2060,9 +2058,8 @@ static void find_unknowns(game_state *state, int *e /* Returned edge indices */) { int c = 0; - grid *g = state->game_grid; while (c < expected_count) { - int line_index = *edge_list - g->edges; + int line_index = (*edge_list)->index; if (state->lines[line_index] == LINE_UNKNOWN) { e[c] = line_index; c++; @@ -2191,7 +2188,7 @@ static int trivial_deductions(solver_state *sstate) /* Per-face deductions */ for (i = 0; i < g->num_faces; i++) { - grid_face *f = g->faces + i; + grid_face *f = g->faces[i]; if (sstate->face_solved[i]) continue; @@ -2249,22 +2246,22 @@ static int trivial_deductions(solver_state *sstate) int j, k, e1, e2, e, d; for (j = 0; j < f->order; j++) { - e1 = f->edges[j] - g->edges; - e2 = f->edges[j+1 < f->order ? j+1 : 0] - g->edges; + e1 = f->edges[j]->index; + e2 = f->edges[j+1 < f->order ? j+1 : 0]->index; - if (g->edges[e1].dot1 == g->edges[e2].dot1 || - g->edges[e1].dot1 == g->edges[e2].dot2) { - d = g->edges[e1].dot1 - g->dots; + if (g->edges[e1]->dot1 == g->edges[e2]->dot1 || + g->edges[e1]->dot1 == g->edges[e2]->dot2) { + d = g->edges[e1]->dot1->index; } else { - assert(g->edges[e1].dot2 == g->edges[e2].dot1 || - g->edges[e1].dot2 == g->edges[e2].dot2); - d = g->edges[e1].dot2 - g->dots; + assert(g->edges[e1]->dot2 == g->edges[e2]->dot1 || + g->edges[e1]->dot2 == g->edges[e2]->dot2); + d = g->edges[e1]->dot2->index; } if (state->lines[e1] == LINE_UNKNOWN && state->lines[e2] == LINE_UNKNOWN) { - for (k = 0; k < g->dots[d].order; k++) { - int e = g->dots[d].edges[k] - g->edges; + for (k = 0; k < g->dots[d]->order; k++) { + int e = g->dots[d]->edges[k]->index; if (state->lines[e] == LINE_YES) goto found; /* multi-level break */ } @@ -2278,7 +2275,7 @@ static int trivial_deductions(solver_state *sstate) * they're e1 and e2. */ for (j = 0; j < f->order; j++) { - e = f->edges[j] - g->edges; + e = f->edges[j]->index; if (state->lines[e] == LINE_UNKNOWN && e != e1 && e != e2) { bool r = solver_set_line(sstate, e, LINE_YES); assert(r); @@ -2292,7 +2289,7 @@ static int trivial_deductions(solver_state *sstate) /* Per-dot deductions */ for (i = 0; i < g->num_dots; i++) { - grid_dot *d = g->dots + i; + grid_dot *d = g->dots[i]; int yes, no, unknown; if (sstate->dot_solved[i]) @@ -2389,7 +2386,7 @@ static int dline_deductions(solver_state *sstate) for (i = 0; i < g->num_faces; i++) { int maxs[MAX_FACE_SIZE][MAX_FACE_SIZE]; int mins[MAX_FACE_SIZE][MAX_FACE_SIZE]; - grid_face *f = g->faces + i; + grid_face *f = g->faces[i]; int N = f->order; int j,m; int clue = state->clues[i]; @@ -2400,7 +2397,7 @@ static int dline_deductions(solver_state *sstate) /* Calculate the (j,j+1) entries */ for (j = 0; j < N; j++) { - int edge_index = f->edges[j] - g->edges; + int edge_index = f->edges[j]->index; int dline_index; enum line_state line1 = state->lines[edge_index]; enum line_state line2; @@ -2411,7 +2408,7 @@ static int dline_deductions(solver_state *sstate) mins[j][k] = (line1 == LINE_YES) ? 1 : 0; /* Calculate the (j,j+2) entries */ dline_index = dline_index_from_face(g, f, k); - edge_index = f->edges[k] - g->edges; + edge_index = f->edges[k]->index; line2 = state->lines[edge_index]; k++; if (k >= N) k = 0; @@ -2456,7 +2453,7 @@ static int dline_deductions(solver_state *sstate) for (j = 0; j < N; j++) { int k; grid_edge *e = f->edges[j]; - int line_index = e - g->edges; + int line_index = e->index; int dline_index; if (state->lines[line_index] != LINE_UNKNOWN) @@ -2491,7 +2488,7 @@ static int dline_deductions(solver_state *sstate) if (sstate->diff >= DIFF_TRICKY) { /* Now see if we can make dline deduction for edges{j,j+1} */ e = f->edges[k]; - if (state->lines[e - g->edges] != LINE_UNKNOWN) + if (state->lines[e->index] != LINE_UNKNOWN) /* Only worth doing this for an UNKNOWN,UNKNOWN pair. * Dlines where one of the edges is known, are handled in the * dot-deductions */ @@ -2523,7 +2520,7 @@ static int dline_deductions(solver_state *sstate) /* ------ Dot deductions ------ */ for (i = 0; i < g->num_dots; i++) { - grid_dot *d = g->dots + i; + grid_dot *d = g->dots[i]; int N = d->order; int yes, no, unknown; int j; @@ -2541,8 +2538,8 @@ static int dline_deductions(solver_state *sstate) k = j + 1; if (k >= N) k = 0; dline_index = dline_index_from_dot(g, d, j); - line1_index = d->edges[j] - g->edges; - line2_index = d->edges[k] - g->edges; + line1_index = d->edges[j]->index; + line2_index = d->edges[k] ->index; line1 = state->lines[line1_index]; line2 = state->lines[line2_index]; @@ -2639,7 +2636,7 @@ static int dline_deductions(solver_state *sstate) int opp_index; if (opp == j || opp == k) continue; - opp_index = d->edges[opp] - g->edges; + opp_index = d->edges[opp]->index; if (state->lines[opp_index] == LINE_UNKNOWN) { solver_set_line(sstate, opp_index, LINE_YES); @@ -2690,7 +2687,7 @@ static int linedsf_deductions(solver_state *sstate) if (clue < 0) continue; - N = g->faces[i].order; + N = g->faces[i]->order; yes = sstate->face_yes_count[i]; if (yes + 1 == clue) { if (face_setall_identical(sstate, i, LINE_NO)) @@ -2708,14 +2705,14 @@ static int linedsf_deductions(solver_state *sstate) /* Deductions with small number of LINE_UNKNOWNs, based on overall * parity of lines. */ - diff_tmp = parity_deductions(sstate, g->faces[i].edges, + diff_tmp = parity_deductions(sstate, g->faces[i]->edges, (clue - yes) % 2, unknown); diff = min(diff, diff_tmp); } /* ------ Dot deductions ------ */ for (i = 0; i < g->num_dots; i++) { - grid_dot *d = g->dots + i; + grid_dot *d = g->dots[i]; int N = d->order; int j; int yes, no, unknown; @@ -2728,12 +2725,12 @@ static int linedsf_deductions(solver_state *sstate) int can1, can2; bool inv1, inv2; int j2; - line1_index = d->edges[j] - g->edges; + line1_index = d->edges[j]->index; if (state->lines[line1_index] != LINE_UNKNOWN) continue; j2 = j + 1; if (j2 == N) j2 = 0; - line2_index = d->edges[j2] - g->edges; + line2_index = d->edges[j2]->index; if (state->lines[line2_index] != LINE_UNKNOWN) continue; /* Infer dline flags from linedsf */ @@ -2855,9 +2852,9 @@ static int loop_deductions(solver_state *sstate) * loop it would create is a solution. */ for (i = 0; i < g->num_edges; i++) { - grid_edge *e = g->edges + i; - int d1 = e->dot1 - g->dots; - int d2 = e->dot2 - g->dots; + grid_edge *e = g->edges[i]; + int d1 = e->dot1->index; + int d2 = e->dot2->index; int eqclass, val; if (state->lines[i] != LINE_UNKNOWN) continue; @@ -2894,13 +2891,13 @@ static int loop_deductions(solver_state *sstate) */ sm1_nearby = 0; if (e->face1) { - int f = e->face1 - g->faces; + int f = e->face1->index; int c = state->clues[f]; if (c >= 0 && sstate->face_yes_count[f] == c - 1) sm1_nearby++; } if (e->face2) { - int f = e->face2 - g->faces; + int f = e->face2->index; int c = state->clues[f]; if (c >= 0 && sstate->face_yes_count[f] == c - 1) sm1_nearby++; @@ -3065,7 +3062,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, if (e == NULL) return NULL; - i = e - g->edges; + i = e->index; /* I think it's only possible to play this game with mouse clicks, sorry */ /* Maybe will add mouse drag support some time */ @@ -3126,7 +3123,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, for (j = n_found = 0; j < dot->order; j++) { grid_edge *e_candidate = dot->edges[j]; - int i_candidate = e_candidate - g->edges; + int i_candidate = e_candidate->index; if (e_candidate != e_this && (ui->autofollow == AF_FIXED || state->lines[i] == LINE_NO || @@ -3137,7 +3134,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, } if (n_found != 1 || - state->lines[e_next - g->edges] != state->lines[i]) + state->lines[e_next->index] != state->lines[i]) break; if (e_next == e) { @@ -3164,7 +3161,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, } e_this = e_next; movelen += sprintf(movebuf+movelen, "%d%c", - (int)(e_this - g->edges), button_char); + (int)(e_this->index), button_char); } autofollow_done:; } @@ -3237,7 +3234,7 @@ static void grid_to_screen(const game_drawstate *ds, const grid *g, static void face_text_pos(const game_drawstate *ds, const grid *g, grid_face *f, int *xret, int *yret) { - int faceindex = f - g->faces; + int faceindex = f->index; /* * Return the cached position for this face, if we've already @@ -3280,7 +3277,7 @@ static void game_redraw_clue(drawing *dr, game_drawstate *ds, const game_state *state, int i) { grid *g = state->game_grid; - grid_face *f = g->faces + i; + grid_face *f = g->faces[i]; int x, y; char c[20]; @@ -3345,7 +3342,7 @@ static void game_redraw_line(drawing *dr, game_drawstate *ds,const game_ui *ui, const game_state *state, int i, int phase) { grid *g = state->game_grid; - grid_edge *e = g->edges + i; + grid_edge *e = g->edges[i]; int x1, x2, y1, y2; int line_colour; @@ -3384,7 +3381,7 @@ static void game_redraw_dot(drawing *dr, game_drawstate *ds, const game_state *state, int i) { grid *g = state->game_grid; - grid_dot *d = g->dots + i; + grid_dot *d = g->dots[i]; int x, y; grid_to_screen(ds, g, d->x, d->y, &x, &y); @@ -3415,20 +3412,20 @@ static void game_redraw_in_rect(drawing *dr, game_drawstate *ds, for (i = 0; i < g->num_faces; i++) { if (state->clues[i] >= 0) { - face_text_bbox(ds, g, &g->faces[i], &bx, &by, &bw, &bh); + face_text_bbox(ds, g, g->faces[i], &bx, &by, &bw, &bh); if (boxes_intersect(x, y, w, h, bx, by, bw, bh)) game_redraw_clue(dr, ds, state, i); } } for (phase = 0; phase < NPHASES; phase++) { for (i = 0; i < g->num_edges; i++) { - edge_bbox(ds, g, &g->edges[i], &bx, &by, &bw, &bh); + edge_bbox(ds, g, g->edges[i], &bx, &by, &bw, &bh); if (boxes_intersect(x, y, w, h, bx, by, bw, bh)) game_redraw_line(dr, ds, ui, state, i, phase); } } for (i = 0; i < g->num_dots; i++) { - dot_bbox(ds, g, &g->dots[i], &bx, &by, &bw, &bh); + dot_bbox(ds, g, g->dots[i], &bx, &by, &bw, &bh); if (boxes_intersect(x, y, w, h, bx, by, bw, bh)) game_redraw_dot(dr, ds, state, i); } @@ -3488,7 +3485,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, /* First, trundle through the faces. */ for (i = 0; i < g->num_faces; i++) { - grid_face *f = g->faces + i; + grid_face *f = g->faces[i]; int sides = f->order; int yes_order, no_order; bool clue_mistake; @@ -3588,7 +3585,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, /* Right. Now we roll up our sleeves. */ for (i = 0; i < nfaces; i++) { - grid_face *f = g->faces + faces[i]; + grid_face *f = g->faces[faces[i]]; int x, y, w, h; face_text_bbox(ds, g, f, &x, &y, &w, &h); @@ -3596,7 +3593,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, } for (i = 0; i < nedges; i++) { - grid_edge *e = g->edges + edges[i]; + grid_edge *e = g->edges[edges[i]]; int x, y, w, h; edge_bbox(ds, g, e, &x, &y, &w, &h); @@ -3660,7 +3657,7 @@ static void game_print(drawing *dr, const game_state *state, const game_ui *ui, for (i = 0; i < g->num_dots; i++) { int x, y; - grid_to_screen(ds, g, g->dots[i].x, g->dots[i].y, &x, &y); + grid_to_screen(ds, g, g->dots[i]->x, g->dots[i]->y, &x, &y); draw_circle(dr, x, y, ds->tilesize / 15, ink, ink); } @@ -3668,7 +3665,7 @@ static void game_print(drawing *dr, const game_state *state, const game_ui *ui, * Clues. */ for (i = 0; i < g->num_faces; i++) { - grid_face *f = g->faces + i; + grid_face *f = g->faces[i]; int clue = state->clues[i]; if (clue >= 0) { char c[20]; @@ -3686,7 +3683,7 @@ static void game_print(drawing *dr, const game_state *state, const game_ui *ui, */ for (i = 0; i < g->num_edges; i++) { int thickness = (state->lines[i] == LINE_YES) ? 30 : 150; - grid_edge *e = g->edges + i; + grid_edge *e = g->edges[i]; int x1, y1, x2, y2; grid_to_screen(ds, g, e->dot1->x, e->dot1->y, &x1, &y1); grid_to_screen(ds, g, e->dot2->x, e->dot2->y, &x2, &y2); |