Add simple contradiction-driven search mechanism
Gets an about 6% improvement
This commit is contained in:
parent
6e9a6810b3
commit
168cdd8e8e
76
main.c
76
main.c
@ -104,6 +104,70 @@ static update_res_t update(state_t *state, int *x_out, int *y_out)
|
|||||||
return FOUND_NOTHING;
|
return FOUND_NOTHING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static update_res_t
|
||||||
|
search_at(state_t *state, int x, int y, int *x_out, int *y_out)
|
||||||
|
{
|
||||||
|
update_res_t res;
|
||||||
|
|
||||||
|
state_t with_mine;
|
||||||
|
memcpy(&with_mine, state, sizeof(state_t));
|
||||||
|
with_mine.field[x][y] = MINE;
|
||||||
|
do {
|
||||||
|
int res_x, res_y;
|
||||||
|
switch (res = update(&with_mine, &res_x, &res_y)) {
|
||||||
|
case FOUND_MINE:
|
||||||
|
break;
|
||||||
|
case FOUND_SAFE:
|
||||||
|
with_mine.field[res_x][res_y] = SAFE;
|
||||||
|
break;
|
||||||
|
case FOUND_NOTHING:
|
||||||
|
break;
|
||||||
|
case FOUND_CONTRADICTION:
|
||||||
|
*x_out = x;
|
||||||
|
*y_out = y;
|
||||||
|
return FOUND_SAFE;
|
||||||
|
}
|
||||||
|
} while (res == FOUND_MINE);
|
||||||
|
|
||||||
|
state_t with_safe;
|
||||||
|
memcpy(&with_safe, state, sizeof(state_t));
|
||||||
|
with_safe.field[x][y] = SAFE;
|
||||||
|
do {
|
||||||
|
int res_x, res_y;
|
||||||
|
switch (res = update(&with_safe, &res_x, &res_y)) {
|
||||||
|
case FOUND_MINE:
|
||||||
|
break;
|
||||||
|
case FOUND_SAFE:
|
||||||
|
with_safe.field[res_x][res_y] = SAFE;
|
||||||
|
break;
|
||||||
|
case FOUND_NOTHING:
|
||||||
|
break;
|
||||||
|
case FOUND_CONTRADICTION:
|
||||||
|
state->field[x][y] = MINE;
|
||||||
|
return FOUND_MINE;
|
||||||
|
}
|
||||||
|
} while (res == FOUND_MINE);
|
||||||
|
|
||||||
|
return FOUND_NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static update_res_t search(state_t *state, int *x_out, int *y_out)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < HEIGHT; ++y) {
|
||||||
|
for (int x = 0; x < WIDTH; ++x) {
|
||||||
|
if (state->field[x][y] != UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (countadj(state->field, x, y, UNKNOWN) != MAX_ADJ) {
|
||||||
|
update_res_t res = search_at(state, x, y, x_out, y_out);
|
||||||
|
if (res == FOUND_MINE || res == FOUND_SAFE)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FOUND_NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
static status_t solve(int *turns_out)
|
static status_t solve(int *turns_out)
|
||||||
{
|
{
|
||||||
state_t state = { .mines = 0, .unknown = WIDTH * HEIGHT };
|
state_t state = { .mines = 0, .unknown = WIDTH * HEIGHT };
|
||||||
@ -123,7 +187,8 @@ static status_t solve(int *turns_out)
|
|||||||
update_res_t res;
|
update_res_t res;
|
||||||
do {
|
do {
|
||||||
res = update(&state, &x, &y);
|
res = update(&state, &x, &y);
|
||||||
assert(res != FOUND_CONTRADICTION);
|
if (res == FOUND_NOTHING)
|
||||||
|
res = search(&state, &x, &y);
|
||||||
} while (res == FOUND_MINE);
|
} while (res == FOUND_MINE);
|
||||||
|
|
||||||
if (check(state.field) != OK) {
|
if (check(state.field) != OK) {
|
||||||
@ -169,12 +234,17 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nincorrect > 0) {
|
||||||
|
printf(
|
||||||
|
"Fail: %d incorrect! (%0.1f%%)\n", nincorrect,
|
||||||
|
(double)nincorrect / NRUNS);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
const double solved_prop = (double)nsolved / NRUNS;
|
const double solved_prop = (double)nsolved / NRUNS;
|
||||||
const double incorrect_prop = (double)nincorrect / NRUNS;
|
|
||||||
const double first_prop = (double)nfirst / NRUNS;
|
const double first_prop = (double)nfirst / NRUNS;
|
||||||
const double solved_safe_start_prop = (double)nsolved / (NRUNS - nfirst);
|
const double solved_safe_start_prop = (double)nsolved / (NRUNS - nfirst);
|
||||||
printf("Solved %d (%0.1f%%)\n", nsolved, 100 * solved_prop);
|
printf("Solved %d (%0.1f%%)\n", nsolved, 100 * solved_prop);
|
||||||
printf("%d incorrect (%0.1f%%)\n", nincorrect, 100 * incorrect_prop);
|
|
||||||
printf("%d died on first turn (%0.1f%%)\n", nfirst, 100 * first_prop);
|
printf("%d died on first turn (%0.1f%%)\n", nfirst, 100 * first_prop);
|
||||||
printf("%0.1f%% solved on safe start\n", 100 * solved_safe_start_prop);
|
printf("%0.1f%% solved on safe start\n", 100 * solved_safe_start_prop);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user