mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Tracks: Highlight more counting errors if track looks good
Normally, Tracks puts error marks on row and column clues only when one of the existing track or no-track marks will have to be removed to satisfy the clue. This could lead to a situation where the player had built a track from A to B and got neither a win nor a highlighted error because the only error was in a row or column having too few track segments. This commit re-arranges the completion checking so that if there's a complete track from A to B and no spurious track then the game will highlight any clue that isn't matched by the actually laid track. This should mean that any solution with a track from A to B will either be a win or have a highlighted error. This should fix Android issue #266.
This commit is contained in:
118
tracks.c
118
tracks.c
@ -1823,7 +1823,7 @@ static int tracks_neighbour(int vertex, void *vctx)
|
|||||||
static bool check_completion(game_state *state, bool mark)
|
static bool check_completion(game_state *state, bool mark)
|
||||||
{
|
{
|
||||||
int w = state->p.w, h = state->p.h, x, y, i, target;
|
int w = state->p.w, h = state->p.h, x, y, i, target;
|
||||||
bool ret = true;
|
bool ret = true, pathret;
|
||||||
int ntrack, nnotrack, ntrackcomplete;
|
int ntrack, nnotrack, ntrackcomplete;
|
||||||
int *dsf, pathclass;
|
int *dsf, pathclass;
|
||||||
struct findloopstate *fls;
|
struct findloopstate *fls;
|
||||||
@ -1844,58 +1844,6 @@ static bool check_completion(game_state *state, bool mark)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A cell is 'complete', for the purposes of marking the game as
|
|
||||||
* finished, if it has two edges marked as TRACK. But it only has
|
|
||||||
* to have one edge marked as TRACK, or be filled in as trackful
|
|
||||||
* without any specific edges known, to count towards checking
|
|
||||||
* row/column clue errors. */
|
|
||||||
for (x = 0; x < w; x++) {
|
|
||||||
target = state->numbers->numbers[x];
|
|
||||||
ntrack = nnotrack = ntrackcomplete = 0;
|
|
||||||
for (y = 0; y < h; y++) {
|
|
||||||
if (S_E_COUNT(state, x, y, E_TRACK) > 0 ||
|
|
||||||
state->sflags[y*w+x] & S_TRACK)
|
|
||||||
ntrack++;
|
|
||||||
if (S_E_COUNT(state, x, y, E_TRACK) == 2)
|
|
||||||
ntrackcomplete++;
|
|
||||||
if (state->sflags[y*w+x] & S_NOTRACK)
|
|
||||||
nnotrack++;
|
|
||||||
}
|
|
||||||
if (mark) {
|
|
||||||
if (ntrack > target || nnotrack > (h-target)) {
|
|
||||||
debug(("col %d error: target %d, track %d, notrack %d",
|
|
||||||
x, target, ntrack, nnotrack));
|
|
||||||
state->num_errors[x] = 1;
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ntrackcomplete != target)
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
for (y = 0; y < h; y++) {
|
|
||||||
target = state->numbers->numbers[w+y];
|
|
||||||
ntrack = nnotrack = ntrackcomplete = 0;
|
|
||||||
for (x = 0; x < w; x++) {
|
|
||||||
if (S_E_COUNT(state, x, y, E_TRACK) > 0 ||
|
|
||||||
state->sflags[y*w+x] & S_TRACK)
|
|
||||||
ntrack++;
|
|
||||||
if (S_E_COUNT(state, x, y, E_TRACK) == 2)
|
|
||||||
ntrackcomplete++;
|
|
||||||
if (state->sflags[y*w+x] & S_NOTRACK)
|
|
||||||
nnotrack++;
|
|
||||||
}
|
|
||||||
if (mark) {
|
|
||||||
if (ntrack > target || nnotrack > (w-target)) {
|
|
||||||
debug(("row %d error: target %d, track %d, notrack %d",
|
|
||||||
y, target, ntrack, nnotrack));
|
|
||||||
state->num_errors[w+y] = 1;
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ntrackcomplete != target)
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dsf = snewn(w*h, int);
|
dsf = snewn(w*h, int);
|
||||||
dsf_init(dsf, w*h);
|
dsf_init(dsf, w*h);
|
||||||
|
|
||||||
@ -1949,6 +1897,70 @@ static bool check_completion(game_state *state, bool mark)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A cell is 'complete', for the purposes of marking the game as
|
||||||
|
* finished, if it has two edges marked as TRACK. But it only has
|
||||||
|
* to have one edge marked as TRACK, or be filled in as trackful
|
||||||
|
* without any specific edges known, to count towards checking
|
||||||
|
* row/column clue errors.
|
||||||
|
*
|
||||||
|
* This changes if we haven't found any other errors by this
|
||||||
|
* point, so the player has constructed a route from A to B. In
|
||||||
|
* that case, we highlight any row/column where the actually laid
|
||||||
|
* tracks don't match the clue.
|
||||||
|
*/
|
||||||
|
pathret = ret; /* Do we have a plausible solution so far? */
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
target = state->numbers->numbers[x];
|
||||||
|
ntrack = nnotrack = ntrackcomplete = 0;
|
||||||
|
for (y = 0; y < h; y++) {
|
||||||
|
if (S_E_COUNT(state, x, y, E_TRACK) > 0 ||
|
||||||
|
state->sflags[y*w+x] & S_TRACK)
|
||||||
|
ntrack++;
|
||||||
|
if (S_E_COUNT(state, x, y, E_TRACK) == 2)
|
||||||
|
ntrackcomplete++;
|
||||||
|
if (state->sflags[y*w+x] & S_NOTRACK)
|
||||||
|
nnotrack++;
|
||||||
|
}
|
||||||
|
if (mark) {
|
||||||
|
if (ntrack > target || nnotrack > (h-target) ||
|
||||||
|
(pathret && ntrackcomplete != target)) {
|
||||||
|
debug(("col %d error: target %d, track %d, notrack %d, "
|
||||||
|
"pathret %d, trackcomplete %d",
|
||||||
|
x, target, ntrack, nnotrack, pathret, ntrackcomplete));
|
||||||
|
state->num_errors[x] = 1;
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ntrackcomplete != target)
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
for (y = 0; y < h; y++) {
|
||||||
|
target = state->numbers->numbers[w+y];
|
||||||
|
ntrack = nnotrack = ntrackcomplete = 0;
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
if (S_E_COUNT(state, x, y, E_TRACK) > 0 ||
|
||||||
|
state->sflags[y*w+x] & S_TRACK)
|
||||||
|
ntrack++;
|
||||||
|
if (S_E_COUNT(state, x, y, E_TRACK) == 2)
|
||||||
|
ntrackcomplete++;
|
||||||
|
if (state->sflags[y*w+x] & S_NOTRACK)
|
||||||
|
nnotrack++;
|
||||||
|
}
|
||||||
|
if (mark) {
|
||||||
|
if (ntrack > target || nnotrack > (w-target) ||
|
||||||
|
(pathret && ntrackcomplete != target)) {
|
||||||
|
debug(("row %d error: target %d, track %d, notrack %d, "
|
||||||
|
"pathret %d, trackcomplete %d",
|
||||||
|
y, target, ntrack, nnotrack, pathret, ntrackcomplete));
|
||||||
|
state->num_errors[w+y] = 1;
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ntrackcomplete != target)
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (mark)
|
if (mark)
|
||||||
state->completed = ret;
|
state->completed = ret;
|
||||||
sfree(dsf);
|
sfree(dsf);
|
||||||
|
Reference in New Issue
Block a user