diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cubetypes.h | 36 | ||||
| -rw-r--r-- | src/solve.c | 125 | ||||
| -rw-r--r-- | src/steps.c | 277 | ||||
| -rw-r--r-- | src/steps.h | 2 |
4 files changed, 274 insertions, 166 deletions
diff --git a/src/cubetypes.h b/src/cubetypes.h index f11f480..3f350af 100644 --- a/src/cubetypes.h +++ b/src/cubetypes.h | |||
| @@ -81,8 +81,9 @@ typedef struct commandargs CommandArgs; | |||
| 81 | typedef struct coordinate Coordinate; | 81 | typedef struct coordinate Coordinate; |
| 82 | typedef struct cube Cube; | 82 | typedef struct cube Cube; |
| 83 | typedef struct cubearray CubeArray; | 83 | typedef struct cubearray CubeArray; |
| 84 | typedef struct cubetarget CubeTarget; | ||
| 85 | typedef struct dfsdata DfsData; | 84 | typedef struct dfsdata DfsData; |
| 85 | typedef struct estimatedata EstimateData; | ||
| 86 | typedef struct localinfo LocalInfo; | ||
| 86 | typedef struct piecefilter PieceFilter; | 87 | typedef struct piecefilter PieceFilter; |
| 87 | typedef struct prunedata PruneData; | 88 | typedef struct prunedata PruneData; |
| 88 | typedef struct solveoptions SolveOptions; | 89 | typedef struct solveoptions SolveOptions; |
| @@ -92,7 +93,7 @@ typedef struct threaddata ThreadData; | |||
| 92 | 93 | ||
| 93 | typedef Cube (*AntiIndexer) (uint64_t); | 94 | typedef Cube (*AntiIndexer) (uint64_t); |
| 94 | typedef bool (*Checker) (Cube); | 95 | typedef bool (*Checker) (Cube); |
| 95 | typedef int (*Estimator) (CubeTarget); | 96 | typedef int (*Estimator) (EstimateData *); |
| 96 | typedef bool (*Validator) (Alg *); | 97 | typedef bool (*Validator) (Alg *); |
| 97 | typedef void (*Exec) (CommandArgs *); | 98 | typedef void (*Exec) (CommandArgs *); |
| 98 | typedef uint64_t (*Indexer) (Cube); | 99 | typedef uint64_t (*Indexer) (Cube); |
| @@ -196,13 +197,6 @@ cubearray | |||
| 196 | }; | 197 | }; |
| 197 | 198 | ||
| 198 | struct | 199 | struct |
| 199 | cubetarget | ||
| 200 | { | ||
| 201 | Cube cube; | ||
| 202 | int target; | ||
| 203 | }; | ||
| 204 | |||
| 205 | struct | ||
| 206 | dfsdata | 200 | dfsdata |
| 207 | { | 201 | { |
| 208 | int d; | 202 | int d; |
| @@ -211,6 +205,7 @@ dfsdata | |||
| 211 | bool niss; | 205 | bool niss; |
| 212 | Move last1; | 206 | Move last1; |
| 213 | Move last2; | 207 | Move last2; |
| 208 | EstimateData * ed; | ||
| 214 | AlgList * sols; | 209 | AlgList * sols; |
| 215 | pthread_mutex_t * sols_mutex; | 210 | pthread_mutex_t * sols_mutex; |
| 216 | Alg * current_alg; | 211 | Alg * current_alg; |
| @@ -220,6 +215,29 @@ dfsdata | |||
| 220 | }; | 215 | }; |
| 221 | 216 | ||
| 222 | struct | 217 | struct |
| 218 | estimatedata | ||
| 219 | { | ||
| 220 | Cube cube; | ||
| 221 | int target; | ||
| 222 | Move lastmove; | ||
| 223 | uint64_t movebitmask; | ||
| 224 | LocalInfo * li; | ||
| 225 | }; | ||
| 226 | |||
| 227 | struct | ||
| 228 | localinfo | ||
| 229 | { | ||
| 230 | int corners; | ||
| 231 | int normal_ud; | ||
| 232 | int normal_fb; | ||
| 233 | int normal_rl; | ||
| 234 | int inverse_ud; | ||
| 235 | int inverse_fb; | ||
| 236 | int inverse_rl; | ||
| 237 | int prev_ret; | ||
| 238 | }; | ||
| 239 | |||
| 240 | struct | ||
| 223 | piecefilter | 241 | piecefilter |
| 224 | { | 242 | { |
| 225 | bool epose; | 243 | bool epose; |
diff --git a/src/solve.c b/src/solve.c index a35a837..881edd6 100644 --- a/src/solve.c +++ b/src/solve.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | /* Local functions ***********************************************************/ | 3 | /* Local functions ***********************************************************/ |
| 4 | 4 | ||
| 5 | static bool allowed_next(Move move, DfsData *dd); | 5 | static bool allowed_next(Move move, DfsData *dd, uint64_t mm); |
| 6 | static void dfs(Cube c, Step *s, SolveOptions *opts, DfsData *dd); | 6 | static void dfs(Cube c, Step *s, SolveOptions *opts, DfsData *dd); |
| 7 | static void dfs_branch(Cube c, Step *s, SolveOptions *os, DfsData *dd); | 7 | static void dfs_branch(Cube c, Step *s, SolveOptions *os, DfsData *dd); |
| 8 | static bool dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd); | 8 | 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, | |||
| 14 | /* Local functions ***********************************************************/ | 14 | /* Local functions ***********************************************************/ |
| 15 | 15 | ||
| 16 | static bool | 16 | static bool |
| 17 | allowed_next(Move move, DfsData *dd) | 17 | allowed_next(Move move, DfsData *dd, uint64_t mm) |
| 18 | { | 18 | { |
| 19 | if ((1 << move) & mm) | ||
| 20 | return false; | ||
| 21 | |||
| 19 | if (!possible_next(dd->last2, dd->last1, move)) | 22 | if (!possible_next(dd->last2, dd->last1, move)) |
| 20 | return false; | 23 | return false; |
| 21 | 24 | ||
| @@ -45,23 +48,21 @@ dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | |||
| 45 | { | 48 | { |
| 46 | bool b = false; | 49 | bool b = false; |
| 47 | int i; | 50 | int i; |
| 51 | uint64_t mm; | ||
| 48 | Move m, l1, l2; | 52 | Move m, l1, l2; |
| 53 | LocalInfo li; | ||
| 49 | 54 | ||
| 50 | l1 = dd->last1; | 55 | l1 = dd->last1; |
| 51 | l2 = dd->last2; | 56 | l2 = dd->last2; |
| 57 | li = *(dd->ed->li); | ||
| 58 | mm = dd->ed->movebitmask; | ||
| 52 | 59 | ||
| 53 | for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) { | 60 | for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) { |
| 54 | /* | ||
| 55 | pthread_mutex_lock(dd->sols_mutex); | ||
| 56 | b = dd->sols->len >= opts->max_solutions; | ||
| 57 | pthread_mutex_unlock(dd->sols_mutex); | ||
| 58 | */ | ||
| 59 | |||
| 60 | if (b) | 61 | if (b) |
| 61 | break; | 62 | break; |
| 62 | 63 | ||
| 63 | m = dd->sorted_moves[i]; | 64 | m = dd->sorted_moves[i]; |
| 64 | if (allowed_next(m, dd)) { | 65 | if (allowed_next(m, dd, mm)) { |
| 65 | dd->last2 = dd->last1; | 66 | dd->last2 = dd->last1; |
| 66 | dd->last1 = m; | 67 | dd->last1 = m; |
| 67 | append_move(dd->current_alg, m, dd->niss); | 68 | append_move(dd->current_alg, m, dd->niss); |
| @@ -69,8 +70,9 @@ dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | |||
| 69 | dfs(apply_move(m, c), s, opts, dd); | 70 | dfs(apply_move(m, c), s, opts, dd); |
| 70 | 71 | ||
| 71 | dd->current_alg->len--; | 72 | dd->current_alg->len--; |
| 72 | dd->last2 = l2; | 73 | dd->last2 = l2; |
| 73 | dd->last1 = l1; | 74 | dd->last1 = l1; |
| 75 | *(dd->ed->li) = li; | ||
| 74 | } | 76 | } |
| 75 | } | 77 | } |
| 76 | } | 78 | } |
| @@ -99,13 +101,17 @@ dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd) | |||
| 99 | static void | 101 | static void |
| 100 | dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | 102 | dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd) |
| 101 | { | 103 | { |
| 102 | Move l1 = dd->last1, l2 = dd->last2; | 104 | Move l1, l2; |
| 103 | CubeTarget ct; | 105 | EstimateData *ed; |
| 104 | 106 | ||
| 105 | ct.cube = apply_move(inverse_move(l1), (Cube){0}); | 107 | l1 = dd->last1; |
| 106 | ct.target = 1; | 108 | l2 = dd->last2; |
| 109 | |||
| 110 | ed = malloc(sizeof(EstimateData)); | ||
| 111 | ed->cube = apply_move(inverse_move(l1), (Cube){0}); | ||
| 112 | ed->target = 1; | ||
| 107 | 113 | ||
| 108 | if (dd->current_alg->len == 0 || s->estimate(ct)) { | 114 | if (dd->current_alg->len == 0 || s->estimate(ed)) { |
| 109 | dd->niss = true; | 115 | dd->niss = true; |
| 110 | dd->last1 = NULLMOVE; | 116 | dd->last1 = NULLMOVE; |
| 111 | dd->last2 = NULLMOVE; | 117 | dd->last2 = NULLMOVE; |
| @@ -116,28 +122,31 @@ dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | |||
| 116 | dd->last2 = l2; | 122 | dd->last2 = l2; |
| 117 | dd->niss = false; | 123 | dd->niss = false; |
| 118 | } | 124 | } |
| 125 | |||
| 126 | free(ed); | ||
| 119 | } | 127 | } |
| 120 | 128 | ||
| 121 | static bool | 129 | static bool |
| 122 | dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | 130 | dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd) |
| 123 | { | 131 | { |
| 124 | bool b = false; | 132 | bool b; |
| 125 | 133 | ||
| 126 | CubeTarget ct = { | 134 | dd->ed->cube = c; |
| 127 | .cube = c, | 135 | dd->ed->target = dd->d - dd->current_alg->len; |
| 128 | .target = dd->d - dd->current_alg->len | 136 | dd->ed->lastmove = dd->last1; |
| 129 | }; | 137 | dd->ed->movebitmask = 0; |
| 130 | 138 | ||
| 131 | dd->lb = s->estimate(ct); | 139 | dd->lb = s->estimate(dd->ed); |
| 132 | if (opts->can_niss && !dd->niss) | 140 | if (opts->can_niss && !dd->niss) |
| 133 | dd->lb = MIN(1, dd->lb); | 141 | dd->lb = MIN(1, dd->lb); |
| 134 | 142 | ||
| 135 | if (dd->current_alg->len + dd->lb > dd->d) | 143 | if (dd->current_alg->len + dd->lb > dd->d) { |
| 136 | return true; | 144 | b = true; |
| 137 | 145 | } else { | |
| 138 | pthread_mutex_lock(dd->sols_mutex); | 146 | pthread_mutex_lock(dd->sols_mutex); |
| 139 | b = dd->sols->len >= opts->max_solutions; | 147 | b = dd->sols->len >= opts->max_solutions; |
| 140 | pthread_mutex_unlock(dd->sols_mutex); | 148 | pthread_mutex_unlock(dd->sols_mutex); |
| 149 | } | ||
| 141 | 150 | ||
| 142 | return b; | 151 | return b; |
| 143 | } | 152 | } |
| @@ -170,30 +179,28 @@ instance_thread(void *arg) | |||
| 170 | apply_move(node->alg->move[0], inverse_cube(td->cube)) : | 179 | apply_move(node->alg->move[0], inverse_cube(td->cube)) : |
| 171 | apply_move(node->alg->move[0], td->cube); | 180 | apply_move(node->alg->move[0], td->cube); |
| 172 | 181 | ||
| 173 | dd.d = td->depth; | 182 | dd.d = td->depth; |
| 174 | dd.m = 1; | 183 | dd.m = 1; |
| 175 | dd.niss = node->alg->inv[0]; | 184 | dd.niss = node->alg->inv[0]; |
| 176 | dd.lb = -1; | 185 | dd.lb = -1; |
| 177 | dd.last1 = node->alg->move[0]; | 186 | dd.last1 = node->alg->move[0]; |
| 178 | dd.last2 = NULLMOVE; | 187 | dd.last2 = NULLMOVE; |
| 179 | dd.sols = td->sols; | 188 | dd.sols = td->sols; |
| 180 | dd.sols_mutex = td->sols_mutex; | 189 | dd.sols_mutex = td->sols_mutex; |
| 181 | dd.current_alg = new_alg(""); | 190 | dd.current_alg = new_alg(""); |
| 182 | append_move(dd.current_alg, node->alg->move[0], | 191 | append_move(dd.current_alg, node->alg->move[0], |
| 183 | node->alg->inv[0]); | 192 | node->alg->inv[0]); |
| 184 | dd.sorted_moves = td->sorted_moves; | 193 | dd.sorted_moves = td->sorted_moves; |
| 185 | dd.move_position = td->move_position; | 194 | dd.move_position = td->move_position; |
| 186 | 195 | dd.ed = malloc(sizeof(EstimateData)); | |
| 187 | /* | 196 | dd.ed->movebitmask = 0; |
| 188 | pthread_mutex_lock(td->sols_mutex); | 197 | dd.ed->li = new_localinfo(); |
| 189 | printf("Starting thread %d with move: ", td->thid); | ||
| 190 | print_alg(dd.current_alg, false); | ||
| 191 | pthread_mutex_unlock(td->sols_mutex); | ||
| 192 | */ | ||
| 193 | 198 | ||
| 194 | dfs(c, td->step, td->opts, &dd); | 199 | dfs(c, td->step, td->opts, &dd); |
| 195 | 200 | ||
| 196 | free_alg(dd.current_alg); | 201 | free_alg(dd.current_alg); |
| 202 | free_localinfo(dd.ed->li); | ||
| 203 | free(dd.ed); | ||
| 197 | } | 204 | } |
| 198 | 205 | ||
| 199 | return NULL; | 206 | return NULL; |
| @@ -223,6 +230,7 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) | |||
| 223 | 230 | ||
| 224 | moveset_to_list(s->moveset, sorted_moves); | 231 | moveset_to_list(s->moveset, sorted_moves); |
| 225 | movelist_to_position(sorted_moves, move_position); | 232 | movelist_to_position(sorted_moves, move_position); |
| 233 | |||
| 226 | for (i = 0; sorted_moves[i] != NULLMOVE; i++) { | 234 | for (i = 0; sorted_moves[i] != NULLMOVE; i++) { |
| 227 | alg = new_alg(""); | 235 | alg = new_alg(""); |
| 228 | append_move(alg, sorted_moves[i], false); | 236 | append_move(alg, sorted_moves[i], false); |
| @@ -268,9 +276,11 @@ AlgList * | |||
| 268 | solve(Cube cube, Step *step, SolveOptions *opts) | 276 | solve(Cube cube, Step *step, SolveOptions *opts) |
| 269 | { | 277 | { |
| 270 | int d; | 278 | int d; |
| 271 | AlgList *sols = new_alglist(); | 279 | AlgList *sols; |
| 272 | AlgListNode *node; | 280 | AlgListNode *node; |
| 273 | Cube c; | 281 | Cube c; |
| 282 | EstimateData *ed; | ||
| 283 | bool b; | ||
| 274 | 284 | ||
| 275 | prepare_step(step); | 285 | prepare_step(step); |
| 276 | 286 | ||
| @@ -278,19 +288,30 @@ solve(Cube cube, Step *step, SolveOptions *opts) | |||
| 278 | step->pre_trans = step->detect(cube); | 288 | step->pre_trans = step->detect(cube); |
| 279 | c = apply_trans(step->pre_trans, cube); | 289 | c = apply_trans(step->pre_trans, cube); |
| 280 | 290 | ||
| 291 | sols = new_alglist(); | ||
| 292 | |||
| 281 | if (step->ready != NULL && !step->ready(c)) { | 293 | if (step->ready != NULL && !step->ready(c)) { |
| 282 | fprintf(stderr, "Cube not ready for solving step: "); | 294 | fprintf(stderr, "Cube not ready for solving step: "); |
| 283 | fprintf(stderr, "%s\n", step->ready_msg); | 295 | fprintf(stderr, "%s\n", step->ready_msg); |
| 284 | return sols; | 296 | return sols; |
| 285 | } | 297 | } |
| 286 | 298 | ||
| 287 | if (step->estimate((CubeTarget){.cube = c, .target = 0}) == 0 && | 299 | if (opts->min_moves == 0) { |
| 288 | opts->min_moves == 0) { | 300 | ed = malloc(sizeof(EstimateData)); |
| 289 | append_alg(sols, new_alg("")); | 301 | ed->cube = cube; |
| 290 | return sols; | 302 | ed->target = 0; |
| 303 | ed->li = new_localinfo(); | ||
| 304 | b = step->estimate(ed) == 0; | ||
| 305 | free_localinfo(ed->li); | ||
| 306 | free(ed); | ||
| 307 | |||
| 308 | if (b) { | ||
| 309 | append_alg(sols, new_alg("")); | ||
| 310 | return sols; | ||
| 311 | } | ||
| 291 | } | 312 | } |
| 292 | 313 | ||
| 293 | for (d = MAX(1, opts->min_moves); | 314 | for (d = opts->min_moves; |
| 294 | d <= opts->max_moves && | 315 | d <= opts->max_moves && |
| 295 | !(sols->len && opts->optimal_only) && | 316 | !(sols->len && opts->optimal_only) && |
| 296 | sols->len < opts->max_solutions; | 317 | sols->len < opts->max_solutions; |
diff --git a/src/steps.c b/src/steps.c index 6478bc2..4646abd 100644 --- a/src/steps.c +++ b/src/steps.c | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | #include "steps.h" | 1 | #include "steps.h" |
| 2 | 2 | ||
| 3 | #define UPDATECHECKSTOP(a, b, c) if ((a=(MAX((a),(b))))>(c)) return (a); | ||
| 4 | |||
| 3 | /* Checkers, estimators and validators ***************************************/ | 5 | /* Checkers, estimators and validators ***************************************/ |
| 4 | 6 | ||
| 5 | static bool check_centers(Cube cube); | 7 | static bool check_centers(Cube cube); |
| @@ -7,24 +9,24 @@ static bool check_eofb(Cube cube); | |||
| 7 | static bool check_drud(Cube cube); | 9 | static bool check_drud(Cube cube); |
| 8 | static bool check_htr(Cube cube); | 10 | static bool check_htr(Cube cube); |
| 9 | 11 | ||
| 10 | static int estimate_eoany_HTM(CubeTarget ct); | 12 | static int estimate_eoany_HTM(EstimateData *ed); |
| 11 | static int estimate_eofb_HTM(CubeTarget ct); | 13 | static int estimate_eofb_HTM(EstimateData *ed); |
| 12 | static int estimate_coany_HTM(CubeTarget ct); | 14 | static int estimate_coany_HTM(EstimateData *ed); |
| 13 | static int estimate_coud_HTM(CubeTarget ct); | 15 | static int estimate_coud_HTM(EstimateData *ed); |
| 14 | static int estimate_coany_URF(CubeTarget ct); | 16 | static int estimate_coany_URF(EstimateData *ed); |
| 15 | static int estimate_coud_URF(CubeTarget ct); | 17 | static int estimate_coud_URF(EstimateData *ed); |
| 16 | static int estimate_corners_HTM(CubeTarget ct); | 18 | static int estimate_corners_HTM(EstimateData *ed); |
| 17 | static int estimate_cornershtr_HTM(CubeTarget ct); | 19 | static int estimate_cornershtr_HTM(EstimateData *ed); |
| 18 | static int estimate_corners_URF(CubeTarget ct); | 20 | static int estimate_corners_URF(EstimateData *ed); |
| 19 | static int estimate_cornershtr_URF(CubeTarget ct); | 21 | static int estimate_cornershtr_URF(EstimateData *ed); |
| 20 | static int estimate_drany_HTM(CubeTarget ct); | 22 | static int estimate_drany_HTM(EstimateData *ed); |
| 21 | static int estimate_drud_HTM(CubeTarget ct); | 23 | static int estimate_drud_HTM(EstimateData *ed); |
| 22 | static int estimate_drud_eofb(CubeTarget ct); | 24 | static int estimate_drud_eofb(EstimateData *ed); |
| 23 | static int estimate_dr_eofb(CubeTarget ct); | 25 | static int estimate_dr_eofb(EstimateData *ed); |
| 24 | static int estimate_drudfin_drud(CubeTarget ct); | 26 | static int estimate_drudfin_drud(EstimateData *ed); |
| 25 | static int estimate_htr_drud(CubeTarget ct); | 27 | static int estimate_htr_drud(EstimateData *ed); |
| 26 | static int estimate_htrfin_htr(CubeTarget ct); | 28 | static int estimate_htrfin_htr(EstimateData *ed); |
| 27 | static int estimate_optimal_HTM(CubeTarget ct); | 29 | static int estimate_optimal_HTM(EstimateData *ed); |
| 28 | 30 | ||
| 29 | static bool always_valid(Alg *alg); | 31 | static bool always_valid(Alg *alg); |
| 30 | static bool validate_singlecw_ending(Alg *alg); | 32 | static bool validate_singlecw_ending(Alg *alg); |
| @@ -799,90 +801,106 @@ check_htr(Cube cube) | |||
| 799 | } | 801 | } |
| 800 | 802 | ||
| 801 | static int | 803 | static int |
| 802 | estimate_eoany_HTM(CubeTarget ct) | 804 | estimate_eoany_HTM(EstimateData *ed) |
| 803 | { | 805 | { |
| 804 | int r1, r2, r3; | 806 | int r1, r2, r3; |
| 805 | 807 | ||
| 806 | r1 = ptableval(&pd_eofb_HTM, ct.cube); | 808 | r1 = ptableval(&pd_eofb_HTM, ed->cube); |
| 807 | r2 = ptableval(&pd_eofb_HTM, apply_trans(ur, ct.cube)); | 809 | r2 = ptableval(&pd_eofb_HTM, apply_trans(ur, ed->cube)); |
| 808 | r3 = ptableval(&pd_eofb_HTM, apply_trans(fd, ct.cube)); | 810 | r3 = ptableval(&pd_eofb_HTM, apply_trans(fd, ed->cube)); |
| 809 | 811 | ||
| 810 | return MIN(r1, MIN(r2, r3)); | 812 | return MIN(r1, MIN(r2, r3)); |
| 811 | } | 813 | } |
| 812 | 814 | ||
| 813 | static int | 815 | static int |
| 814 | estimate_eofb_HTM(CubeTarget ct) | 816 | estimate_eofb_HTM(EstimateData *ed) |
| 815 | { | 817 | { |
| 816 | return ptableval(&pd_eofb_HTM, ct.cube); | 818 | return ptableval(&pd_eofb_HTM, ed->cube); |
| 817 | } | 819 | } |
| 818 | 820 | ||
| 819 | static int | 821 | static int |
| 820 | estimate_coany_HTM(CubeTarget ct) | 822 | estimate_coany_HTM(EstimateData *ed) |
| 821 | { | 823 | { |
| 822 | int r1, r2, r3; | 824 | int r1, r2, r3; |
| 823 | 825 | ||
| 824 | r1 = ptableval(&pd_coud_HTM, ct.cube); | 826 | r1 = ptableval(&pd_coud_HTM, ed->cube); |
| 825 | r2 = ptableval(&pd_coud_HTM, apply_trans(rf, ct.cube)); | 827 | r2 = ptableval(&pd_coud_HTM, apply_trans(rf, ed->cube)); |
| 826 | r3 = ptableval(&pd_coud_HTM, apply_trans(fd, ct.cube)); | 828 | r3 = ptableval(&pd_coud_HTM, apply_trans(fd, ed->cube)); |
| 827 | 829 | ||
| 828 | return MIN(r1, MIN(r2, r3)); | 830 | return MIN(r1, MIN(r2, r3)); |
| 829 | } | 831 | } |
| 830 | 832 | ||
| 831 | static int | 833 | static int |
| 832 | estimate_coud_HTM(CubeTarget ct) | 834 | estimate_coud_HTM(EstimateData *ed) |
| 833 | { | 835 | { |
| 834 | return ptableval(&pd_coud_HTM, ct.cube); | 836 | return ptableval(&pd_coud_HTM, ed->cube); |
| 835 | } | 837 | } |
| 836 | 838 | ||
| 837 | static int | 839 | static int |
| 838 | estimate_coany_URF(CubeTarget ct) | 840 | estimate_coany_URF(EstimateData *ed) |
| 839 | { | 841 | { |
| 840 | int r1, r2, r3; | 842 | int r1, r2, r3; |
| 841 | CubeTarget ct2, ct3; | 843 | EstimateData *ed2, *ed3; |
| 844 | |||
| 845 | ed2 = malloc(sizeof(EstimateData)); | ||
| 846 | ed3 = malloc(sizeof(EstimateData)); | ||
| 842 | 847 | ||
| 843 | ct2.cube = apply_trans(rf, ct.cube); | 848 | ed2->cube = apply_trans(rf, ed->cube); |
| 844 | ct2.target = ct.target; | 849 | ed2->target = ed->target; |
| 845 | 850 | ||
| 846 | ct3.cube = apply_trans(fd, ct.cube); | 851 | ed3->cube = apply_trans(fd, ed->cube); |
| 847 | ct3.target = ct.target; | 852 | ed3->target = ed->target; |
| 848 | 853 | ||
| 849 | r1 = estimate_coud_URF(ct); | 854 | r1 = estimate_coud_URF(ed); |
| 850 | r2 = estimate_coud_URF(ct2); | 855 | r2 = estimate_coud_URF(ed2); |
| 851 | r3 = estimate_coud_URF(ct3); | 856 | r3 = estimate_coud_URF(ed3); |
| 857 | |||
| 858 | free(ed2); | ||
| 859 | free(ed3); | ||
| 852 | 860 | ||
| 853 | return MIN(r1, MIN(r2, r3)); | 861 | return MIN(r1, MIN(r2, r3)); |
| 854 | } | 862 | } |
| 855 | 863 | ||
| 856 | static int | 864 | static int |
| 857 | estimate_coud_URF(CubeTarget ct) | 865 | estimate_coud_URF(EstimateData *ed) |
| 858 | { | 866 | { |
| 859 | /* TODO: I can improve this by checking first the orientation of | 867 | /* TODO: I can improve this by checking first the orientation of |
| 860 | * the corner in DBL and use that as a reference */ | 868 | * the corner in DBL and use that as a reference */ |
| 861 | 869 | ||
| 862 | CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target}; | 870 | EstimateData *ed2, *ed3; |
| 863 | CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target}; | 871 | |
| 872 | ed2 = malloc(sizeof(EstimateData)); | ||
| 873 | ed2->cube = apply_move(z, ed->cube); | ||
| 874 | ed2->target = ed->target; | ||
| 864 | 875 | ||
| 865 | int ud = estimate_coud_HTM(ct); | 876 | ed3 = malloc(sizeof(EstimateData)); |
| 866 | int rl = estimate_coud_HTM(ct2); | 877 | ed3->cube = apply_move(x, ed->cube); |
| 867 | int fb = estimate_coud_HTM(ct3); | 878 | ed3->target = ed->target; |
| 879 | |||
| 880 | int ud = estimate_coud_HTM(ed); | ||
| 881 | int rl = estimate_coud_HTM(ed2); | ||
| 882 | int fb = estimate_coud_HTM(ed3); | ||
| 883 | |||
| 884 | free(ed2); | ||
| 885 | free(ed3); | ||
| 868 | 886 | ||
| 869 | return MIN(ud, MIN(rl, fb)); | 887 | return MIN(ud, MIN(rl, fb)); |
| 870 | } | 888 | } |
| 871 | 889 | ||
| 872 | static int | 890 | static int |
| 873 | estimate_corners_HTM(CubeTarget ct) | 891 | estimate_corners_HTM(EstimateData *ed) |
| 874 | { | 892 | { |
| 875 | return ptableval(&pd_corners_HTM, ct.cube); | 893 | return ptableval(&pd_corners_HTM, ed->cube); |
| 876 | } | 894 | } |
| 877 | 895 | ||
| 878 | static int | 896 | static int |
| 879 | estimate_cornershtr_HTM(CubeTarget ct) | 897 | estimate_cornershtr_HTM(EstimateData *ed) |
| 880 | { | 898 | { |
| 881 | return ptableval(&pd_cornershtr_HTM, ct.cube); | 899 | return ptableval(&pd_cornershtr_HTM, ed->cube); |
| 882 | } | 900 | } |
| 883 | 901 | ||
| 884 | static int | 902 | static int |
| 885 | estimate_cornershtr_URF(CubeTarget ct) | 903 | estimate_cornershtr_URF(EstimateData *ed) |
| 886 | { | 904 | { |
| 887 | /* TODO: I can improve this by checking first the corner in DBL | 905 | /* TODO: I can improve this by checking first the corner in DBL |
| 888 | * and use that as a reference */ | 906 | * and use that as a reference */ |
| @@ -891,8 +909,8 @@ estimate_cornershtr_URF(CubeTarget ct) | |||
| 891 | Trans i; | 909 | Trans i; |
| 892 | 910 | ||
| 893 | for (i = 0; i < NROTATIONS; i++) { | 911 | for (i = 0; i < NROTATIONS; i++) { |
| 894 | ct.cube = apply_alg(rotation_alg(i), ct.cube); | 912 | ed->cube = apply_alg(rotation_alg(i), ed->cube); |
| 895 | c = estimate_cornershtr_HTM(ct); | 913 | c = estimate_cornershtr_HTM(ed); |
| 896 | ret = MIN(ret, c); | 914 | ret = MIN(ret, c); |
| 897 | } | 915 | } |
| 898 | 916 | ||
| @@ -900,7 +918,7 @@ estimate_cornershtr_URF(CubeTarget ct) | |||
| 900 | } | 918 | } |
| 901 | 919 | ||
| 902 | static int | 920 | static int |
| 903 | estimate_corners_URF(CubeTarget ct) | 921 | estimate_corners_URF(EstimateData *ed) |
| 904 | { | 922 | { |
| 905 | /* TODO: I can improve this by checking first the corner in DBL | 923 | /* TODO: I can improve this by checking first the corner in DBL |
| 906 | * and use that as a reference */ | 924 | * and use that as a reference */ |
| @@ -909,8 +927,8 @@ estimate_corners_URF(CubeTarget ct) | |||
| 909 | Trans i; | 927 | Trans i; |
| 910 | 928 | ||
| 911 | for (i = 0; i < NROTATIONS; i++) { | 929 | for (i = 0; i < NROTATIONS; i++) { |
| 912 | ct.cube = apply_alg(rotation_alg(i), ct.cube); | 930 | ed->cube = apply_alg(rotation_alg(i), ed->cube); |
| 913 | c = estimate_corners_HTM(ct); | 931 | c = estimate_corners_HTM(ed); |
| 914 | ret = MIN(ret, c); | 932 | ret = MIN(ret, c); |
| 915 | } | 933 | } |
| 916 | 934 | ||
| @@ -918,104 +936,130 @@ estimate_corners_URF(CubeTarget ct) | |||
| 918 | } | 936 | } |
| 919 | 937 | ||
| 920 | static int | 938 | static int |
| 921 | estimate_drany_HTM(CubeTarget ct) | 939 | estimate_drany_HTM(EstimateData *ed) |
| 922 | { | 940 | { |
| 923 | int r1, r2, r3; | 941 | int r1, r2, r3; |
| 924 | 942 | ||
| 925 | r1 = ptableval(&pd_drud_sym16_HTM, ct.cube); | 943 | r1 = ptableval(&pd_drud_sym16_HTM, ed->cube); |
| 926 | r2 = ptableval(&pd_drud_sym16_HTM, apply_trans(rf, ct.cube)); | 944 | r2 = ptableval(&pd_drud_sym16_HTM, apply_trans(rf, ed->cube)); |
| 927 | r3 = ptableval(&pd_drud_sym16_HTM, apply_trans(fd, ct.cube)); | 945 | r3 = ptableval(&pd_drud_sym16_HTM, apply_trans(fd, ed->cube)); |
| 928 | 946 | ||
| 929 | return MIN(r1, MIN(r2, r3)); | 947 | return MIN(r1, MIN(r2, r3)); |
| 930 | } | 948 | } |
| 931 | 949 | ||
| 932 | static int | 950 | static int |
| 933 | estimate_drud_HTM(CubeTarget ct) | 951 | estimate_drud_HTM(EstimateData *ed) |
| 934 | { | 952 | { |
| 935 | return ptableval(&pd_drud_sym16_HTM, ct.cube); | 953 | return ptableval(&pd_drud_sym16_HTM, ed->cube); |
| 936 | } | 954 | } |
| 937 | 955 | ||
| 938 | static int | 956 | static int |
| 939 | estimate_drud_eofb(CubeTarget ct) | 957 | estimate_drud_eofb(EstimateData *ed) |
| 940 | { | 958 | { |
| 941 | return ptableval(&pd_drud_eofb, ct.cube); | 959 | return ptableval(&pd_drud_eofb, ed->cube); |
| 942 | } | 960 | } |
| 943 | 961 | ||
| 944 | static int | 962 | static int |
| 945 | estimate_dr_eofb(CubeTarget ct) | 963 | estimate_dr_eofb(EstimateData *ed) |
| 946 | { | 964 | { |
| 947 | int r1, r2; | 965 | int r1, r2; |
| 948 | 966 | ||
| 949 | r1 = ptableval(&pd_drud_eofb, ct.cube); | 967 | r1 = ptableval(&pd_drud_eofb, ed->cube); |
| 950 | r2 = ptableval(&pd_drud_eofb, apply_trans(rf, ct.cube)); | 968 | r2 = ptableval(&pd_drud_eofb, apply_trans(rf, ed->cube)); |
| 951 | 969 | ||
| 952 | return MIN(r1, r2); | 970 | return MIN(r1, r2); |
| 953 | } | 971 | } |
| 954 | 972 | ||
| 955 | static int | 973 | static int |
| 956 | estimate_drudfin_drud(CubeTarget ct) | 974 | estimate_drudfin_drud(EstimateData *ed) |
| 957 | { | 975 | { |
| 958 | int val = ptableval(&pd_drudfin_noE_sym16_drud, ct.cube); | 976 | int val = ptableval(&pd_drudfin_noE_sym16_drud, ed->cube); |
| 959 | 977 | ||
| 960 | if (val != 0) | 978 | if (val != 0) |
| 961 | return val; | 979 | return val; |
| 962 | 980 | ||
| 963 | return ct.cube.epose % 24 == 0 ? 0 : 1; | 981 | return ed->cube.epose % 24 == 0 ? 0 : 1; |
| 964 | } | 982 | } |
| 965 | 983 | ||
| 966 | static int | 984 | static int |
| 967 | estimate_htr_drud(CubeTarget ct) | 985 | estimate_htr_drud(EstimateData *ed) |
| 968 | { | 986 | { |
| 969 | return ptableval(&pd_htr_drud, ct.cube); | 987 | return ptableval(&pd_htr_drud, ed->cube); |
| 970 | } | 988 | } |
| 971 | 989 | ||
| 972 | static int | 990 | static int |
| 973 | estimate_htrfin_htr(CubeTarget ct) | 991 | estimate_htrfin_htr(EstimateData *ed) |
| 974 | { | 992 | { |
| 975 | return ptableval(&pd_htrfin_htr, ct.cube); | 993 | return ptableval(&pd_htrfin_htr, ed->cube); |
| 976 | } | 994 | } |
| 977 | 995 | ||
| 978 | static int | 996 | static int |
| 979 | estimate_optimal_HTM(CubeTarget ct) | 997 | estimate_optimal_HTM(EstimateData *ed) |
| 980 | { | 998 | { |
| 981 | int dr1, dr2, dr3, cor, ret; | 999 | int ret = -1; |
| 982 | Cube inv; | 1000 | Move lbase; |
| 1001 | Cube cubeaux, inv; | ||
| 983 | 1002 | ||
| 984 | dr1 = ptableval(&pd_khuge_HTM, ct.cube); | 1003 | ed->li->corners = ptableval(&pd_corners_HTM, ed->cube); |
| 985 | cor = estimate_corners_HTM(ct); | 1004 | UPDATECHECKSTOP(ret, ed->li->corners, ed->target); |
| 986 | ret = MAX(dr1, cor); | ||
| 987 | if (ret > ct.target) | ||
| 988 | return ret; | ||
| 989 | 1005 | ||
| 990 | dr2 = ptableval(&pd_khuge_HTM, apply_trans(rf, ct.cube)); | 1006 | ed->li->normal_ud = ptableval(&pd_khuge_HTM, ed->cube); |
| 991 | ret = MAX(ret, dr2); | 1007 | UPDATECHECKSTOP(ret, ed->li->normal_ud, ed->target); |
| 992 | if (ret > ct.target) | ||
| 993 | return ret; | ||
| 994 | 1008 | ||
| 995 | dr3 = ptableval(&pd_khuge_HTM, apply_trans(fd, ct.cube)); | 1009 | cubeaux = apply_trans(fd, ed->cube); |
| 996 | if (dr1 == dr2 && dr2 == dr3 && dr1 != 0) | 1010 | ed->li->normal_fb = ptableval(&pd_khuge_HTM, cubeaux); |
| 997 | dr3++; | 1011 | UPDATECHECKSTOP(ret, ed->li->normal_fb, ed->target); |
| 998 | ret = MAX(ret, dr3); | ||
| 999 | if (ret > ct.target || ret == 0) | ||
| 1000 | return ret; | ||
| 1001 | 1012 | ||
| 1002 | /* Inverse cube probing */ | 1013 | cubeaux = apply_trans(rf, ed->cube); |
| 1014 | ed->li->normal_rl = ptableval(&pd_khuge_HTM, cubeaux); | ||
| 1015 | UPDATECHECKSTOP(ret, ed->li->normal_rl, ed->target); | ||
| 1003 | 1016 | ||
| 1004 | inv = inverse_cube(ct.cube); | 1017 | if (ret == 0) |
| 1005 | dr1 = ptableval(&pd_khuge_HTM, inv); | ||
| 1006 | ret = MAX(ret, dr1); | ||
| 1007 | if (ret > ct.target) | ||
| 1008 | return ret; | 1018 | return ret; |
| 1009 | 1019 | ||
| 1010 | dr2 = ptableval(&pd_khuge_HTM, apply_trans(rf, inv)); | 1020 | if (ed->li->normal_ud == ed->li->normal_fb && |
| 1011 | ret = MAX(ret, dr2); | 1021 | ed->li->normal_fb == ed->li->normal_rl) |
| 1012 | if (ret > ct.target) | 1022 | UPDATECHECKSTOP(ret, ed->li->normal_ud + 1, ed->target); |
| 1013 | return ret; | 1023 | |
| 1014 | 1024 | /* TODO: avoid computation of inverse if unnecessary */ | |
| 1015 | dr3 = ptableval(&pd_khuge_HTM, apply_trans(fd, inv)); | 1025 | lbase = base_move(ed->lastmove); |
| 1016 | if (dr1 == dr2 && dr2 == dr3 && dr1 != 0) | 1026 | inv = inverse_cube(ed->cube); |
| 1017 | dr3++; | 1027 | |
| 1018 | return MAX(ret, dr3); | 1028 | if ((lbase != U && lbase != D) || |
| 1029 | (ed->li->inverse_ud == -1)) { | ||
| 1030 | ed->li->inverse_ud = ptableval(&pd_khuge_HTM, inv); | ||
| 1031 | } | ||
| 1032 | UPDATECHECKSTOP(ret, ed->li->inverse_ud, ed->target); | ||
| 1033 | |||
| 1034 | if ((lbase != F && lbase != B) || | ||
| 1035 | (ed->li->inverse_fb == -1)) { | ||
| 1036 | cubeaux = apply_trans(fd, inv); | ||
| 1037 | ed->li->inverse_fb = ptableval(&pd_khuge_HTM, cubeaux); | ||
| 1038 | } | ||
| 1039 | UPDATECHECKSTOP(ret, ed->li->inverse_fb, ed->target); | ||
| 1040 | |||
| 1041 | if ((lbase != R && lbase != L) || | ||
| 1042 | (ed->li->inverse_rl == -1)) { | ||
| 1043 | cubeaux = apply_trans(rf, inv); | ||
| 1044 | ed->li->inverse_rl = ptableval(&pd_khuge_HTM, cubeaux); | ||
| 1045 | } | ||
| 1046 | UPDATECHECKSTOP(ret, ed->li->inverse_rl, ed->target); | ||
| 1047 | |||
| 1048 | if (ed->li->inverse_ud == ed->li->inverse_fb && | ||
| 1049 | ed->li->inverse_fb == ed->li->inverse_rl) | ||
| 1050 | UPDATECHECKSTOP(ret, ed->li->inverse_ud + 1, ed->target); | ||
| 1051 | |||
| 1052 | if (ed->li->inverse_ud == ed->target) | ||
| 1053 | ed->movebitmask |= (1<<U) | (1<<U2) | (1<<U3) | | ||
| 1054 | (1<<D) | (1<<D2) | (1<<D3); | ||
| 1055 | if (ed->li->inverse_fb == ed->target) | ||
| 1056 | ed->movebitmask |= (1<<F) | (1<<F2) | (1<<F3) | | ||
| 1057 | (1<<B) | (1<<B2) | (1<<B3); | ||
| 1058 | if (ed->li->inverse_rl == ed->target) | ||
| 1059 | ed->movebitmask |= (1<<R) | (1<<R2) | (1<<R3) | | ||
| 1060 | (1<<L) | (1<<L2) | (1<<L3); | ||
| 1061 | |||
| 1062 | return ret; | ||
| 1019 | } | 1063 | } |
| 1020 | 1064 | ||
| 1021 | static bool | 1065 | static bool |
| @@ -1076,6 +1120,29 @@ detect_pretrans_drud(Cube cube) | |||
| 1076 | /* Public functions **********************************************************/ | 1120 | /* Public functions **********************************************************/ |
| 1077 | 1121 | ||
| 1078 | void | 1122 | void |
| 1123 | free_localinfo(LocalInfo *li) | ||
| 1124 | { | ||
| 1125 | free(li); | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | LocalInfo * | ||
| 1129 | new_localinfo() | ||
| 1130 | { | ||
| 1131 | LocalInfo *ret = malloc(sizeof(LocalInfo)); | ||
| 1132 | |||
| 1133 | ret->corners = -1; | ||
| 1134 | ret->normal_ud = -1; | ||
| 1135 | ret->normal_fb = -1; | ||
| 1136 | ret->normal_rl = -1; | ||
| 1137 | ret->inverse_ud = -1; | ||
| 1138 | ret->inverse_fb = -1; | ||
| 1139 | ret->inverse_rl = -1; | ||
| 1140 | ret->prev_ret = -1; | ||
| 1141 | |||
| 1142 | return ret; | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | void | ||
| 1079 | prepare_step(Step *step) | 1146 | prepare_step(Step *step) |
| 1080 | { | 1147 | { |
| 1081 | int i; | 1148 | int i; |
diff --git a/src/steps.h b/src/steps.h index 4aedcee..f23bc69 100644 --- a/src/steps.h +++ b/src/steps.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | 7 | ||
| 8 | extern Step * steps[NSTEPS]; | 8 | extern Step * steps[NSTEPS]; |
| 9 | 9 | ||
| 10 | void free_localinfo(LocalInfo *li); | ||
| 11 | LocalInfo * new_localinfo(); | ||
| 10 | void prepare_step(Step *step); | 12 | void prepare_step(Step *step); |
| 11 | 13 | ||
| 12 | #endif | 14 | #endif |
