nissy-classic

Stable branch of nissy
git clone https://git.tronto.net/nissy-classic
Download | Log | Files | Refs | README | LICENSE

commit b6fd508253bce9225dd24b6538adb5093892c4f8
parent e528411b1a1be45e1bef0f525fd0f411c9689b11
Author: Sebastiano Tronto <sebastiano.tronto@gmail.com>
Date:   Tue,  7 Dec 2021 12:20:51 +0100

Little performance improvement in optimal solver - more to come!

Diffstat:
MMakefile | 2+-
MTODO.md | 3+++
Mnissy | 0
Dnissy-2.0beta4.tar.gz | 0
Anissy-2.0beta5.tar.gz | 0
Mnissy.exe | 0
Msrc/cubetypes.h | 36+++++++++++++++++++++++++++---------
Msrc/solve.c | 125++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/steps.c | 277+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/steps.h | 2++
10 files changed, 278 insertions(+), 167 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ # See LICENSE file for copyright and license details. -VERSION = 2.0beta4 +VERSION = 2.0beta5 PREFIX = /usr/local MANPREFIX = ${PREFIX}/share/man diff --git a/TODO.md b/TODO.md @@ -14,6 +14,9 @@ It's more of a personal reminder than anything else. * invert an alg ### More steps for `solve` +* "slow" optimal solver, using drud table but all the tricks + of khuge (+ trick to avoid 180° moves when one of the inverse + probes returns exactly the target value) * QTM optimal solving * Block-building steps (cross, roux blocks, ...) * Other common steps (LSE, ...) diff --git a/nissy b/nissy Binary files differ. diff --git a/nissy-2.0beta4.tar.gz b/nissy-2.0beta4.tar.gz Binary files differ. diff --git a/nissy-2.0beta5.tar.gz b/nissy-2.0beta5.tar.gz Binary files differ. diff --git a/nissy.exe b/nissy.exe Binary files differ. diff --git a/src/cubetypes.h b/src/cubetypes.h @@ -81,8 +81,9 @@ typedef struct commandargs CommandArgs; typedef struct coordinate Coordinate; typedef struct cube Cube; typedef struct cubearray CubeArray; -typedef struct cubetarget CubeTarget; typedef struct dfsdata DfsData; +typedef struct estimatedata EstimateData; +typedef struct localinfo LocalInfo; typedef struct piecefilter PieceFilter; typedef struct prunedata PruneData; typedef struct solveoptions SolveOptions; @@ -92,7 +93,7 @@ typedef struct threaddata ThreadData; typedef Cube (*AntiIndexer) (uint64_t); typedef bool (*Checker) (Cube); -typedef int (*Estimator) (CubeTarget); +typedef int (*Estimator) (EstimateData *); typedef bool (*Validator) (Alg *); typedef void (*Exec) (CommandArgs *); typedef uint64_t (*Indexer) (Cube); @@ -196,13 +197,6 @@ cubearray }; struct -cubetarget -{ - Cube cube; - int target; -}; - -struct dfsdata { int d; @@ -211,6 +205,7 @@ dfsdata bool niss; Move last1; Move last2; + EstimateData * ed; AlgList * sols; pthread_mutex_t * sols_mutex; Alg * current_alg; @@ -220,6 +215,29 @@ dfsdata }; struct +estimatedata +{ + Cube cube; + int target; + Move lastmove; + uint64_t movebitmask; + LocalInfo * li; +}; + +struct +localinfo +{ + int corners; + int normal_ud; + int normal_fb; + int normal_rl; + int inverse_ud; + int inverse_fb; + int inverse_rl; + int prev_ret; +}; + +struct piecefilter { bool epose; diff --git a/src/solve.c b/src/solve.c @@ -2,7 +2,7 @@ /* Local functions ***********************************************************/ -static bool allowed_next(Move move, DfsData *dd); +static bool allowed_next(Move move, DfsData *dd, uint64_t mm); static void dfs(Cube c, Step *s, SolveOptions *opts, DfsData *dd); static void dfs_branch(Cube c, Step *s, SolveOptions *os, DfsData *dd); static bool dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd); @@ -14,8 +14,11 @@ static void multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, /* Local functions ***********************************************************/ static bool -allowed_next(Move move, DfsData *dd) +allowed_next(Move move, DfsData *dd, uint64_t mm) { + if ((1 << move) & mm) + return false; + if (!possible_next(dd->last2, dd->last1, move)) return false; @@ -45,23 +48,21 @@ dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd) { bool b = false; int i; + uint64_t mm; Move m, l1, l2; + LocalInfo li; l1 = dd->last1; l2 = dd->last2; + li = *(dd->ed->li); + mm = dd->ed->movebitmask; for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) { - /* - pthread_mutex_lock(dd->sols_mutex); - b = dd->sols->len >= opts->max_solutions; - pthread_mutex_unlock(dd->sols_mutex); - */ - if (b) break; m = dd->sorted_moves[i]; - if (allowed_next(m, dd)) { + if (allowed_next(m, dd, mm)) { dd->last2 = dd->last1; dd->last1 = m; append_move(dd->current_alg, m, dd->niss); @@ -69,8 +70,9 @@ dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd) dfs(apply_move(m, c), s, opts, dd); dd->current_alg->len--; - dd->last2 = l2; - dd->last1 = l1; + dd->last2 = l2; + dd->last1 = l1; + *(dd->ed->li) = li; } } } @@ -99,13 +101,17 @@ dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd) static void dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd) { - Move l1 = dd->last1, l2 = dd->last2; - CubeTarget ct; + Move l1, l2; + EstimateData *ed; - ct.cube = apply_move(inverse_move(l1), (Cube){0}); - ct.target = 1; + l1 = dd->last1; + l2 = dd->last2; + + ed = malloc(sizeof(EstimateData)); + ed->cube = apply_move(inverse_move(l1), (Cube){0}); + ed->target = 1; - if (dd->current_alg->len == 0 || s->estimate(ct)) { + if (dd->current_alg->len == 0 || s->estimate(ed)) { dd->niss = true; dd->last1 = NULLMOVE; dd->last2 = NULLMOVE; @@ -116,28 +122,31 @@ dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd) dd->last2 = l2; dd->niss = false; } + + free(ed); } static bool dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd) { - bool b = false; + bool b; - CubeTarget ct = { - .cube = c, - .target = dd->d - dd->current_alg->len - }; + dd->ed->cube = c; + dd->ed->target = dd->d - dd->current_alg->len; + dd->ed->lastmove = dd->last1; + dd->ed->movebitmask = 0; - dd->lb = s->estimate(ct); + dd->lb = s->estimate(dd->ed); if (opts->can_niss && !dd->niss) dd->lb = MIN(1, dd->lb); - if (dd->current_alg->len + dd->lb > dd->d) - return true; - - pthread_mutex_lock(dd->sols_mutex); - b = dd->sols->len >= opts->max_solutions; - pthread_mutex_unlock(dd->sols_mutex); + if (dd->current_alg->len + dd->lb > dd->d) { + b = true; + } else { + pthread_mutex_lock(dd->sols_mutex); + b = dd->sols->len >= opts->max_solutions; + pthread_mutex_unlock(dd->sols_mutex); + } return b; } @@ -170,30 +179,28 @@ instance_thread(void *arg) apply_move(node->alg->move[0], inverse_cube(td->cube)) : apply_move(node->alg->move[0], td->cube); - dd.d = td->depth; - dd.m = 1; - dd.niss = node->alg->inv[0]; - dd.lb = -1; - dd.last1 = node->alg->move[0]; - dd.last2 = NULLMOVE; - dd.sols = td->sols; - dd.sols_mutex = td->sols_mutex; - dd.current_alg = new_alg(""); + dd.d = td->depth; + dd.m = 1; + dd.niss = node->alg->inv[0]; + dd.lb = -1; + dd.last1 = node->alg->move[0]; + dd.last2 = NULLMOVE; + dd.sols = td->sols; + dd.sols_mutex = td->sols_mutex; + dd.current_alg = new_alg(""); append_move(dd.current_alg, node->alg->move[0], node->alg->inv[0]); - dd.sorted_moves = td->sorted_moves; - dd.move_position = td->move_position; - -/* - pthread_mutex_lock(td->sols_mutex); - printf("Starting thread %d with move: ", td->thid); - print_alg(dd.current_alg, false); - pthread_mutex_unlock(td->sols_mutex); -*/ + dd.sorted_moves = td->sorted_moves; + dd.move_position = td->move_position; + dd.ed = malloc(sizeof(EstimateData)); + dd.ed->movebitmask = 0; + dd.ed->li = new_localinfo(); dfs(c, td->step, td->opts, &dd); free_alg(dd.current_alg); + free_localinfo(dd.ed->li); + free(dd.ed); } return NULL; @@ -223,6 +230,7 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) moveset_to_list(s->moveset, sorted_moves); movelist_to_position(sorted_moves, move_position); + for (i = 0; sorted_moves[i] != NULLMOVE; i++) { alg = new_alg(""); append_move(alg, sorted_moves[i], false); @@ -268,9 +276,11 @@ AlgList * solve(Cube cube, Step *step, SolveOptions *opts) { int d; - AlgList *sols = new_alglist(); + AlgList *sols; AlgListNode *node; Cube c; + EstimateData *ed; + bool b; prepare_step(step); @@ -278,19 +288,30 @@ solve(Cube cube, Step *step, SolveOptions *opts) step->pre_trans = step->detect(cube); c = apply_trans(step->pre_trans, cube); + sols = new_alglist(); + if (step->ready != NULL && !step->ready(c)) { fprintf(stderr, "Cube not ready for solving step: "); fprintf(stderr, "%s\n", step->ready_msg); return sols; } - if (step->estimate((CubeTarget){.cube = c, .target = 0}) == 0 && - opts->min_moves == 0) { - append_alg(sols, new_alg("")); - return sols; + if (opts->min_moves == 0) { + ed = malloc(sizeof(EstimateData)); + ed->cube = cube; + ed->target = 0; + ed->li = new_localinfo(); + b = step->estimate(ed) == 0; + free_localinfo(ed->li); + free(ed); + + if (b) { + append_alg(sols, new_alg("")); + return sols; + } } - for (d = MAX(1, opts->min_moves); + for (d = opts->min_moves; d <= opts->max_moves && !(sols->len && opts->optimal_only) && sols->len < opts->max_solutions; diff --git a/src/steps.c b/src/steps.c @@ -1,5 +1,7 @@ #include "steps.h" +#define UPDATECHECKSTOP(a, b, c) if ((a=(MAX((a),(b))))>(c)) return (a); + /* Checkers, estimators and validators ***************************************/ static bool check_centers(Cube cube); @@ -7,24 +9,24 @@ static bool check_eofb(Cube cube); static bool check_drud(Cube cube); static bool check_htr(Cube cube); -static int estimate_eoany_HTM(CubeTarget ct); -static int estimate_eofb_HTM(CubeTarget ct); -static int estimate_coany_HTM(CubeTarget ct); -static int estimate_coud_HTM(CubeTarget ct); -static int estimate_coany_URF(CubeTarget ct); -static int estimate_coud_URF(CubeTarget ct); -static int estimate_corners_HTM(CubeTarget ct); -static int estimate_cornershtr_HTM(CubeTarget ct); -static int estimate_corners_URF(CubeTarget ct); -static int estimate_cornershtr_URF(CubeTarget ct); -static int estimate_drany_HTM(CubeTarget ct); -static int estimate_drud_HTM(CubeTarget ct); -static int estimate_drud_eofb(CubeTarget ct); -static int estimate_dr_eofb(CubeTarget ct); -static int estimate_drudfin_drud(CubeTarget ct); -static int estimate_htr_drud(CubeTarget ct); -static int estimate_htrfin_htr(CubeTarget ct); -static int estimate_optimal_HTM(CubeTarget ct); +static int estimate_eoany_HTM(EstimateData *ed); +static int estimate_eofb_HTM(EstimateData *ed); +static int estimate_coany_HTM(EstimateData *ed); +static int estimate_coud_HTM(EstimateData *ed); +static int estimate_coany_URF(EstimateData *ed); +static int estimate_coud_URF(EstimateData *ed); +static int estimate_corners_HTM(EstimateData *ed); +static int estimate_cornershtr_HTM(EstimateData *ed); +static int estimate_corners_URF(EstimateData *ed); +static int estimate_cornershtr_URF(EstimateData *ed); +static int estimate_drany_HTM(EstimateData *ed); +static int estimate_drud_HTM(EstimateData *ed); +static int estimate_drud_eofb(EstimateData *ed); +static int estimate_dr_eofb(EstimateData *ed); +static int estimate_drudfin_drud(EstimateData *ed); +static int estimate_htr_drud(EstimateData *ed); +static int estimate_htrfin_htr(EstimateData *ed); +static int estimate_optimal_HTM(EstimateData *ed); static bool always_valid(Alg *alg); static bool validate_singlecw_ending(Alg *alg); @@ -799,90 +801,106 @@ check_htr(Cube cube) } static int -estimate_eoany_HTM(CubeTarget ct) +estimate_eoany_HTM(EstimateData *ed) { int r1, r2, r3; - r1 = ptableval(&pd_eofb_HTM, ct.cube); - r2 = ptableval(&pd_eofb_HTM, apply_trans(ur, ct.cube)); - r3 = ptableval(&pd_eofb_HTM, apply_trans(fd, ct.cube)); + r1 = ptableval(&pd_eofb_HTM, ed->cube); + r2 = ptableval(&pd_eofb_HTM, apply_trans(ur, ed->cube)); + r3 = ptableval(&pd_eofb_HTM, apply_trans(fd, ed->cube)); return MIN(r1, MIN(r2, r3)); } static int -estimate_eofb_HTM(CubeTarget ct) +estimate_eofb_HTM(EstimateData *ed) { - return ptableval(&pd_eofb_HTM, ct.cube); + return ptableval(&pd_eofb_HTM, ed->cube); } static int -estimate_coany_HTM(CubeTarget ct) +estimate_coany_HTM(EstimateData *ed) { int r1, r2, r3; - r1 = ptableval(&pd_coud_HTM, ct.cube); - r2 = ptableval(&pd_coud_HTM, apply_trans(rf, ct.cube)); - r3 = ptableval(&pd_coud_HTM, apply_trans(fd, ct.cube)); + r1 = ptableval(&pd_coud_HTM, ed->cube); + r2 = ptableval(&pd_coud_HTM, apply_trans(rf, ed->cube)); + r3 = ptableval(&pd_coud_HTM, apply_trans(fd, ed->cube)); return MIN(r1, MIN(r2, r3)); } static int -estimate_coud_HTM(CubeTarget ct) +estimate_coud_HTM(EstimateData *ed) { - return ptableval(&pd_coud_HTM, ct.cube); + return ptableval(&pd_coud_HTM, ed->cube); } static int -estimate_coany_URF(CubeTarget ct) +estimate_coany_URF(EstimateData *ed) { int r1, r2, r3; - CubeTarget ct2, ct3; + EstimateData *ed2, *ed3; + + ed2 = malloc(sizeof(EstimateData)); + ed3 = malloc(sizeof(EstimateData)); - ct2.cube = apply_trans(rf, ct.cube); - ct2.target = ct.target; + ed2->cube = apply_trans(rf, ed->cube); + ed2->target = ed->target; - ct3.cube = apply_trans(fd, ct.cube); - ct3.target = ct.target; + ed3->cube = apply_trans(fd, ed->cube); + ed3->target = ed->target; - r1 = estimate_coud_URF(ct); - r2 = estimate_coud_URF(ct2); - r3 = estimate_coud_URF(ct3); + r1 = estimate_coud_URF(ed); + r2 = estimate_coud_URF(ed2); + r3 = estimate_coud_URF(ed3); + + free(ed2); + free(ed3); return MIN(r1, MIN(r2, r3)); } static int -estimate_coud_URF(CubeTarget ct) +estimate_coud_URF(EstimateData *ed) { /* TODO: I can improve this by checking first the orientation of * the corner in DBL and use that as a reference */ - CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target}; - CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target}; + EstimateData *ed2, *ed3; + + ed2 = malloc(sizeof(EstimateData)); + ed2->cube = apply_move(z, ed->cube); + ed2->target = ed->target; - int ud = estimate_coud_HTM(ct); - int rl = estimate_coud_HTM(ct2); - int fb = estimate_coud_HTM(ct3); + ed3 = malloc(sizeof(EstimateData)); + ed3->cube = apply_move(x, ed->cube); + ed3->target = ed->target; + + int ud = estimate_coud_HTM(ed); + int rl = estimate_coud_HTM(ed2); + int fb = estimate_coud_HTM(ed3); + + free(ed2); + free(ed3); return MIN(ud, MIN(rl, fb)); } static int -estimate_corners_HTM(CubeTarget ct) +estimate_corners_HTM(EstimateData *ed) { - return ptableval(&pd_corners_HTM, ct.cube); + return ptableval(&pd_corners_HTM, ed->cube); } static int -estimate_cornershtr_HTM(CubeTarget ct) +estimate_cornershtr_HTM(EstimateData *ed) { - return ptableval(&pd_cornershtr_HTM, ct.cube); + return ptableval(&pd_cornershtr_HTM, ed->cube); } static int -estimate_cornershtr_URF(CubeTarget ct) +estimate_cornershtr_URF(EstimateData *ed) { /* TODO: I can improve this by checking first the corner in DBL * and use that as a reference */ @@ -891,8 +909,8 @@ estimate_cornershtr_URF(CubeTarget ct) Trans i; for (i = 0; i < NROTATIONS; i++) { - ct.cube = apply_alg(rotation_alg(i), ct.cube); - c = estimate_cornershtr_HTM(ct); + ed->cube = apply_alg(rotation_alg(i), ed->cube); + c = estimate_cornershtr_HTM(ed); ret = MIN(ret, c); } @@ -900,7 +918,7 @@ estimate_cornershtr_URF(CubeTarget ct) } static int -estimate_corners_URF(CubeTarget ct) +estimate_corners_URF(EstimateData *ed) { /* TODO: I can improve this by checking first the corner in DBL * and use that as a reference */ @@ -909,8 +927,8 @@ estimate_corners_URF(CubeTarget ct) Trans i; for (i = 0; i < NROTATIONS; i++) { - ct.cube = apply_alg(rotation_alg(i), ct.cube); - c = estimate_corners_HTM(ct); + ed->cube = apply_alg(rotation_alg(i), ed->cube); + c = estimate_corners_HTM(ed); ret = MIN(ret, c); } @@ -918,104 +936,130 @@ estimate_corners_URF(CubeTarget ct) } static int -estimate_drany_HTM(CubeTarget ct) +estimate_drany_HTM(EstimateData *ed) { int r1, r2, r3; - r1 = ptableval(&pd_drud_sym16_HTM, ct.cube); - r2 = ptableval(&pd_drud_sym16_HTM, apply_trans(rf, ct.cube)); - r3 = ptableval(&pd_drud_sym16_HTM, apply_trans(fd, ct.cube)); + r1 = ptableval(&pd_drud_sym16_HTM, ed->cube); + r2 = ptableval(&pd_drud_sym16_HTM, apply_trans(rf, ed->cube)); + r3 = ptableval(&pd_drud_sym16_HTM, apply_trans(fd, ed->cube)); return MIN(r1, MIN(r2, r3)); } static int -estimate_drud_HTM(CubeTarget ct) +estimate_drud_HTM(EstimateData *ed) { - return ptableval(&pd_drud_sym16_HTM, ct.cube); + return ptableval(&pd_drud_sym16_HTM, ed->cube); } static int -estimate_drud_eofb(CubeTarget ct) +estimate_drud_eofb(EstimateData *ed) { - return ptableval(&pd_drud_eofb, ct.cube); + return ptableval(&pd_drud_eofb, ed->cube); } static int -estimate_dr_eofb(CubeTarget ct) +estimate_dr_eofb(EstimateData *ed) { int r1, r2; - r1 = ptableval(&pd_drud_eofb, ct.cube); - r2 = ptableval(&pd_drud_eofb, apply_trans(rf, ct.cube)); + r1 = ptableval(&pd_drud_eofb, ed->cube); + r2 = ptableval(&pd_drud_eofb, apply_trans(rf, ed->cube)); return MIN(r1, r2); } static int -estimate_drudfin_drud(CubeTarget ct) +estimate_drudfin_drud(EstimateData *ed) { - int val = ptableval(&pd_drudfin_noE_sym16_drud, ct.cube); + int val = ptableval(&pd_drudfin_noE_sym16_drud, ed->cube); if (val != 0) return val; - return ct.cube.epose % 24 == 0 ? 0 : 1; + return ed->cube.epose % 24 == 0 ? 0 : 1; } static int -estimate_htr_drud(CubeTarget ct) +estimate_htr_drud(EstimateData *ed) { - return ptableval(&pd_htr_drud, ct.cube); + return ptableval(&pd_htr_drud, ed->cube); } static int -estimate_htrfin_htr(CubeTarget ct) +estimate_htrfin_htr(EstimateData *ed) { - return ptableval(&pd_htrfin_htr, ct.cube); + return ptableval(&pd_htrfin_htr, ed->cube); } static int -estimate_optimal_HTM(CubeTarget ct) +estimate_optimal_HTM(EstimateData *ed) { - int dr1, dr2, dr3, cor, ret; - Cube inv; + int ret = -1; + Move lbase; + Cube cubeaux, inv; - dr1 = ptableval(&pd_khuge_HTM, ct.cube); - cor = estimate_corners_HTM(ct); - ret = MAX(dr1, cor); - if (ret > ct.target) - return ret; + ed->li->corners = ptableval(&pd_corners_HTM, ed->cube); + UPDATECHECKSTOP(ret, ed->li->corners, ed->target); - dr2 = ptableval(&pd_khuge_HTM, apply_trans(rf, ct.cube)); - ret = MAX(ret, dr2); - if (ret > ct.target) - return ret; + ed->li->normal_ud = ptableval(&pd_khuge_HTM, ed->cube); + UPDATECHECKSTOP(ret, ed->li->normal_ud, ed->target); - dr3 = ptableval(&pd_khuge_HTM, apply_trans(fd, ct.cube)); - if (dr1 == dr2 && dr2 == dr3 && dr1 != 0) - dr3++; - ret = MAX(ret, dr3); - if (ret > ct.target || ret == 0) - return ret; + cubeaux = apply_trans(fd, ed->cube); + ed->li->normal_fb = ptableval(&pd_khuge_HTM, cubeaux); + UPDATECHECKSTOP(ret, ed->li->normal_fb, ed->target); - /* Inverse cube probing */ + cubeaux = apply_trans(rf, ed->cube); + ed->li->normal_rl = ptableval(&pd_khuge_HTM, cubeaux); + UPDATECHECKSTOP(ret, ed->li->normal_rl, ed->target); - inv = inverse_cube(ct.cube); - dr1 = ptableval(&pd_khuge_HTM, inv); - ret = MAX(ret, dr1); - if (ret > ct.target) + if (ret == 0) return ret; - dr2 = ptableval(&pd_khuge_HTM, apply_trans(rf, inv)); - ret = MAX(ret, dr2); - if (ret > ct.target) - return ret; - - dr3 = ptableval(&pd_khuge_HTM, apply_trans(fd, inv)); - if (dr1 == dr2 && dr2 == dr3 && dr1 != 0) - dr3++; - return MAX(ret, dr3); + if (ed->li->normal_ud == ed->li->normal_fb && + ed->li->normal_fb == ed->li->normal_rl) + UPDATECHECKSTOP(ret, ed->li->normal_ud + 1, ed->target); + + /* TODO: avoid computation of inverse if unnecessary */ + lbase = base_move(ed->lastmove); + inv = inverse_cube(ed->cube); + + if ((lbase != U && lbase != D) || + (ed->li->inverse_ud == -1)) { + ed->li->inverse_ud = ptableval(&pd_khuge_HTM, inv); + } + UPDATECHECKSTOP(ret, ed->li->inverse_ud, ed->target); + + if ((lbase != F && lbase != B) || + (ed->li->inverse_fb == -1)) { + cubeaux = apply_trans(fd, inv); + ed->li->inverse_fb = ptableval(&pd_khuge_HTM, cubeaux); + } + UPDATECHECKSTOP(ret, ed->li->inverse_fb, ed->target); + + if ((lbase != R && lbase != L) || + (ed->li->inverse_rl == -1)) { + cubeaux = apply_trans(rf, inv); + ed->li->inverse_rl = ptableval(&pd_khuge_HTM, cubeaux); + } + UPDATECHECKSTOP(ret, ed->li->inverse_rl, ed->target); + + if (ed->li->inverse_ud == ed->li->inverse_fb && + ed->li->inverse_fb == ed->li->inverse_rl) + UPDATECHECKSTOP(ret, ed->li->inverse_ud + 1, ed->target); + + if (ed->li->inverse_ud == ed->target) + ed->movebitmask |= (1<<U) | (1<<U2) | (1<<U3) | + (1<<D) | (1<<D2) | (1<<D3); + if (ed->li->inverse_fb == ed->target) + ed->movebitmask |= (1<<F) | (1<<F2) | (1<<F3) | + (1<<B) | (1<<B2) | (1<<B3); + if (ed->li->inverse_rl == ed->target) + ed->movebitmask |= (1<<R) | (1<<R2) | (1<<R3) | + (1<<L) | (1<<L2) | (1<<L3); + + return ret; } static bool @@ -1076,6 +1120,29 @@ detect_pretrans_drud(Cube cube) /* Public functions **********************************************************/ void +free_localinfo(LocalInfo *li) +{ + free(li); +} + +LocalInfo * +new_localinfo() +{ + LocalInfo *ret = malloc(sizeof(LocalInfo)); + + ret->corners = -1; + ret->normal_ud = -1; + ret->normal_fb = -1; + ret->normal_rl = -1; + ret->inverse_ud = -1; + ret->inverse_fb = -1; + ret->inverse_rl = -1; + ret->prev_ret = -1; + + return ret; +} + +void prepare_step(Step *step) { int i; diff --git a/src/steps.h b/src/steps.h @@ -7,6 +7,8 @@ extern Step * steps[NSTEPS]; +void free_localinfo(LocalInfo *li); +LocalInfo * new_localinfo(); void prepare_step(Step *step); #endif