diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2022-09-06 23:25:31 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2022-09-06 23:25:31 +0200 |
| commit | 569983380edfb3744192b5a652e2ac038840e53d (patch) | |
| tree | feea695d10d6984b45ce2a55efec3f10e5ff36be | |
| parent | a125e69c8ce0a2764b1e50b2dad0a4fa9d141ef4 (diff) | |
| download | nissy-569983380edfb3744192b5a652e2ac038840e53d.tar.gz nissy-569983380edfb3744192b5a652e2ac038840e53d.zip | |
Removed some code preparing for moving optimal solver away from general coordinate solving.
Kept symcoord for coordinate solving.
| -rw-r--r-- | TODO.md | 36 | ||||
| -rw-r--r-- | src/commands.c | 20 | ||||
| -rw-r--r-- | src/cubetypes.h | 64 | ||||
| -rw-r--r-- | src/pruning.c | 99 | ||||
| -rw-r--r-- | src/solve.c | 133 | ||||
| -rw-r--r-- | src/solve.h | 2 | ||||
| -rw-r--r-- | src/steps.c | 78 | ||||
| -rw-r--r-- | src/steps.h | 144 |
8 files changed, 202 insertions, 374 deletions
| @@ -3,20 +3,28 @@ | |||
| 3 | This is a list of things that I would like to add or change at some point. | 3 | This is a list of things that I would like to add or change at some point. |
| 4 | It's more of a personal reminder than anything else. | 4 | It's more of a personal reminder than anything else. |
| 5 | 5 | ||
| 6 | ## After symcoord | ||
| 7 | ### Solving standard coordinates | ||
| 8 | * add Void * extradata to DfsArg and a custom move function | ||
| 9 | * add optional custom pre-process for generating special table (nx) | ||
| 10 | * copy_dfsdata should copy extra too! | ||
| 11 | * Pruning: remove base value? | ||
| 12 | ### nx.c | ||
| 13 | * implement nxopt with all tables and all tricks | ||
| 14 | (maybe compile time variable for maximum memory to use?) | ||
| 15 | * custom pruning table, copy some code from pruning.h | ||
| 16 | * generate compressed: hard-code the base value, doable! | ||
| 17 | * special type of pruning table with fallback and whatnot | ||
| 18 | * is_valid should also unniss / cleanup the alg | ||
| 19 | ### fst_cube | ||
| 20 | * slightly different from cube in v2.0.2: each "side" coordinate | ||
| 21 | is a transformation of the other, not an eorl or similar (changes | ||
| 22 | the permutation!) | ||
| 23 | * add fst_index for some coordinates? | ||
| 24 | * inverse: for edges, just generate ep[12] and convert back | ||
| 25 | * corners: big table (150Mb if 16bit integers are used) | ||
| 26 | |||
| 6 | ## For version 2.1 | 27 | ## For version 2.1 |
| 7 | ### Slow: it is slower than the old nissy 2.0.2 :( | ||
| 8 | * nxopt's trick (switching to reduce branching) actually saves about 50%! | ||
| 9 | * Another factor is estimating *while* moving (i.e. do not move all | ||
| 10 | coordinates if the first one already gives a high value!) | ||
| 11 | * simplify solve, remove everything that is used only by optimal solvers | ||
| 12 | * Good compromise: each stepalt offers one of two alternatives: either solve | ||
| 13 | by simply using pruning tables and moving coordinates, or using a custom | ||
| 14 | estimator and moving a cube (or fast_cube) and computing coordinates | ||
| 15 | in the estimator | ||
| 16 | * is there really no way to use inverse branching trick with current system? | ||
| 17 | * new file optimal.c with the old solve logic; try first with the simple | ||
| 18 | cube implementation and the new indexers, if it is still slow change | ||
| 19 | to fast_cube (intermediate nissy v2.0.2 implementation) | ||
| 20 | ### Changes to Step and Solve | 28 | ### Changes to Step and Solve |
| 21 | * remove cube from dfsarg? (i still need to save the scramble somewhere, | 29 | * remove cube from dfsarg? (i still need to save the scramble somewhere, |
| 22 | but I really only use it in dfs_niss) | 30 | but I really only use it in dfs_niss) |
| @@ -24,8 +32,6 @@ It's more of a personal reminder than anything else. | |||
| 24 | * steps.c: checkers (use coordinates), all stepalt and steps (WIP...) | 32 | * steps.c: checkers (use coordinates), all stepalt and steps (WIP...) |
| 25 | * commands gen and freemem | 33 | * commands gen and freemem |
| 26 | * commands.c: twophase, ...? | 34 | * commands.c: twophase, ...? |
| 27 | * Coordinate should have a moveset field? No, at worst there are some garbage | ||
| 28 | values in mtable, but no risk for errors | ||
| 29 | ### Rotate, not transform, before solving | 35 | ### Rotate, not transform, before solving |
| 30 | * solve should re-orient first if needed and not just give up if centers are off | 36 | * solve should re-orient first if needed and not just give up if centers are off |
| 31 | ### Documentation | 37 | ### Documentation |
diff --git a/src/commands.c b/src/commands.c index 7f58ef5..9ac1ae6 100644 --- a/src/commands.c +++ b/src/commands.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | #include "commands.h" | 3 | #include "commands.h" |
| 4 | 4 | ||
| 5 | static bool read_step(CommandArgs *args, char *str); | 5 | static bool read_cs(CommandArgs *args, char *str); |
| 6 | static bool read_scrtype(CommandArgs *args, char *str); | 6 | static bool read_scrtype(CommandArgs *args, char *str); |
| 7 | static bool read_scramble(int c, char **v, CommandArgs *args); | 7 | static bool read_scramble(int c, char **v, CommandArgs *args); |
| 8 | 8 | ||
| @@ -95,7 +95,7 @@ solve_parse_args(int c, char **v) | |||
| 95 | a->opts->print_number = false; | 95 | a->opts->print_number = false; |
| 96 | } else if (!strcmp(v[i], "-c")) { | 96 | } else if (!strcmp(v[i], "-c")) { |
| 97 | a->opts->count_only = true; | 97 | a->opts->count_only = true; |
| 98 | } else if (!read_step(a, v[i])) { | 98 | } else if (!read_cs(a, v[i])) { |
| 99 | break; | 99 | break; |
| 100 | } | 100 | } |
| 101 | } | 101 | } |
| @@ -218,7 +218,7 @@ solve_exec(CommandArgs *args) | |||
| 218 | 218 | ||
| 219 | make_solved(&c); | 219 | make_solved(&c); |
| 220 | apply_alg(args->scramble, &c); | 220 | apply_alg(args->scramble, &c); |
| 221 | sols = solve(&c, args->step, args->opts); | 221 | sols = solve(&c, args->cs, args->opts); |
| 222 | 222 | ||
| 223 | if (args->opts->count_only) | 223 | if (args->opts->count_only) |
| 224 | printf("%d\n", sols->len); | 224 | printf("%d\n", sols->len); |
| @@ -345,8 +345,8 @@ steps_exec(CommandArgs *args) | |||
| 345 | { | 345 | { |
| 346 | int i; | 346 | int i; |
| 347 | 347 | ||
| 348 | for (i = 0; steps[i] != NULL; i++) | 348 | for (i = 0; csteps[i] != NULL; i++) |
| 349 | printf("%-15s %s\n", steps[i]->shortname, steps[i]->name); | 349 | printf("%-15s %s\n", csteps[i]->shortname, csteps[i]->name); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | void | 352 | void |
| @@ -503,13 +503,13 @@ read_scrtype(CommandArgs *args, char *str) | |||
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | static bool | 505 | static bool |
| 506 | read_step(CommandArgs *args, char *str) | 506 | read_cs(CommandArgs *args, char *str) |
| 507 | { | 507 | { |
| 508 | int i; | 508 | int i; |
| 509 | 509 | ||
| 510 | for (i = 0; steps[i] != NULL; i++) { | 510 | for (i = 0; csteps[i] != NULL; i++) { |
| 511 | if (!strcmp(steps[i]->shortname, str)) { | 511 | if (!strcmp(csteps[i]->shortname, str)) { |
| 512 | args->step = steps[i]; | 512 | args->cs = csteps[i]; |
| 513 | return true; | 513 | return true; |
| 514 | } | 514 | } |
| 515 | } | 515 | } |
| @@ -546,7 +546,7 @@ new_args() | |||
| 546 | args->opts = malloc(sizeof(SolveOptions)); | 546 | args->opts = malloc(sizeof(SolveOptions)); |
| 547 | 547 | ||
| 548 | /* step and command are static */ | 548 | /* step and command are static */ |
| 549 | args->step = steps[0]; /* default: first step in list */ | 549 | args->cs = csteps[0]; /* default: first step in list */ |
| 550 | args->command = NULL; | 550 | args->command = NULL; |
| 551 | 551 | ||
| 552 | return args; | 552 | return args; |
diff --git a/src/cubetypes.h b/src/cubetypes.h index cf6b7d5..fa19f6c 100644 --- a/src/cubetypes.h +++ b/src/cubetypes.h | |||
| @@ -84,7 +84,7 @@ trans | |||
| 84 | typedef struct alg Alg; | 84 | typedef struct alg Alg; |
| 85 | typedef struct alglist AlgList; | 85 | typedef struct alglist AlgList; |
| 86 | typedef struct alglistnode AlgListNode; | 86 | typedef struct alglistnode AlgListNode; |
| 87 | typedef struct block Block; | 87 | typedef struct choicestep ChoiceStep; |
| 88 | typedef struct command Command; | 88 | typedef struct command Command; |
| 89 | typedef struct commandargs CommandArgs; | 89 | typedef struct commandargs CommandArgs; |
| 90 | typedef struct coordinate Coordinate; | 90 | typedef struct coordinate Coordinate; |
| @@ -97,13 +97,14 @@ typedef struct pdgendata PDGenData; | |||
| 97 | typedef struct prunedata PruneData; | 97 | typedef struct prunedata PruneData; |
| 98 | typedef struct solveoptions SolveOptions; | 98 | typedef struct solveoptions SolveOptions; |
| 99 | typedef struct step Step; | 99 | typedef struct step Step; |
| 100 | typedef struct stepalt StepAlt; | ||
| 101 | typedef struct symdata SymData; | 100 | typedef struct symdata SymData; |
| 102 | typedef struct threaddatasolve ThreadDataSolve; | 101 | typedef struct threaddatasolve ThreadDataSolve; |
| 103 | typedef struct threaddatagenpt ThreadDataGenpt; | 102 | typedef struct threaddatagenpt ThreadDataGenpt; |
| 104 | typedef struct transgroup TransGroup; | 103 | typedef struct transgroup TransGroup; |
| 105 | 104 | ||
| 106 | typedef bool (*Checker) (Cube *); | 105 | typedef bool (*Checker) (Cube *); |
| 106 | typedef bool (*DfsMover) (DfsArg *); | ||
| 107 | typedef void (*DfsExtraCopier) (void *, void *); | ||
| 107 | typedef bool (*Validator) (Alg *); | 108 | typedef bool (*Validator) (Alg *); |
| 108 | typedef void (*Exec) (CommandArgs *); | 109 | typedef void (*Exec) (CommandArgs *); |
| 109 | typedef CommandArgs * (*ArgParser) (int, char **); | 110 | typedef CommandArgs * (*ArgParser) (int, char **); |
| @@ -137,11 +138,13 @@ alglistnode | |||
| 137 | }; | 138 | }; |
| 138 | 139 | ||
| 139 | struct | 140 | struct |
| 140 | block | 141 | choicestep |
| 141 | { | 142 | { |
| 142 | bool edge[12]; | 143 | char * shortname; |
| 143 | bool corner[8]; | 144 | char * name; |
| 144 | bool center[6]; | 145 | Step * step[99]; |
| 146 | Trans t[99]; | ||
| 147 | char * ready_msg; | ||
| 145 | }; | 148 | }; |
| 146 | 149 | ||
| 147 | struct | 150 | struct |
| @@ -160,7 +163,7 @@ commandargs | |||
| 160 | bool success; | 163 | bool success; |
| 161 | Alg * scramble; | 164 | Alg * scramble; |
| 162 | SolveOptions * opts; | 165 | SolveOptions * opts; |
| 163 | Step * step; | 166 | ChoiceStep * cs; |
| 164 | Command * command; /* For help */ | 167 | Command * command; /* For help */ |
| 165 | int n; | 168 | int n; |
| 166 | char scrtype[20]; | 169 | char scrtype[20]; |
| @@ -210,7 +213,7 @@ dfsarg | |||
| 210 | Cube * cube; | 213 | Cube * cube; |
| 211 | Movable ind[MAX_N_COORD]; | 214 | Movable ind[MAX_N_COORD]; |
| 212 | Trans t; | 215 | Trans t; |
| 213 | StepAlt * sa; | 216 | Step * s; |
| 214 | SolveOptions * opts; | 217 | SolveOptions * opts; |
| 215 | int d; | 218 | int d; |
| 216 | int bound; | 219 | int bound; |
| @@ -220,6 +223,7 @@ dfsarg | |||
| 220 | AlgList * sols; | 223 | AlgList * sols; |
| 221 | pthread_mutex_t * sols_mutex; | 224 | pthread_mutex_t * sols_mutex; |
| 222 | Alg * current_alg; | 225 | Alg * current_alg; |
| 226 | void * extra; | ||
| 223 | }; | 227 | }; |
| 224 | 228 | ||
| 225 | struct | 229 | struct |
| @@ -245,7 +249,6 @@ pdgendata | |||
| 245 | { | 249 | { |
| 246 | Coordinate * coord; | 250 | Coordinate * coord; |
| 247 | Moveset * moveset; | 251 | Moveset * moveset; |
| 248 | bool compact; | ||
| 249 | PruneData * pd; | 252 | PruneData * pd; |
| 250 | }; | 253 | }; |
| 251 | 254 | ||
| @@ -256,10 +259,7 @@ prunedata | |||
| 256 | uint64_t n; | 259 | uint64_t n; |
| 257 | Coordinate * coord; | 260 | Coordinate * coord; |
| 258 | Moveset * moveset; | 261 | Moveset * moveset; |
| 259 | bool compact; | ||
| 260 | int base; | ||
| 261 | uint64_t count[16]; | 262 | uint64_t count[16]; |
| 262 | uint64_t fbmod; | ||
| 263 | }; | 263 | }; |
| 264 | 264 | ||
| 265 | struct | 265 | struct |
| @@ -280,54 +280,18 @@ solveoptions | |||
| 280 | struct | 280 | struct |
| 281 | step | 281 | step |
| 282 | { | 282 | { |
| 283 | char * shortname; | ||
| 284 | char * name; | ||
| 285 | StepAlt * alt[99]; | ||
| 286 | Trans t[99]; | ||
| 287 | char * ready_msg; | ||
| 288 | }; | ||
| 289 | |||
| 290 | struct | ||
| 291 | stepalt | ||
| 292 | { | ||
| 293 | Checker ready; | 283 | Checker ready; |
| 294 | bool final; | 284 | bool final; |
| 295 | Moveset * moveset; | 285 | Moveset * moveset; |
| 296 | /* Just a comment, (TODO: remove this): moveset is really a stepalt | ||
| 297 | * property, because for example we may want to define a "fingertrick | ||
| 298 | * friendly ZBLL" step, where we allow either <R U D> or <R U F> as | ||
| 299 | * movesets (or similar) */ | ||
| 300 | int n_coord; | 286 | int n_coord; |
| 301 | Coordinate * coord[MAX_N_COORD]; | 287 | Coordinate * coord[MAX_N_COORD]; |
| 302 | Trans coord_trans[MAX_N_COORD]; | 288 | Trans coord_trans[MAX_N_COORD]; |
| 303 | PruneData * pd[MAX_N_COORD]; | 289 | PruneData * pd[MAX_N_COORD]; |
| 304 | bool compact_pd[MAX_N_COORD]; | ||
| 305 | Coordinate * fallback_coord[MAX_N_COORD]; | ||
| 306 | PruneData * fallback_pd[MAX_N_COORD]; | ||
| 307 | uint64_t fbmod[MAX_N_COORD]; | ||
| 308 | int n_dbtrick; | ||
| 309 | int dbtrick[MAX_N_COORD][3]; | ||
| 310 | Validator is_valid; | 290 | Validator is_valid; |
| 291 | DfsMover custom_move_checkstop; | ||
| 292 | DfsExtraCopier copy_extra; | ||
| 311 | }; | 293 | }; |
| 312 | 294 | ||
| 313 | /* | ||
| 314 | struct | ||
| 315 | symdata | ||
| 316 | { | ||
| 317 | char * filename; | ||
| 318 | bool generated; | ||
| 319 | Coordinate * coord; | ||
| 320 | Coordinate * sym_coord; | ||
| 321 | int ntrans; | ||
| 322 | Trans * trans; | ||
| 323 | uint64_t * class; | ||
| 324 | uint64_t * unsym; | ||
| 325 | Trans * transtorep; | ||
| 326 | uint64_t * selfsim; | ||
| 327 | }; | ||
| 328 | */ | ||
| 329 | |||
| 330 | |||
| 331 | struct | 295 | struct |
| 332 | threaddatasolve | 296 | threaddatasolve |
| 333 | { | 297 | { |
diff --git a/src/pruning.c b/src/pruning.c index 5be977c..2e30351 100644 --- a/src/pruning.c +++ b/src/pruning.c | |||
| @@ -3,13 +3,10 @@ | |||
| 3 | #include "pruning.h" | 3 | #include "pruning.h" |
| 4 | 4 | ||
| 5 | #define ENTRIES_PER_GROUP (2*sizeof(entry_group_t)) | 5 | #define ENTRIES_PER_GROUP (2*sizeof(entry_group_t)) |
| 6 | #define ENTRIES_PER_GROUP_COMPACT (4*sizeof(entry_group_t)) | ||
| 7 | 6 | ||
| 8 | static int findchunk(PruneData *pd, int nchunks, uint64_t i); | 7 | static int findchunk(PruneData *pd, int nchunks, uint64_t i); |
| 9 | static void genptable_bfs(PruneData *pd, int d, int nt, int nc); | 8 | static void genptable_bfs(PruneData *pd, int d, int nt, int nc); |
| 10 | static void genptable_compress(PruneData *pd); | ||
| 11 | static void genptable_fixnasty(PruneData *pd, int d, int nthreads); | 9 | static void genptable_fixnasty(PruneData *pd, int d, int nthreads); |
| 12 | static void genptable_setbase(PruneData *pd); | ||
| 13 | static void * instance_bfs(void *arg); | 10 | static void * instance_bfs(void *arg); |
| 14 | static void * instance_fixnasty(void *arg); | 11 | static void * instance_fixnasty(void *arg); |
| 15 | static void ptable_update(PruneData *pd, uint64_t ind, int m); | 12 | static void ptable_update(PruneData *pd, uint64_t ind, int m); |
| @@ -32,16 +29,13 @@ findchunk(PruneData *pd, int nchunks, uint64_t i) | |||
| 32 | PruneData * | 29 | PruneData * |
| 33 | genptable(PDGenData *pdg, int nthreads) | 30 | genptable(PDGenData *pdg, int nthreads) |
| 34 | { | 31 | { |
| 35 | bool compact; | ||
| 36 | int d, nchunks, i; | 32 | int d, nchunks, i; |
| 37 | uint64_t oldn, sz; | 33 | uint64_t oldn; |
| 38 | PruneData *pd; | 34 | PruneData *pd; |
| 39 | 35 | ||
| 40 | for (i = 0; active_pdg[i] != NULL; i++) { | 36 | for (i = 0; active_pdg[i] != NULL; i++) { |
| 41 | pd = active_pdg[i]->pd; | 37 | pd = active_pdg[i]->pd; |
| 42 | if (pd->coord == pdg->coord && | 38 | if (pd->coord == pdg->coord && pd->moveset == pdg->moveset) |
| 43 | pd->moveset == pdg->moveset && | ||
| 44 | pd->compact == pdg->compact) | ||
| 45 | return pd; | 39 | return pd; |
| 46 | } | 40 | } |
| 47 | 41 | ||
| @@ -49,10 +43,7 @@ genptable(PDGenData *pdg, int nthreads) | |||
| 49 | pdg->pd = pd; | 43 | pdg->pd = pd; |
| 50 | pd->coord = pdg->coord; | 44 | pd->coord = pdg->coord; |
| 51 | pd->moveset = pdg->moveset; | 45 | pd->moveset = pdg->moveset; |
| 52 | pd->compact = pdg->compact; | 46 | pd->ptable = malloc(ptablesize(pd) * sizeof(entry_group_t)); |
| 53 | |||
| 54 | sz = ptablesize(pd) * (pd->compact ? 2 : 1); | ||
| 55 | pd->ptable = malloc(sz * sizeof(entry_group_t)); | ||
| 56 | 47 | ||
| 57 | gen_coord(pd->coord); | 48 | gen_coord(pd->coord); |
| 58 | 49 | ||
| @@ -70,11 +61,6 @@ genptable(PDGenData *pdg, int nthreads) | |||
| 70 | ); | 61 | ); |
| 71 | } | 62 | } |
| 72 | 63 | ||
| 73 | |||
| 74 | /* For the first steps we proceed the same way for compact and not */ | ||
| 75 | compact = pd->compact; | ||
| 76 | pd->compact = false; | ||
| 77 | |||
| 78 | nchunks = MIN(ptablesize(pd), 100000); | 64 | nchunks = MIN(ptablesize(pd), 100000); |
| 79 | fprintf(stderr, "Generating pt_%s_%s with %d threads\n", | 65 | fprintf(stderr, "Generating pt_%s_%s with %d threads\n", |
| 80 | pd->coord->name, pd->moveset->name, nthreads); | 66 | pd->coord->name, pd->moveset->name, nthreads); |
| @@ -102,10 +88,6 @@ genptable(PDGenData *pdg, int nthreads) | |||
| 102 | oldn = pd->n; | 88 | oldn = pd->n; |
| 103 | } | 89 | } |
| 104 | fprintf(stderr, "Pruning table generated!\n"); | 90 | fprintf(stderr, "Pruning table generated!\n"); |
| 105 | |||
| 106 | genptable_setbase(pd); | ||
| 107 | if (compact) | ||
| 108 | genptable_compress(pd); | ||
| 109 | 91 | ||
| 110 | if (!write_ptable_file(pd)) | 92 | if (!write_ptable_file(pd)) |
| 111 | fprintf(stderr, "Error writing ptable file\n"); | 93 | fprintf(stderr, "Error writing ptable file\n"); |
| @@ -115,7 +97,6 @@ genptable_done: | |||
| 115 | active_pdg[i] = malloc(sizeof(PDGenData)); | 97 | active_pdg[i] = malloc(sizeof(PDGenData)); |
| 116 | active_pdg[i]->coord = pdg->coord; | 98 | active_pdg[i]->coord = pdg->coord; |
| 117 | active_pdg[i]->moveset = pdg->moveset; | 99 | active_pdg[i]->moveset = pdg->moveset; |
| 118 | active_pdg[i]->compact = pdg->compact; | ||
| 119 | active_pdg[i]->pd = pd; | 100 | active_pdg[i]->pd = pd; |
| 120 | 101 | ||
| 121 | return pd; | 102 | return pd; |
| @@ -156,31 +137,6 @@ genptable_bfs(PruneData *pd, int d, int nthreads, int nchunks) | |||
| 156 | } | 137 | } |
| 157 | 138 | ||
| 158 | static void | 139 | static void |
| 159 | genptable_compress(PruneData *pd) | ||
| 160 | { | ||
| 161 | int val; | ||
| 162 | uint64_t i, j; | ||
| 163 | entry_group_t mask, v; | ||
| 164 | |||
| 165 | fprintf(stderr, "Compressing table to 2 bits per entry\n"); | ||
| 166 | |||
| 167 | for (i = 0; i < pd->coord->max; i += ENTRIES_PER_GROUP_COMPACT) { | ||
| 168 | mask = (entry_group_t)0; | ||
| 169 | for (j = 0; j < ENTRIES_PER_GROUP_COMPACT; j++) { | ||
| 170 | if (i+j >= pd->coord->max) | ||
| 171 | break; | ||
| 172 | val = ptableval(pd, i+j) - pd->base; | ||
| 173 | v = (entry_group_t)MIN(3, MAX(0, val)); | ||
| 174 | mask |= v << (2*j); | ||
| 175 | } | ||
| 176 | pd->ptable[i/ENTRIES_PER_GROUP_COMPACT] = mask; | ||
| 177 | } | ||
| 178 | |||
| 179 | pd->compact = true; | ||
| 180 | pd->ptable = realloc(pd->ptable, sizeof(entry_group_t)*ptablesize(pd)); | ||
| 181 | } | ||
| 182 | |||
| 183 | static void | ||
| 184 | genptable_fixnasty(PruneData *pd, int d, int nthreads) | 140 | genptable_fixnasty(PruneData *pd, int d, int nthreads) |
| 185 | { | 141 | { |
| 186 | int i; | 142 | int i; |
| @@ -208,22 +164,6 @@ genptable_fixnasty(PruneData *pd, int d, int nthreads) | |||
| 208 | free(upmtx); | 164 | free(upmtx); |
| 209 | } | 165 | } |
| 210 | 166 | ||
| 211 | static void | ||
| 212 | genptable_setbase(PruneData *pd) | ||
| 213 | { | ||
| 214 | int i; | ||
| 215 | uint64_t sum, newsum; | ||
| 216 | |||
| 217 | pd->base = 0; | ||
| 218 | sum = pd->count[0] + pd->count[1] + pd->count[2]; | ||
| 219 | for (i = 3; i < 16; i++) { | ||
| 220 | newsum = sum + pd->count[i] - pd->count[i-3]; | ||
| 221 | if (newsum > sum) | ||
| 222 | pd->base = i-3; | ||
| 223 | sum = newsum; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | static void * | 167 | static void * |
| 228 | instance_bfs(void *arg) | 168 | instance_bfs(void *arg) |
| 229 | { | 169 | { |
| @@ -317,7 +257,6 @@ print_ptable(PruneData *pd) | |||
| 317 | uint64_t i; | 257 | uint64_t i; |
| 318 | 258 | ||
| 319 | printf("Table %s_%s\n", pd->coord->name, pd->moveset->name); | 259 | printf("Table %s_%s\n", pd->coord->name, pd->moveset->name); |
| 320 | printf("Base value: %d\n", pd->base); | ||
| 321 | for (i = 0; i < 16; i++) | 260 | for (i = 0; i < 16; i++) |
| 322 | printf("%2" PRIu64 "\t%10" PRIu64 "\n", i, pd->count[i]); | 261 | printf("%2" PRIu64 "\t%10" PRIu64 "\n", i, pd->count[i]); |
| 323 | } | 262 | } |
| @@ -325,11 +264,7 @@ print_ptable(PruneData *pd) | |||
| 325 | uint64_t | 264 | uint64_t |
| 326 | ptablesize(PruneData *pd) | 265 | ptablesize(PruneData *pd) |
| 327 | { | 266 | { |
| 328 | uint64_t e; | 267 | return (pd->coord->max + ENTRIES_PER_GROUP - 1) / ENTRIES_PER_GROUP; |
| 329 | |||
| 330 | e = pd->compact ? ENTRIES_PER_GROUP_COMPACT : ENTRIES_PER_GROUP; | ||
| 331 | |||
| 332 | return (pd->coord->max + e - 1) / e; | ||
| 333 | } | 268 | } |
| 334 | 269 | ||
| 335 | static void | 270 | static void |
| @@ -350,23 +285,11 @@ ptable_update(PruneData *pd, uint64_t ind, int n) | |||
| 350 | int | 285 | int |
| 351 | ptableval(PruneData *pd, uint64_t ind) | 286 | ptableval(PruneData *pd, uint64_t ind) |
| 352 | { | 287 | { |
| 353 | int sh, ret; | 288 | int sh; |
| 354 | uint64_t e; | ||
| 355 | entry_group_t m; | ||
| 356 | |||
| 357 | if (pd->compact) { | ||
| 358 | e = ENTRIES_PER_GROUP_COMPACT; | ||
| 359 | m = 3; | ||
| 360 | sh = (ind % e) * 2; | ||
| 361 | } else { | ||
| 362 | e = ENTRIES_PER_GROUP; | ||
| 363 | m = 15; | ||
| 364 | sh = (ind % e) * 4; | ||
| 365 | } | ||
| 366 | 289 | ||
| 367 | ret = (pd->ptable[ind/e] & (m << sh)) >> sh; | 290 | sh = (ind % ENTRIES_PER_GROUP) * 4; |
| 368 | 291 | ||
| 369 | return pd->compact ? ret + pd->base : ret; | 292 | return (pd->ptable[ind/ENTRIES_PER_GROUP] & (15 << sh)) >> sh; |
| 370 | } | 293 | } |
| 371 | 294 | ||
| 372 | static bool | 295 | static bool |
| @@ -376,7 +299,7 @@ read_ptable_file(PruneData *pd) | |||
| 376 | 299 | ||
| 377 | FILE *f; | 300 | FILE *f; |
| 378 | char fname[strlen(tabledir)+256]; | 301 | char fname[strlen(tabledir)+256]; |
| 379 | int i; | 302 | int i, phony; |
| 380 | uint64_t r; | 303 | uint64_t r; |
| 381 | 304 | ||
| 382 | strcpy(fname, tabledir); | 305 | strcpy(fname, tabledir); |
| @@ -388,7 +311,7 @@ read_ptable_file(PruneData *pd) | |||
| 388 | if ((f = fopen(fname, "rb")) == NULL) | 311 | if ((f = fopen(fname, "rb")) == NULL) |
| 389 | return false; | 312 | return false; |
| 390 | 313 | ||
| 391 | r = fread(&(pd->base), sizeof(int), 1, f); | 314 | r = fread(&phony, sizeof(int), 1, f); |
| 392 | for (i = 0; i < 16; i++) | 315 | for (i = 0; i < 16; i++) |
| 393 | r += fread(&(pd->count[i]), sizeof(uint64_t), 1, f); | 316 | r += fread(&(pd->count[i]), sizeof(uint64_t), 1, f); |
| 394 | r += fread(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f); | 317 | r += fread(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f); |
| @@ -405,7 +328,7 @@ write_ptable_file(PruneData *pd) | |||
| 405 | 328 | ||
| 406 | FILE *f; | 329 | FILE *f; |
| 407 | char fname[strlen(tabledir)+256]; | 330 | char fname[strlen(tabledir)+256]; |
| 408 | int i; | 331 | int i, phony = 0; |
| 409 | uint64_t w; | 332 | uint64_t w; |
| 410 | 333 | ||
| 411 | strcpy(fname, tabledir); | 334 | strcpy(fname, tabledir); |
| @@ -417,7 +340,7 @@ write_ptable_file(PruneData *pd) | |||
| 417 | if ((f = fopen(fname, "wb")) == NULL) | 340 | if ((f = fopen(fname, "wb")) == NULL) |
| 418 | return false; | 341 | return false; |
| 419 | 342 | ||
| 420 | w = fwrite(&(pd->base), sizeof(int), 1, f); | 343 | w = fwrite(&phony, sizeof(int), 1, f); /* phony replace base */ |
| 421 | for (i = 0; i < 16; i++) | 344 | for (i = 0; i < 16; i++) |
| 422 | w += fwrite(&(pd->count[i]), sizeof(uint64_t), 1, f); | 345 | w += fwrite(&(pd->count[i]), sizeof(uint64_t), 1, f); |
| 423 | w += fwrite(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f); | 346 | w += fwrite(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f); |
diff --git a/src/solve.c b/src/solve.c index 911d208..df15cca 100644 --- a/src/solve.c +++ b/src/solve.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | /* Local functions ***********************************************************/ | 5 | /* Local functions ***********************************************************/ |
| 6 | 6 | ||
| 7 | static bool allowed_next(Move move, StepAlt *sa, Move l0, Move l1); | 7 | static bool allowed_next(Move move, Step *s, Move l0, Move l1); |
| 8 | static bool cancel_niss(DfsArg *arg); | 8 | static bool cancel_niss(DfsArg *arg); |
| 9 | static void copy_dfsarg(DfsArg *src, DfsArg *dst); | 9 | static void copy_dfsarg(DfsArg *src, DfsArg *dst); |
| 10 | static void dfs(DfsArg *arg); | 10 | static void dfs(DfsArg *arg); |
| @@ -19,13 +19,13 @@ static bool solvestop(int d, int op, SolveOptions *opts, AlgList *sols); | |||
| 19 | /* Local functions ***********************************************************/ | 19 | /* Local functions ***********************************************************/ |
| 20 | 20 | ||
| 21 | static bool | 21 | static bool |
| 22 | allowed_next(Move m, StepAlt *sa, Move l0, Move l1) | 22 | allowed_next(Move m, Step *s, Move l0, Move l1) |
| 23 | { | 23 | { |
| 24 | bool allowed, order; | 24 | bool allowed, order; |
| 25 | uint64_t mbit; | 25 | uint64_t mbit; |
| 26 | 26 | ||
| 27 | mbit = ((uint64_t)1) << m; | 27 | mbit = ((uint64_t)1) << m; |
| 28 | allowed = mbit & sa->moveset->mask[l1][l0]; | 28 | allowed = mbit & s->moveset->mask[l1][l0]; |
| 29 | order = !commute(l0, m) || l0 < m; | 29 | order = !commute(l0, m) || l0 < m; |
| 30 | 30 | ||
| 31 | return allowed && order; | 31 | return allowed && order; |
| @@ -41,7 +41,7 @@ cancel_niss(DfsArg *arg) | |||
| 41 | if (arg->lastinv[0] == NULLMOVE) | 41 | if (arg->lastinv[0] == NULLMOVE) |
| 42 | return false; | 42 | return false; |
| 43 | 43 | ||
| 44 | ms = arg->sa->moveset; | 44 | ms = arg->s->moveset; |
| 45 | i1 = inverse_move(arg->lastinv[0]); | 45 | i1 = inverse_move(arg->lastinv[0]); |
| 46 | i2 = inverse_move(arg->lastinv[1]); | 46 | i2 = inverse_move(arg->lastinv[1]); |
| 47 | 47 | ||
| @@ -63,7 +63,7 @@ copy_dfsarg(DfsArg *src, DfsArg *dst) | |||
| 63 | 63 | ||
| 64 | dst->cube = src->cube; | 64 | dst->cube = src->cube; |
| 65 | dst->t = src->t; | 65 | dst->t = src->t; |
| 66 | dst->sa = src->sa; | 66 | dst->s = src->s; |
| 67 | dst->opts = src->opts; | 67 | dst->opts = src->opts; |
| 68 | dst->d = src->d; | 68 | dst->d = src->d; |
| 69 | dst->bound = src->bound; /* In theory not needed */ | 69 | dst->bound = src->bound; /* In theory not needed */ |
| @@ -77,10 +77,14 @@ copy_dfsarg(DfsArg *src, DfsArg *dst) | |||
| 77 | dst->lastinv[i] = src->lastinv[i]; | 77 | dst->lastinv[i] = src->lastinv[i]; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | for (i = 0; i < src->sa->n_coord; i++) { | 80 | for (i = 0; i < src->s->n_coord; i++) { |
| 81 | dst->ind[i].val = src->ind[i].val; | 81 | dst->ind[i].val = src->ind[i].val; |
| 82 | dst->ind[i].t = src->ind[i].t; | 82 | dst->ind[i].t = src->ind[i].t; |
| 83 | } | 83 | } |
| 84 | |||
| 85 | /* | ||
| 86 | src->s->copy_extra(src, dst); | ||
| 87 | */ | ||
| 84 | } | 88 | } |
| 85 | 89 | ||
| 86 | static void | 90 | static void |
| @@ -99,9 +103,9 @@ dfs(DfsArg *arg) | |||
| 99 | return; | 103 | return; |
| 100 | } | 104 | } |
| 101 | 105 | ||
| 102 | for (i = 0; arg->sa->moveset->sorted_moves[i] != NULLMOVE; i++) { | 106 | for (i = 0; arg->s->moveset->sorted_moves[i] != NULLMOVE; i++) { |
| 103 | m = arg->sa->moveset->sorted_moves[i]; | 107 | m = arg->s->moveset->sorted_moves[i]; |
| 104 | if (allowed_next(m, arg->sa, arg->last[0], arg->last[1])) { | 108 | if (allowed_next(m, arg->s, arg->last[0], arg->last[1])) { |
| 105 | copy_dfsarg(arg, &newarg); | 109 | copy_dfsarg(arg, &newarg); |
| 106 | newarg.last[1] = arg->last[0]; | 110 | newarg.last[1] = arg->last[0]; |
| 107 | newarg.last[0] = m; | 111 | newarg.last[0] = m; |
| @@ -120,9 +124,9 @@ dfs_add_sol(DfsArg *arg) | |||
| 120 | { | 124 | { |
| 121 | bool valid, accepted, nisscanc; | 125 | bool valid, accepted, nisscanc; |
| 122 | 126 | ||
| 123 | valid = arg->sa->is_valid==NULL || arg->sa->is_valid(arg->current_alg); | 127 | valid = arg->s->is_valid==NULL || arg->s->is_valid(arg->current_alg); |
| 124 | accepted = valid || arg->opts->all; | 128 | accepted = valid || arg->opts->all; |
| 125 | nisscanc = arg->sa->final && cancel_niss(arg); | 129 | nisscanc = arg->s->final && cancel_niss(arg); |
| 126 | 130 | ||
| 127 | if (accepted && !nisscanc) { | 131 | if (accepted && !nisscanc) { |
| 128 | pthread_mutex_lock(arg->sols_mutex); | 132 | pthread_mutex_lock(arg->sols_mutex); |
| @@ -159,7 +163,7 @@ dfs_niss(DfsArg *arg) | |||
| 159 | compose(c, newarg.cube); | 163 | compose(c, newarg.cube); |
| 160 | 164 | ||
| 161 | /* New indexes */ | 165 | /* New indexes */ |
| 162 | compute_ind(newarg.sa, newarg.cube, newarg.ind); | 166 | compute_ind(newarg.s, newarg.cube, newarg.ind); |
| 163 | 167 | ||
| 164 | swapmove(&(newarg.last[0]), &(newarg.lastinv[0])); | 168 | swapmove(&(newarg.last[0]), &(newarg.lastinv[0])); |
| 165 | swapmove(&(newarg.last[1]), &(newarg.lastinv[1])); | 169 | swapmove(&(newarg.last[1]), &(newarg.lastinv[1])); |
| @@ -175,36 +179,35 @@ dfs_niss(DfsArg *arg) | |||
| 175 | static bool | 179 | static bool |
| 176 | dfs_move_checkstop(DfsArg *arg) | 180 | dfs_move_checkstop(DfsArg *arg) |
| 177 | { | 181 | { |
| 178 | bool b; | 182 | int i, goal, nsols; |
| 179 | int i, goal; | ||
| 180 | Move mm; | 183 | Move mm; |
| 181 | Trans tt = uf; /* Avoid uninitialized warning */ | 184 | Trans tt = uf; /* Avoid uninitialized warning */ |
| 182 | 185 | ||
| 183 | /* Moving */ | 186 | /* Moving and computing bound */ |
| 184 | if (arg->last[0] != NULLMOVE) { | 187 | arg->bound = 0; |
| 185 | for (i = 0; i < arg->sa->n_coord; i++) { | 188 | goal = arg->d - arg->current_alg->len; |
| 189 | for (i = 0; i < arg->s->n_coord; i++) { | ||
| 190 | if (arg->last[0] != NULLMOVE) { | ||
| 186 | mm = transform_move(arg->ind[i].t, arg->last[0]); | 191 | mm = transform_move(arg->ind[i].t, arg->last[0]); |
| 187 | arg->ind[i].val = move_coord(arg->sa->coord[i], | 192 | arg->ind[i].val = move_coord(arg->s->coord[i], |
| 188 | mm, arg->ind[i].val, &tt); | 193 | mm, arg->ind[i].val, &tt); |
| 189 | arg->ind[i].t = transform_trans(tt, arg->ind[i].t); | 194 | arg->ind[i].t = transform_trans(tt, arg->ind[i].t); |
| 190 | } | 195 | } |
| 191 | } | ||
| 192 | 196 | ||
| 193 | /* Computing bound for coordinates */ | 197 | arg->bound = |
| 194 | goal = arg->d - arg->current_alg->len; | 198 | MAX(arg->bound, ptableval(arg->s->pd[i], arg->ind[i].val)); |
| 195 | arg->bound = estimate_stepalt(arg->sa, arg->ind, goal); | 199 | if (arg->opts->can_niss && !arg->niss) |
| 196 | if (arg->opts->can_niss && !arg->niss) | 200 | arg->bound = MIN(1, arg->bound); |
| 197 | arg->bound = MIN(1, arg->bound); | ||
| 198 | 201 | ||
| 199 | if (arg->bound > goal) { | 202 | if (arg->bound > goal) |
| 200 | b = true; | 203 | return true; |
| 201 | } else { | ||
| 202 | pthread_mutex_lock(arg->sols_mutex); | ||
| 203 | b = arg->sols->len >= arg->opts->max_solutions; | ||
| 204 | pthread_mutex_unlock(arg->sols_mutex); | ||
| 205 | } | 204 | } |
| 206 | 205 | ||
| 207 | return b; | 206 | pthread_mutex_lock(arg->sols_mutex); |
| 207 | nsols = arg->sols->len; | ||
| 208 | pthread_mutex_unlock(arg->sols_mutex); | ||
| 209 | |||
| 210 | return nsols >= arg->opts->max_solutions; | ||
| 208 | } | 211 | } |
| 209 | 212 | ||
| 210 | static void * | 213 | static void * |
| @@ -240,7 +243,7 @@ instance_thread(void *arg) | |||
| 240 | invert_cube(&c); | 243 | invert_cube(&c); |
| 241 | 244 | ||
| 242 | copy_dfsarg(&td->arg, &darg); | 245 | copy_dfsarg(&td->arg, &darg); |
| 243 | compute_ind(td->arg.sa, &c, darg.ind); | 246 | compute_ind(td->arg.s, &c, darg.ind); |
| 244 | darg.cube = &c; | 247 | darg.cube = &c; |
| 245 | 248 | ||
| 246 | darg.niss = inv; | 249 | darg.niss = inv; |
| @@ -279,11 +282,11 @@ multidfs(DfsArg *arg) | |||
| 279 | pthread_mutex_init(start_mutex, NULL); | 282 | pthread_mutex_init(start_mutex, NULL); |
| 280 | pthread_mutex_init(sols_mutex, NULL); | 283 | pthread_mutex_init(sols_mutex, NULL); |
| 281 | 284 | ||
| 282 | for (i = 0; arg->sa->moveset->sorted_moves[i] != NULLMOVE; i++) { | 285 | for (i = 0; arg->s->moveset->sorted_moves[i] != NULLMOVE; i++) { |
| 283 | alg = new_alg(""); | 286 | alg = new_alg(""); |
| 284 | append_move(alg, arg->sa->moveset->sorted_moves[i], false); | 287 | append_move(alg, arg->s->moveset->sorted_moves[i], false); |
| 285 | append_alg(start, alg); | 288 | append_alg(start, alg); |
| 286 | if (arg->opts->can_niss && !arg->sa->final) { | 289 | if (arg->opts->can_niss && !arg->s->final) { |
| 287 | alg->inv[0] = true; | 290 | alg->inv[0] = true; |
| 288 | append_alg(start, alg); | 291 | append_alg(start, alg); |
| 289 | } | 292 | } |
| @@ -318,15 +321,25 @@ multidfs(DfsArg *arg) | |||
| 318 | static bool | 321 | static bool |
| 319 | niss_makes_sense(DfsArg *arg) | 322 | niss_makes_sense(DfsArg *arg) |
| 320 | { | 323 | { |
| 321 | Cube testcube; | 324 | Move m, mm; |
| 325 | uint64_t u; | ||
| 326 | int i; | ||
| 322 | 327 | ||
| 323 | if (arg->sa->final || arg->niss || !arg->opts->can_niss) | 328 | if (arg->s->final || arg->niss || !arg->opts->can_niss) |
| 324 | return false; | 329 | return false; |
| 325 | 330 | ||
| 326 | make_solved(&testcube); | 331 | if (arg->last[0] == NULLMOVE) |
| 327 | apply_move(inverse_move(arg->last[0]), &testcube); | 332 | return true; |
| 328 | return arg->current_alg->len == 0 || | 333 | |
| 329 | estimate_stepalt(arg->sa, arg->ind, 0) > 0; | 334 | m = inverse_move(arg->last[0]); |
| 335 | for (i = 0; i < arg->s->n_coord; i++) { | ||
| 336 | mm = transform_move(arg->ind[i].t, m); | ||
| 337 | u = move_coord(arg->s->coord[i], mm, 0, NULL); | ||
| 338 | if (ptableval(arg->s->pd[i], u) > 0) | ||
| 339 | return true; | ||
| 340 | } | ||
| 341 | |||
| 342 | return false; | ||
| 330 | } | 343 | } |
| 331 | 344 | ||
| 332 | static bool | 345 | static bool |
| @@ -344,38 +357,38 @@ solvestop(int d, int op, SolveOptions *opts, AlgList *sols) | |||
| 344 | /* Public functions **********************************************************/ | 357 | /* Public functions **********************************************************/ |
| 345 | 358 | ||
| 346 | AlgList * | 359 | AlgList * |
| 347 | solve(Cube *cube, Step *step, SolveOptions *opts) | 360 | solve(Cube *cube, ChoiceStep *cs, SolveOptions *opts) |
| 348 | { | 361 | { |
| 349 | int i, d, op; | 362 | int i, j, d, op, est; |
| 350 | bool ready[99], one_ready, zerosol; | 363 | bool ready[99], one_ready, zerosol; |
| 351 | Movable ind[99][10]; | 364 | Movable ind[99][10]; |
| 352 | AlgList *s; | 365 | AlgList *s; |
| 353 | Cube *c[99]; | 366 | Cube *c[99]; |
| 354 | DfsArg arg[99]; | 367 | DfsArg arg[99]; |
| 355 | 368 | ||
| 356 | prepare_step(step, opts); | 369 | prepare_cs(cs, opts); |
| 357 | s = new_alglist(); | 370 | s = new_alglist(); |
| 358 | 371 | ||
| 359 | for (i = 0, one_ready = false; step->alt[i] != NULL; i++) { | 372 | for (i = 0, one_ready = false; cs->step[i] != NULL; i++) { |
| 360 | c[i] = malloc(sizeof(Cube)); | 373 | c[i] = malloc(sizeof(Cube)); |
| 361 | copy_cube(cube, c[i]); | 374 | copy_cube(cube, c[i]); |
| 362 | apply_trans(step->t[i], c[i]); | 375 | apply_trans(cs->t[i], c[i]); |
| 363 | 376 | ||
| 364 | arg[i].cube = c[i]; | 377 | arg[i].cube = c[i]; |
| 365 | arg[i].t = step->t[i]; | 378 | arg[i].t = cs->t[i]; |
| 366 | arg[i].sa = step->alt[i]; | 379 | arg[i].s = cs->step[i]; |
| 367 | arg[i].opts = opts; | 380 | arg[i].opts = opts; |
| 368 | arg[i].sols = s; | 381 | arg[i].sols = s; |
| 369 | 382 | ||
| 370 | if ((ready[i] = step->alt[i]->ready(c[i]))) { | 383 | if ((ready[i] = cs->step[i]->ready(c[i]))) { |
| 371 | one_ready = true; | 384 | one_ready = true; |
| 372 | /* Only for local use for 0 moves solutions */ | 385 | /* Only for local use for 0 moves solutions */ |
| 373 | compute_ind(step->alt[i], c[i], ind[i]); | 386 | compute_ind(cs->step[i], c[i], ind[i]); |
| 374 | } | 387 | } |
| 375 | } | 388 | } |
| 376 | if (!one_ready) { | 389 | if (!one_ready) { |
| 377 | fprintf(stderr, "Cube not ready for solving step: "); | 390 | fprintf(stderr, "Cube not ready for solving step: "); |
| 378 | fprintf(stderr, "%s\n", step->ready_msg); | 391 | fprintf(stderr, "%s\n", cs->ready_msg); |
| 379 | return s; | 392 | return s; |
| 380 | } | 393 | } |
| 381 | 394 | ||
| @@ -383,10 +396,16 @@ solve(Cube *cube, Step *step, SolveOptions *opts) | |||
| 383 | * alternatives, all longer solutions will be discarded, so we may | 396 | * alternatives, all longer solutions will be discarded, so we may |
| 384 | * just set its ready[] value to false. If the solution is accepted | 397 | * just set its ready[] value to false. If the solution is accepted |
| 385 | * we append it and start searching from d = 1. */ | 398 | * we append it and start searching from d = 1. */ |
| 386 | for (i = 0, zerosol = false; step->alt[i] != NULL; i++) { | 399 | for (i = 0, zerosol = false; cs->step[i] != NULL; i++) { |
| 387 | if (ready[i] && estimate_stepalt(step->alt[i],ind[i],0) == 0) { | 400 | if (ready[i]) { |
| 388 | ready[i] = false; | 401 | est = 0; |
| 389 | zerosol = true; | 402 | for (j = 0; j < cs->step[i]->n_coord; j++) |
| 403 | est = MAX(est, ptableval(cs->step[i]->pd[j], | ||
| 404 | ind[i][j].val)); | ||
| 405 | if (est == 0) { | ||
| 406 | ready[i] = false; | ||
| 407 | zerosol = true; | ||
| 408 | } | ||
| 390 | } | 409 | } |
| 391 | } | 410 | } |
| 392 | if (zerosol && opts->min_moves == 0) { | 411 | if (zerosol && opts->min_moves == 0) { |
| @@ -401,7 +420,7 @@ solve(Cube *cube, Step *step, SolveOptions *opts) | |||
| 401 | if (opts->verbose) | 420 | if (opts->verbose) |
| 402 | fprintf(stderr, "Searching depth %d\n", d); | 421 | fprintf(stderr, "Searching depth %d\n", d); |
| 403 | 422 | ||
| 404 | for (i=0; step->alt[i]!=NULL && !solvestop(d,op,opts,s); i++) { | 423 | for (i=0; cs->step[i]!=NULL && !solvestop(d,op,opts,s); i++) { |
| 405 | if (!ready[i]) | 424 | if (!ready[i]) |
| 406 | continue; | 425 | continue; |
| 407 | 426 | ||
| @@ -413,7 +432,7 @@ solve(Cube *cube, Step *step, SolveOptions *opts) | |||
| 413 | } | 432 | } |
| 414 | } | 433 | } |
| 415 | 434 | ||
| 416 | for (i = 0; step->alt[i] != NULL; i++) | 435 | for (i = 0; cs->step[i] != NULL; i++) |
| 417 | free(c[i]); | 436 | free(c[i]); |
| 418 | 437 | ||
| 419 | return s; | 438 | return s; |
diff --git a/src/solve.h b/src/solve.h index 9039e4a..9a284ff 100644 --- a/src/solve.h +++ b/src/solve.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include "steps.h" | 5 | #include "steps.h" |
| 6 | #include "trans.h" | 6 | #include "trans.h" |
| 7 | 7 | ||
| 8 | AlgList * solve(Cube *cube, Step *step, SolveOptions *opts); | 8 | AlgList * solve(Cube *cube, ChoiceStep *cs, SolveOptions *opts); |
| 9 | Alg * solve_2phase(Cube *cube, int nthreads); | 9 | Alg * solve_2phase(Cube *cube, int nthreads); |
| 10 | 10 | ||
| 11 | #endif | 11 | #endif |
diff --git a/src/steps.c b/src/steps.c index 81af269..a04d5e2 100644 --- a/src/steps.c +++ b/src/steps.c | |||
| @@ -132,90 +132,40 @@ validate_singlecw_ending(Alg *alg) | |||
| 132 | /* Public functions **********************************************************/ | 132 | /* Public functions **********************************************************/ |
| 133 | 133 | ||
| 134 | void | 134 | void |
| 135 | compute_ind(StepAlt *a, Cube *cube, Movable *ind) | 135 | compute_ind(Step *s, Cube *cube, Movable *ind) |
| 136 | { | 136 | { |
| 137 | int i; | 137 | int i; |
| 138 | Cube mvd; | 138 | Cube mvd; |
| 139 | Trans t, tt; | 139 | Trans t, tt; |
| 140 | 140 | ||
| 141 | for (i = 0; i < a->n_coord; i++) { | 141 | for (i = 0; i < s->n_coord; i++) { |
| 142 | t = a->coord_trans[i]; | 142 | t = s->coord_trans[i]; |
| 143 | copy_cube(cube, &mvd); | 143 | copy_cube(cube, &mvd); |
| 144 | apply_trans(t, &mvd); | 144 | apply_trans(t, &mvd); |
| 145 | 145 | ||
| 146 | ind[i].val = index_coord(a->coord[i], &mvd, &tt); | 146 | ind[i].val = index_coord(s->coord[i], &mvd, &tt); |
| 147 | ind[i].t = transform_trans(tt, t); | 147 | ind[i].t = transform_trans(tt, t); |
| 148 | } | 148 | } |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | int | ||
| 152 | estimate_stepalt(StepAlt *a, Movable *ind, int goal) | ||
| 153 | { | ||
| 154 | int i, ret, est[a->n_coord]; | ||
| 155 | |||
| 156 | for (i = 0; i < a->n_coord; i++) { | ||
| 157 | est[i] = ptableval(a->pd[i], ind[i].val); | ||
| 158 | if (est[i] == a->pd[i]->base && a->compact_pd[i]) | ||
| 159 | est[i] = ptableval(a->fallback_pd[i], | ||
| 160 | ind[i].val/a->fbmod[i]); | ||
| 161 | if (ind[i].val != 0 && est[i] == 0) /* est == 0 iff solved */ | ||
| 162 | est[i] = 1; | ||
| 163 | /* | ||
| 164 | TODO: remove this debug code | ||
| 165 | printf("%d: est=%d | ", i, est[i]); | ||
| 166 | */ | ||
| 167 | |||
| 168 | if (est[i] > goal) | ||
| 169 | return est[i]; | ||
| 170 | } | ||
| 171 | |||
| 172 | for (i = 0; i < a->n_dbtrick; i++) | ||
| 173 | if (est[a->dbtrick[i][0]] > 0 && | ||
| 174 | est[a->dbtrick[i][0]] == est[a->dbtrick[i][1]] && | ||
| 175 | est[a->dbtrick[i][0]] == est[a->dbtrick[i][2]]) | ||
| 176 | est[a->dbtrick[i][0]] += 1; | ||
| 177 | |||
| 178 | for (i = 0, ret = -1; i < a->n_coord; i++) | ||
| 179 | ret = MAX(ret, est[i]); | ||
| 180 | |||
| 181 | /* | ||
| 182 | TODO: remove this debug code | ||
| 183 | printf("Final estimate: %d\n", ret); | ||
| 184 | */ | ||
| 185 | |||
| 186 | return ret; | ||
| 187 | } | ||
| 188 | |||
| 189 | void | 151 | void |
| 190 | prepare_step(Step *step, SolveOptions *opts) | 152 | prepare_cs(ChoiceStep *cs, SolveOptions *opts) |
| 191 | { | 153 | { |
| 192 | int i, j; | 154 | int i, j; |
| 193 | PDGenData pdg; | 155 | PDGenData pdg; |
| 194 | StepAlt *a; | 156 | Step *s; |
| 195 | 157 | ||
| 196 | for (i = 0; step->alt[i] != NULL; i++) { | 158 | for (i = 0; cs->step[i] != NULL; i++) { |
| 197 | a = step->alt[i]; | 159 | s = cs->step[i]; |
| 198 | init_moveset(a->moveset); | 160 | init_moveset(s->moveset); |
| 199 | pdg.moveset = a->moveset; | 161 | pdg.moveset = s->moveset; |
| 200 | for (j = 0; j < a->n_coord; j++) { | 162 | for (j = 0; j < s->n_coord; j++) { |
| 201 | gen_coord(a->coord[j]); | 163 | gen_coord(s->coord[j]); |
| 202 | 164 | ||
| 203 | pdg.coord = a->coord[j]; | 165 | pdg.coord = s->coord[j]; |
| 204 | pdg.compact = a->compact_pd[j]; | ||
| 205 | pdg.pd = NULL; | 166 | pdg.pd = NULL; |
| 206 | 167 | ||
| 207 | a->pd[j] = genptable(&pdg, opts->nthreads); | 168 | s->pd[j] = genptable(&pdg, opts->nthreads); |
| 208 | |||
| 209 | if (a->compact_pd[j]) { | ||
| 210 | gen_coord(a->fallback_coord[j]); | ||
| 211 | |||
| 212 | pdg.coord = a->fallback_coord[j]; | ||
| 213 | pdg.compact = false; | ||
| 214 | pdg.pd = NULL; | ||
| 215 | |||
| 216 | a->fallback_pd[j] = | ||
| 217 | genptable(&pdg, opts->nthreads); | ||
| 218 | } | ||
| 219 | } | 169 | } |
| 220 | } | 170 | } |
| 221 | } | 171 | } |
diff --git a/src/steps.h b/src/steps.h index 341be98..0511b27 100644 --- a/src/steps.h +++ b/src/steps.h | |||
| @@ -13,9 +13,8 @@ bool check_cornershtr(Cube *cube); | |||
| 13 | bool check_eofb(Cube *cube); | 13 | bool check_eofb(Cube *cube); |
| 14 | bool check_drud(Cube *cube); | 14 | bool check_drud(Cube *cube); |
| 15 | bool check_htr(Cube *cube); | 15 | bool check_htr(Cube *cube); |
| 16 | void compute_ind(StepAlt *a, Cube *cube, Movable *ind); | 16 | void compute_ind(Step *a, Cube *cube, Movable *ind); |
| 17 | int estimate_stepalt(StepAlt *a, Movable *ind, int goal); | 17 | void prepare_cs(ChoiceStep *cs, SolveOptions *opts); |
| 18 | void prepare_step(Step *step, SolveOptions *opts); | ||
| 19 | bool always_valid(Alg *alg); | 18 | bool always_valid(Alg *alg); |
| 20 | bool validate_singlecw_ending(Alg *alg); | 19 | bool validate_singlecw_ending(Alg *alg); |
| 21 | 20 | ||
| @@ -27,26 +26,25 @@ extern char check_dr_msg[100]; | |||
| 27 | extern char check_htr_msg[100]; | 26 | extern char check_htr_msg[100]; |
| 28 | extern char check_drany_msg[100]; | 27 | extern char check_drany_msg[100]; |
| 29 | 28 | ||
| 30 | extern StepAlt sa_nxopt31_HTM; | 29 | extern Step step_eofb_HTM; |
| 31 | extern StepAlt sa_eofb_HTM; | 30 | extern Step step_drud_HTM; |
| 32 | extern StepAlt sa_drud_HTM; | 31 | extern Step step_drfin_drud; |
| 33 | extern StepAlt sa_drfin_drud; | ||
| 34 | 32 | ||
| 35 | extern Step optimal_HTM; | 33 | extern ChoiceStep optimal_HTM; |
| 36 | extern Step eoany_HTM; | 34 | extern ChoiceStep eoany_HTM; |
| 37 | extern Step eofb_HTM; | 35 | extern ChoiceStep eofb_HTM; |
| 38 | extern Step eorl_HTM; | 36 | extern ChoiceStep eorl_HTM; |
| 39 | extern Step eoud_HTM; | 37 | extern ChoiceStep eoud_HTM; |
| 40 | extern Step drany_HTM; | 38 | extern ChoiceStep drany_HTM; |
| 41 | extern Step drud_HTM; | 39 | extern ChoiceStep drud_HTM; |
| 42 | extern Step drrl_HTM; | 40 | extern ChoiceStep drrl_HTM; |
| 43 | extern Step drfb_HTM; | 41 | extern ChoiceStep drfb_HTM; |
| 44 | extern Step dranyfin_DR; | 42 | extern ChoiceStep dranyfin_DR; |
| 45 | extern Step drudfin_drud; | 43 | extern ChoiceStep drudfin_drud; |
| 46 | extern Step drrlfin_drrl; | 44 | extern ChoiceStep drrlfin_drrl; |
| 47 | extern Step drfbfin_drfb; | 45 | extern ChoiceStep drfbfin_drfb; |
| 48 | 46 | ||
| 49 | extern Step *steps[]; | 47 | extern ChoiceStep *csteps[]; |
| 50 | 48 | ||
| 51 | #else | 49 | #else |
| 52 | 50 | ||
| @@ -56,83 +54,51 @@ char check_dr_msg[100] = "DR must be solved on given axis"; | |||
| 56 | char check_htr_msg[100] = "HTR must be solved"; | 54 | char check_htr_msg[100] = "HTR must be solved"; |
| 57 | char check_drany_msg[100] = "DR must be solved on at least one axis"; | 55 | char check_drany_msg[100] = "DR must be solved on at least one axis"; |
| 58 | 56 | ||
| 59 | /* Optimal solvers *******************/ | ||
| 60 | /* TODO: build options for smaller optimal solvers */ | ||
| 61 | |||
| 62 | StepAlt | ||
| 63 | sa_nxopt31_HTM = { | ||
| 64 | .ready = check_centers, | ||
| 65 | .final = true, | ||
| 66 | .moveset = &moveset_HTM, | ||
| 67 | .n_coord = 6, | ||
| 68 | .coord = {&coord_nxopt31, &coord_nxopt31, &coord_nxopt31, | ||
| 69 | &coord_eposepe, &coord_eposepe, &coord_eposepe}, | ||
| 70 | /* TODO: use khuge as fallback? */ | ||
| 71 | .coord_trans = {uf, rd, bl, uf, rd, bl}, | ||
| 72 | .compact_pd = {true, true, true, false, false, false}, | ||
| 73 | .fallback_coord = {&coord_drud_sym16, &coord_drud_sym16, | ||
| 74 | &coord_drud_sym16}, | ||
| 75 | .fbmod = {BINOM8ON4, BINOM8ON4, BINOM8ON4}, | ||
| 76 | .n_dbtrick = 1, /* TODO: change to 2 when khuge */ | ||
| 77 | .dbtrick = {{0, 1, 2}}, | ||
| 78 | .is_valid = NULL, | ||
| 79 | }; | ||
| 80 | Step | ||
| 81 | optimal_HTM = { | ||
| 82 | .shortname = "optimal", | ||
| 83 | .name = "Optimal solve (in HTM)", | ||
| 84 | .alt = {&sa_nxopt31_HTM, NULL}, | ||
| 85 | .t = {uf}, | ||
| 86 | .ready_msg = check_centers_msg, | ||
| 87 | }; | ||
| 88 | |||
| 89 | /* Optimal after EO ******************/ | 57 | /* Optimal after EO ******************/ |
| 90 | /* TODO: eofin_eo (generic), eofbfin_eofb, eorlfin_eorl, eoudfin_eoud */ | 58 | /* TODO: eofin_eo (generic), eofbfin_eofb, eorlfin_eorl, eoudfin_eoud */ |
| 91 | 59 | ||
| 92 | /* EO steps **************************/ | 60 | /* EO steps **************************/ |
| 93 | /* TODO: eoany_HTM (generic), eofb_HTM, eorl_HTM, eoud_HTM */ | 61 | /* TODO: eoany_HTM (generic), eofb_HTM, eorl_HTM, eoud_HTM */ |
| 94 | 62 | ||
| 95 | StepAlt | 63 | Step |
| 96 | sa_eofb_HTM = { | 64 | step_eofb_HTM = { |
| 97 | .ready = check_centers, | 65 | .ready = check_centers, |
| 98 | .final = false, | 66 | .final = false, |
| 99 | .moveset = &moveset_HTM, | 67 | .moveset = &moveset_HTM, |
| 100 | .n_coord = 1, | 68 | .n_coord = 1, |
| 101 | .coord = {&coord_eofb}, | 69 | .coord = {&coord_eofb}, |
| 102 | .coord_trans = {uf}, | 70 | .coord_trans = {uf}, |
| 103 | .compact_pd = {false}, | ||
| 104 | .n_dbtrick = 0, | ||
| 105 | .is_valid = validate_singlecw_ending, | 71 | .is_valid = validate_singlecw_ending, |
| 106 | }; | 72 | }; |
| 107 | Step | 73 | ChoiceStep |
| 108 | eoany_HTM = { | 74 | eoany_HTM = { |
| 109 | .shortname = "eo", | 75 | .shortname = "eo", |
| 110 | .name = "EO on any axis", | 76 | .name = "EO on any axis", |
| 111 | .alt = {&sa_eofb_HTM, &sa_eofb_HTM, &sa_eofb_HTM, NULL}, | 77 | .step = {&step_eofb_HTM, &step_eofb_HTM, &step_eofb_HTM, NULL}, |
| 112 | .t = {uf, ur, fd}, | 78 | .t = {uf, ur, fd}, |
| 113 | .ready_msg = check_centers_msg, | 79 | .ready_msg = check_centers_msg, |
| 114 | }; | 80 | }; |
| 115 | Step | 81 | ChoiceStep |
| 116 | eofb_HTM = { | 82 | eofb_HTM = { |
| 117 | .shortname = "eofb", | 83 | .shortname = "eofb", |
| 118 | .name = "EO on F/B", | 84 | .name = "EO on F/B", |
| 119 | .alt = {&sa_eofb_HTM, NULL}, | 85 | .step = {&step_eofb_HTM, NULL}, |
| 120 | .t = {uf}, | 86 | .t = {uf}, |
| 121 | .ready_msg = check_centers_msg, | 87 | .ready_msg = check_centers_msg, |
| 122 | }; | 88 | }; |
| 123 | Step | 89 | ChoiceStep |
| 124 | eorl_HTM = { | 90 | eorl_HTM = { |
| 125 | .shortname = "eorl", | 91 | .shortname = "eorl", |
| 126 | .name = "EO on R/L", | 92 | .name = "EO on R/L", |
| 127 | .alt = {&sa_eofb_HTM, NULL}, | 93 | .step = {&step_eofb_HTM, NULL}, |
| 128 | .t = {ur}, | 94 | .t = {ur}, |
| 129 | .ready_msg = check_centers_msg, | 95 | .ready_msg = check_centers_msg, |
| 130 | }; | 96 | }; |
| 131 | Step | 97 | ChoiceStep |
| 132 | eoud_HTM = { | 98 | eoud_HTM = { |
| 133 | .shortname = "eoud", | 99 | .shortname = "eoud", |
| 134 | .name = "EO on U/D", | 100 | .name = "EO on U/D", |
| 135 | .alt = {&sa_eofb_HTM, NULL}, | 101 | .step = {&step_eofb_HTM, NULL}, |
| 136 | .t = {fd}, | 102 | .t = {fd}, |
| 137 | .ready_msg = check_centers_msg, | 103 | .ready_msg = check_centers_msg, |
| 138 | }; | 104 | }; |
| @@ -150,93 +116,90 @@ eoud_HTM = { | |||
| 150 | /* TODO: dr_eofb (generic), dr_eorl (generic), dr_eoud (generic) */ | 116 | /* TODO: dr_eofb (generic), dr_eorl (generic), dr_eoud (generic) */ |
| 151 | /* TODO: drud_eofb, drrl_eofb, drud_eorl, drfb_eorl, drrl_eoud, drfb_eoud */ | 117 | /* TODO: drud_eofb, drrl_eofb, drud_eorl, drfb_eorl, drrl_eoud, drfb_eoud */ |
| 152 | 118 | ||
| 153 | StepAlt | 119 | Step |
| 154 | sa_drud_HTM = { | 120 | step_drud_HTM = { |
| 155 | .ready = check_centers, | 121 | .ready = check_centers, |
| 156 | .final = false, | 122 | .final = false, |
| 157 | .moveset = &moveset_HTM, | 123 | .moveset = &moveset_HTM, |
| 158 | .n_coord = 1, | 124 | .n_coord = 1, |
| 159 | .coord = {&coord_drud_sym16}, | 125 | .coord = {&coord_drud_sym16}, |
| 160 | .coord_trans = {uf}, | 126 | .coord_trans = {uf}, |
| 161 | .compact_pd = {false}, /* TODO: maybe compactify */ | ||
| 162 | .n_dbtrick = 0, | ||
| 163 | .is_valid = validate_singlecw_ending, | 127 | .is_valid = validate_singlecw_ending, |
| 164 | }; | 128 | }; |
| 165 | Step | 129 | ChoiceStep |
| 166 | drany_HTM = { | 130 | drany_HTM = { |
| 167 | .shortname = "dr", | 131 | .shortname = "dr", |
| 168 | .name = "DR on any axis", | 132 | .name = "DR on any axis", |
| 169 | .alt = {&sa_drud_HTM, &sa_drud_HTM, &sa_drud_HTM, NULL}, | 133 | .step = {&step_drud_HTM, &step_drud_HTM, &step_drud_HTM, NULL}, |
| 170 | .t = {uf, rf, fd}, | 134 | .t = {uf, rf, fd}, |
| 171 | .ready_msg = check_centers_msg, | 135 | .ready_msg = check_centers_msg, |
| 172 | }; | 136 | }; |
| 173 | Step | 137 | ChoiceStep |
| 174 | drud_HTM = { | 138 | drud_HTM = { |
| 175 | .shortname = "drud", | 139 | .shortname = "drud", |
| 176 | .name = "DR on U/D", | 140 | .name = "DR on U/D", |
| 177 | .alt = {&sa_drud_HTM, NULL}, | 141 | .step = {&step_drud_HTM, NULL}, |
| 178 | .t = {uf}, | 142 | .t = {uf}, |
| 179 | .ready_msg = check_centers_msg, | 143 | .ready_msg = check_centers_msg, |
| 180 | }; | 144 | }; |
| 181 | Step | 145 | ChoiceStep |
| 182 | drrl_HTM = { | 146 | drrl_HTM = { |
| 183 | .shortname = "drrl", | 147 | .shortname = "drrl", |
| 184 | .name = "DR on R/L", | 148 | .name = "DR on R/L", |
| 185 | .alt = {&sa_drud_HTM, NULL}, | 149 | .step = {&step_drud_HTM, NULL}, |
| 186 | .t = {rf}, | 150 | .t = {rf}, |
| 187 | .ready_msg = check_centers_msg, | 151 | .ready_msg = check_centers_msg, |
| 188 | }; | 152 | }; |
| 189 | Step | 153 | ChoiceStep |
| 190 | drfb_HTM = { | 154 | drfb_HTM = { |
| 191 | .shortname = "drfb", | 155 | .shortname = "drfb", |
| 192 | .name = "DR on F/B", | 156 | .name = "DR on F/B", |
| 193 | .alt = {&sa_drud_HTM, NULL}, | 157 | .step = {&step_drud_HTM, NULL}, |
| 194 | .t = {fd}, | 158 | .t = {fd}, |
| 195 | .ready_msg = check_centers_msg, | 159 | .ready_msg = check_centers_msg, |
| 196 | }; | 160 | }; |
| 197 | 161 | ||
| 198 | /* DR finish steps */ | 162 | /* DR finish steps */ |
| 199 | StepAlt | 163 | Step |
| 200 | sa_drfin_drud = { | 164 | step_drfin_drud = { |
| 201 | .ready = check_drud, | 165 | .ready = check_drud, |
| 202 | .final = true, | 166 | .final = true, |
| 203 | .moveset = &moveset_drud, | 167 | .moveset = &moveset_drud, |
| 204 | .n_coord = 1, | 168 | .n_coord = 1, |
| 205 | .coord = {&coord_drudfin_noE_sym16}, /* TODO: maybe no noE */ | 169 | .coord = {&coord_drudfin_noE_sym16}, /* TODO: maybe no noE */ |
| 206 | .coord_trans = {uf}, | 170 | .coord_trans = {uf}, |
| 207 | .compact_pd = {false}, /* TODO: maybe compactify */ | ||
| 208 | .n_dbtrick = 0, | ||
| 209 | .is_valid = NULL, | 171 | .is_valid = NULL, |
| 210 | }; | 172 | }; |
| 211 | Step | 173 | ChoiceStep |
| 212 | dranyfin_DR = { | 174 | dranyfin_DR = { |
| 213 | .shortname = "drfin", | 175 | .shortname = "drfin", |
| 214 | .name = "DR finish on any axis without breaking DR", | 176 | .name = "DR finish on any axis without breaking DR", |
| 215 | .alt = {&sa_drfin_drud, &sa_drfin_drud, &sa_drfin_drud, NULL}, | 177 | .step = {&step_drfin_drud, &step_drfin_drud, |
| 178 | &step_drfin_drud, NULL}, | ||
| 216 | .t = {uf, rf, fd}, | 179 | .t = {uf, rf, fd}, |
| 217 | .ready_msg = check_dr_msg, | 180 | .ready_msg = check_dr_msg, |
| 218 | }; | 181 | }; |
| 219 | Step | 182 | ChoiceStep |
| 220 | drudfin_drud = { | 183 | drudfin_drud = { |
| 221 | .shortname = "drudfin", | 184 | .shortname = "drudfin", |
| 222 | .name = "DR finis on U/D without breaking DR", | 185 | .name = "DR finis on U/D without breaking DR", |
| 223 | .alt = {&sa_drfin_drud, NULL}, | 186 | .step = {&step_drfin_drud, NULL}, |
| 224 | .t = {uf}, | 187 | .t = {uf}, |
| 225 | .ready_msg = check_dr_msg, | 188 | .ready_msg = check_dr_msg, |
| 226 | }; | 189 | }; |
| 227 | Step | 190 | ChoiceStep |
| 228 | drrlfin_drrl = { | 191 | drrlfin_drrl = { |
| 229 | .shortname = "drrlfin", | 192 | .shortname = "drrlfin", |
| 230 | .name = "DR finish on R/L without breaking DR", | 193 | .name = "DR finish on R/L without breaking DR", |
| 231 | .alt = {&sa_drfin_drud, NULL}, | 194 | .step = {&step_drfin_drud, NULL}, |
| 232 | .t = {rf}, | 195 | .t = {rf}, |
| 233 | .ready_msg = check_dr_msg, | 196 | .ready_msg = check_dr_msg, |
| 234 | }; | 197 | }; |
| 235 | Step | 198 | ChoiceStep |
| 236 | drfbfin_drfb = { | 199 | drfbfin_drfb = { |
| 237 | .shortname = "drfbfin", | 200 | .shortname = "drfbfin", |
| 238 | .name = "DR finish on F/B without breaking DR", | 201 | .name = "DR finish on F/B without breaking DR", |
| 239 | .alt = {&sa_drfin_drud, NULL}, | 202 | .step = {&step_drfin_drud, NULL}, |
| 240 | .t = {fd}, | 203 | .t = {fd}, |
| 241 | .ready_msg = check_dr_msg, | 204 | .ready_msg = check_dr_msg, |
| 242 | }; | 205 | }; |
| @@ -247,13 +210,16 @@ drfbfin_drfb = { | |||
| 247 | /* HTR finish */ | 210 | /* HTR finish */ |
| 248 | /* TODO: htrfin_htr */ | 211 | /* TODO: htrfin_htr */ |
| 249 | 212 | ||
| 250 | Step *steps[] = { | 213 | ChoiceStep *csteps[] = { |
| 251 | &optimal_HTM, /* first is default */ | 214 | /* TODO: re-implement optimal |
| 215 | &optimal_HTM, | ||
| 216 | */ | ||
| 252 | 217 | ||
| 253 | &eoany_HTM, &eofb_HTM, &eorl_HTM, &eoud_HTM, | 218 | &eoany_HTM, &eofb_HTM, &eorl_HTM, &eoud_HTM, |
| 254 | &drany_HTM, &drud_HTM, &drrl_HTM, &drfb_HTM, | 219 | &drany_HTM, &drud_HTM, &drrl_HTM, &drfb_HTM, |
| 255 | &dranyfin_DR, &drudfin_drud, &drrlfin_drrl, &drfbfin_drfb, | 220 | &dranyfin_DR, &drudfin_drud, &drrlfin_drrl, &drfbfin_drfb, |
| 256 | 221 | ||
| 222 | NULL | ||
| 257 | /* TODO: | 223 | /* TODO: |
| 258 | &optimal_light_HTM, | 224 | &optimal_light_HTM, |
| 259 | 225 | ||
