aboutsummaryrefslogtreecommitdiff
path: root/src/solve.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/solve.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/src/solve.c b/src/solve.c
index 79e421d..5a72bba 100644
--- a/src/solve.c
+++ b/src/solve.c
@@ -13,8 +13,10 @@ static void dfs_niss(DfsArg *arg);
13static bool dfs_stop(DfsArg *arg); 13static bool dfs_stop(DfsArg *arg);
14static void * instance_thread(void *arg); 14static void * instance_thread(void *arg);
15static void invert_branch(DfsArg *arg); 15static void invert_branch(DfsArg *arg);
16static void multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d); 16static void multidfs(Cube c, Trans t, Step *s, SolveOptions *opts,
17 AlgList *sols, int d);
17static bool niss_makes_sense(DfsArg *arg); 18static bool niss_makes_sense(DfsArg *arg);
19static bool solvestop(int d, int op, SolveOptions *opts, AlgList *sols);
18 20
19/* Local functions ***********************************************************/ 21/* Local functions ***********************************************************/
20 22
@@ -62,6 +64,7 @@ copy_dfsarg(DfsArg *src, DfsArg *dst)
62{ 64{
63 dst->step = src->step; 65 dst->step = src->step;
64 dst->opts = src->opts; 66 dst->opts = src->opts;
67 dst->t = src->t;
65 dst->cube = src->cube; 68 dst->cube = src->cube;
66 dst->inverse = src->inverse; 69 dst->inverse = src->inverse;
67 dst->d = src->d; 70 dst->d = src->d;
@@ -146,7 +149,7 @@ dfs_check_solved(DfsArg *arg)
146 append_alg(arg->sols, arg->current_alg); 149 append_alg(arg->sols, arg->current_alg);
147 150
148 transform_alg( 151 transform_alg(
149 inverse_trans(arg->step->pre_trans), 152 inverse_trans(arg->t),
150 arg->sols->last->alg 153 arg->sols->last->alg
151 ); 154 );
152 if (arg->step->final) 155 if (arg->step->final)
@@ -260,6 +263,7 @@ instance_thread(void *arg)
260 263
261 darg.step = td->step; 264 darg.step = td->step;
262 darg.opts = td->opts; 265 darg.opts = td->opts;
266 darg.t = td->t;
263 darg.cube = c; 267 darg.cube = c;
264 darg.d = td->depth; 268 darg.d = td->depth;
265 darg.niss = node->alg->inv[0]; 269 darg.niss = node->alg->inv[0];
@@ -304,7 +308,7 @@ invert_branch(DfsArg *arg)
304} 308}
305 309
306static void 310static void
307multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) 311multidfs(Cube c, Trans tr, Step *s, SolveOptions *opts, AlgList *sols, int d)
308{ 312{
309 int i; 313 int i;
310 Alg *alg; 314 Alg *alg;
@@ -324,8 +328,6 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d)
324 328
325 for (i = 0; s->moveset->sorted_moves[i] != NULLMOVE; i++) { 329 for (i = 0; s->moveset->sorted_moves[i] != NULLMOVE; i++) {
326 alg = new_alg(""); 330 alg = new_alg("");
327 /* TODO: start on inverse also in case of final step
328 and ed->sw true */
329 append_move(alg, s->moveset->sorted_moves[i], false); 331 append_move(alg, s->moveset->sorted_moves[i], false);
330 append_alg(start, alg); 332 append_alg(start, alg);
331 if (opts->can_niss) { 333 if (opts->can_niss) {
@@ -338,6 +340,7 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d)
338 340
339 for (i = 0; i < opts->nthreads; i++) { 341 for (i = 0; i < opts->nthreads; i++) {
340 td[i].thid = i; 342 td[i].thid = i;
343 td[i].t = tr;
341 td[i].cube = c; 344 td[i].cube = c;
342 td[i].step = s; 345 td[i].step = s;
343 td[i].depth = d; 346 td[i].depth = d;
@@ -368,47 +371,69 @@ niss_makes_sense(DfsArg *arg)
368 return arg->current_alg->len == 0 || arg->step->is_done(testcube); 371 return arg->current_alg->len == 0 || arg->step->is_done(testcube);
369} 372}
370 373
374static bool
375solvestop(int d, int op, SolveOptions *opts, AlgList *sols)
376{
377 bool opt_done, max_moves_exceeded, max_sols_exceeded;
378
379 opt_done = opts->optimal != -1 && op != -1 && d > opts->optimal + op;
380 max_moves_exceeded = d > opts->max_moves;
381 max_sols_exceeded = sols->len >= opts->max_solutions;
382
383 return opt_done || max_moves_exceeded || max_sols_exceeded;
384}
385
371/* Public functions **********************************************************/ 386/* Public functions **********************************************************/
372 387
373AlgList * 388AlgList *
374solve(Cube cube, Step *step, SolveOptions *opts) 389solve(Cube cube, Step *step, SolveOptions *opts)
375{ 390{
376 int d, op; 391 bool ready;
392 int i, d, op, nt;
377 AlgList *sols; 393 AlgList *sols;
378 Cube c; 394 Cube c;
395 Trans tt[NTRANS];
379 396
380 prepare_step(step, opts); 397 prepare_step(step, opts);
381 398
382 if (step->detect != NULL) 399 if (step->detect != NULL) {
383 step->pre_trans = step->detect(cube); 400 nt = step->detect(cube, tt);
384 c = apply_trans(step->pre_trans, cube); 401 } else {
402 tt[0] = step->pre_trans;
403 ready = step->ready == NULL ||
404 step->ready(apply_trans(tt[0], cube));
405 nt = ready ? 1 : 0;
406 }
385 407
386 sols = new_alglist(); 408 sols = new_alglist();
387 409
388 if (step->ready != NULL && !step->ready(c)) { 410 if (nt == 0) {
389 fprintf(stderr, "Cube not ready for solving step: "); 411 fprintf(stderr, "Cube not ready for solving step: ");
390 fprintf(stderr, "%s\n", step->ready_msg); 412 fprintf(stderr, "%s\n", step->ready_msg);
391 return sols; 413 return sols;
392 } 414 }
393 415
394 if (opts->min_moves == 0 && step->is_done(cube)) { 416 if (opts->min_moves == 0) {
395 append_alg(sols, new_alg("")); 417 for (i = 0; i < nt; i++) {
396 return sols; 418 c = apply_trans(tt[i], cube);
419 if (step->is_done(c)) {
420 append_alg(sols, new_alg(""));
421 return sols;
422 }
423 }
397 } 424 }
398 425
399 op = -1; 426 op = -1;
400 for (d = opts->min_moves; 427 for (d = opts->min_moves; !solvestop(d, op, opts, sols); d++) {
401 d <= opts->max_moves &&
402 !(opts->optimal != -1 && op != -1 && opts->optimal + op < d) &&
403 sols->len < opts->max_solutions;
404 d++) {
405 if (opts->verbose) 428 if (opts->verbose)
406 fprintf(stderr, 429 fprintf(stderr, "Searching depth %d\n", d);
407 "Found %d solutions, searching depth %d...\n", 430
408 sols->len, d); 431 for (i = 0; i < nt && !solvestop(d, op, opts, sols); i++) {
409 multidfs(c, step, opts, sols, d); 432 c = apply_trans(tt[i], cube);
410 if (sols->len > 0 && op == -1) 433 multidfs(c, tt[i], step, opts, sols, d);
411 op = d; 434 if (sols->len > 0 && op == -1)
435 op = d;
436 }
412 } 437 }
413 438
414 return sols; 439 return sols;

Generated with cgit - Back to sebastiano.tronto.net