aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2022-09-06 23:25:31 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2022-09-06 23:25:31 +0200
commit569983380edfb3744192b5a652e2ac038840e53d (patch)
treefeea695d10d6984b45ce2a55efec3f10e5ff36be
parenta125e69c8ce0a2764b1e50b2dad0a4fa9d141ef4 (diff)
downloadnissy-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.md36
-rw-r--r--src/commands.c20
-rw-r--r--src/cubetypes.h64
-rw-r--r--src/pruning.c99
-rw-r--r--src/solve.c133
-rw-r--r--src/solve.h2
-rw-r--r--src/steps.c78
-rw-r--r--src/steps.h144
8 files changed, 202 insertions, 374 deletions
diff --git a/TODO.md b/TODO.md
index b7481f1..fb57dd1 100644
--- a/TODO.md
+++ b/TODO.md
@@ -3,20 +3,28 @@
3This is a list of things that I would like to add or change at some point. 3This is a list of things that I would like to add or change at some point.
4It's more of a personal reminder than anything else. 4It'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
5static bool read_step(CommandArgs *args, char *str); 5static bool read_cs(CommandArgs *args, char *str);
6static bool read_scrtype(CommandArgs *args, char *str); 6static bool read_scrtype(CommandArgs *args, char *str);
7static bool read_scramble(int c, char **v, CommandArgs *args); 7static 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
352void 352void
@@ -503,13 +503,13 @@ read_scrtype(CommandArgs *args, char *str)
503} 503}
504 504
505static bool 505static bool
506read_step(CommandArgs *args, char *str) 506read_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
84typedef struct alg Alg; 84typedef struct alg Alg;
85typedef struct alglist AlgList; 85typedef struct alglist AlgList;
86typedef struct alglistnode AlgListNode; 86typedef struct alglistnode AlgListNode;
87typedef struct block Block; 87typedef struct choicestep ChoiceStep;
88typedef struct command Command; 88typedef struct command Command;
89typedef struct commandargs CommandArgs; 89typedef struct commandargs CommandArgs;
90typedef struct coordinate Coordinate; 90typedef struct coordinate Coordinate;
@@ -97,13 +97,14 @@ typedef struct pdgendata PDGenData;
97typedef struct prunedata PruneData; 97typedef struct prunedata PruneData;
98typedef struct solveoptions SolveOptions; 98typedef struct solveoptions SolveOptions;
99typedef struct step Step; 99typedef struct step Step;
100typedef struct stepalt StepAlt;
101typedef struct symdata SymData; 100typedef struct symdata SymData;
102typedef struct threaddatasolve ThreadDataSolve; 101typedef struct threaddatasolve ThreadDataSolve;
103typedef struct threaddatagenpt ThreadDataGenpt; 102typedef struct threaddatagenpt ThreadDataGenpt;
104typedef struct transgroup TransGroup; 103typedef struct transgroup TransGroup;
105 104
106typedef bool (*Checker) (Cube *); 105typedef bool (*Checker) (Cube *);
106typedef bool (*DfsMover) (DfsArg *);
107typedef void (*DfsExtraCopier) (void *, void *);
107typedef bool (*Validator) (Alg *); 108typedef bool (*Validator) (Alg *);
108typedef void (*Exec) (CommandArgs *); 109typedef void (*Exec) (CommandArgs *);
109typedef CommandArgs * (*ArgParser) (int, char **); 110typedef CommandArgs * (*ArgParser) (int, char **);
@@ -137,11 +138,13 @@ alglistnode
137}; 138};
138 139
139struct 140struct
140block 141choicestep
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
147struct 150struct
@@ -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
225struct 229struct
@@ -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
265struct 265struct
@@ -280,54 +280,18 @@ solveoptions
280struct 280struct
281step 281step
282{ 282{
283 char * shortname;
284 char * name;
285 StepAlt * alt[99];
286 Trans t[99];
287 char * ready_msg;
288};
289
290struct
291stepalt
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/*
314struct
315symdata
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
331struct 295struct
332threaddatasolve 296threaddatasolve
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
8static int findchunk(PruneData *pd, int nchunks, uint64_t i); 7static int findchunk(PruneData *pd, int nchunks, uint64_t i);
9static void genptable_bfs(PruneData *pd, int d, int nt, int nc); 8static void genptable_bfs(PruneData *pd, int d, int nt, int nc);
10static void genptable_compress(PruneData *pd);
11static void genptable_fixnasty(PruneData *pd, int d, int nthreads); 9static void genptable_fixnasty(PruneData *pd, int d, int nthreads);
12static void genptable_setbase(PruneData *pd);
13static void * instance_bfs(void *arg); 10static void * instance_bfs(void *arg);
14static void * instance_fixnasty(void *arg); 11static void * instance_fixnasty(void *arg);
15static void ptable_update(PruneData *pd, uint64_t ind, int m); 12static void ptable_update(PruneData *pd, uint64_t ind, int m);
@@ -32,16 +29,13 @@ findchunk(PruneData *pd, int nchunks, uint64_t i)
32PruneData * 29PruneData *
33genptable(PDGenData *pdg, int nthreads) 30genptable(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
158static void 139static void
159genptable_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
183static void
184genptable_fixnasty(PruneData *pd, int d, int nthreads) 140genptable_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
211static void
212genptable_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
227static void * 167static void *
228instance_bfs(void *arg) 168instance_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)
325uint64_t 264uint64_t
326ptablesize(PruneData *pd) 265ptablesize(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
335static void 270static void
@@ -350,23 +285,11 @@ ptable_update(PruneData *pd, uint64_t ind, int n)
350int 285int
351ptableval(PruneData *pd, uint64_t ind) 286ptableval(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
372static bool 295static 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
7static bool allowed_next(Move move, StepAlt *sa, Move l0, Move l1); 7static bool allowed_next(Move move, Step *s, Move l0, Move l1);
8static bool cancel_niss(DfsArg *arg); 8static bool cancel_niss(DfsArg *arg);
9static void copy_dfsarg(DfsArg *src, DfsArg *dst); 9static void copy_dfsarg(DfsArg *src, DfsArg *dst);
10static void dfs(DfsArg *arg); 10static 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
21static bool 21static bool
22allowed_next(Move m, StepAlt *sa, Move l0, Move l1) 22allowed_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
86static void 90static 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)
175static bool 179static bool
176dfs_move_checkstop(DfsArg *arg) 180dfs_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
210static void * 213static 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)
318static bool 321static bool
319niss_makes_sense(DfsArg *arg) 322niss_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
332static bool 345static bool
@@ -344,38 +357,38 @@ solvestop(int d, int op, SolveOptions *opts, AlgList *sols)
344/* Public functions **********************************************************/ 357/* Public functions **********************************************************/
345 358
346AlgList * 359AlgList *
347solve(Cube *cube, Step *step, SolveOptions *opts) 360solve(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
8AlgList * solve(Cube *cube, Step *step, SolveOptions *opts); 8AlgList * solve(Cube *cube, ChoiceStep *cs, SolveOptions *opts);
9Alg * solve_2phase(Cube *cube, int nthreads); 9Alg * 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
134void 134void
135compute_ind(StepAlt *a, Cube *cube, Movable *ind) 135compute_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
151int
152estimate_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/*
164TODO: remove this debug code
165printf("%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/*
182TODO: remove this debug code
183printf("Final estimate: %d\n", ret);
184*/
185
186 return ret;
187}
188
189void 151void
190prepare_step(Step *step, SolveOptions *opts) 152prepare_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);
13bool check_eofb(Cube *cube); 13bool check_eofb(Cube *cube);
14bool check_drud(Cube *cube); 14bool check_drud(Cube *cube);
15bool check_htr(Cube *cube); 15bool check_htr(Cube *cube);
16void compute_ind(StepAlt *a, Cube *cube, Movable *ind); 16void compute_ind(Step *a, Cube *cube, Movable *ind);
17int estimate_stepalt(StepAlt *a, Movable *ind, int goal); 17void prepare_cs(ChoiceStep *cs, SolveOptions *opts);
18void prepare_step(Step *step, SolveOptions *opts);
19bool always_valid(Alg *alg); 18bool always_valid(Alg *alg);
20bool validate_singlecw_ending(Alg *alg); 19bool validate_singlecw_ending(Alg *alg);
21 20
@@ -27,26 +26,25 @@ extern char check_dr_msg[100];
27extern char check_htr_msg[100]; 26extern char check_htr_msg[100];
28extern char check_drany_msg[100]; 27extern char check_drany_msg[100];
29 28
30extern StepAlt sa_nxopt31_HTM; 29extern Step step_eofb_HTM;
31extern StepAlt sa_eofb_HTM; 30extern Step step_drud_HTM;
32extern StepAlt sa_drud_HTM; 31extern Step step_drfin_drud;
33extern StepAlt sa_drfin_drud;
34 32
35extern Step optimal_HTM; 33extern ChoiceStep optimal_HTM;
36extern Step eoany_HTM; 34extern ChoiceStep eoany_HTM;
37extern Step eofb_HTM; 35extern ChoiceStep eofb_HTM;
38extern Step eorl_HTM; 36extern ChoiceStep eorl_HTM;
39extern Step eoud_HTM; 37extern ChoiceStep eoud_HTM;
40extern Step drany_HTM; 38extern ChoiceStep drany_HTM;
41extern Step drud_HTM; 39extern ChoiceStep drud_HTM;
42extern Step drrl_HTM; 40extern ChoiceStep drrl_HTM;
43extern Step drfb_HTM; 41extern ChoiceStep drfb_HTM;
44extern Step dranyfin_DR; 42extern ChoiceStep dranyfin_DR;
45extern Step drudfin_drud; 43extern ChoiceStep drudfin_drud;
46extern Step drrlfin_drrl; 44extern ChoiceStep drrlfin_drrl;
47extern Step drfbfin_drfb; 45extern ChoiceStep drfbfin_drfb;
48 46
49extern Step *steps[]; 47extern 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";
56char check_htr_msg[100] = "HTR must be solved"; 54char check_htr_msg[100] = "HTR must be solved";
57char check_drany_msg[100] = "DR must be solved on at least one axis"; 55char 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
62StepAlt
63sa_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};
80Step
81optimal_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
95StepAlt 63Step
96sa_eofb_HTM = { 64step_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};
107Step 73ChoiceStep
108eoany_HTM = { 74eoany_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};
115Step 81ChoiceStep
116eofb_HTM = { 82eofb_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};
123Step 89ChoiceStep
124eorl_HTM = { 90eorl_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};
131Step 97ChoiceStep
132eoud_HTM = { 98eoud_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
153StepAlt 119Step
154sa_drud_HTM = { 120step_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};
165Step 129ChoiceStep
166drany_HTM = { 130drany_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};
173Step 137ChoiceStep
174drud_HTM = { 138drud_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};
181Step 145ChoiceStep
182drrl_HTM = { 146drrl_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};
189Step 153ChoiceStep
190drfb_HTM = { 154drfb_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 */
199StepAlt 163Step
200sa_drfin_drud = { 164step_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};
211Step 173ChoiceStep
212dranyfin_DR = { 174dranyfin_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};
219Step 182ChoiceStep
220drudfin_drud = { 183drudfin_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};
227Step 190ChoiceStep
228drrlfin_drrl = { 191drrlfin_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};
235Step 198ChoiceStep
236drfbfin_drfb = { 199drfbfin_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
250Step *steps[] = { 213ChoiceStep *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
222NULL
257/* TODO: 223/* TODO:
258 &optimal_light_HTM, 224 &optimal_light_HTM,
259 225

Generated with cgit - Back to sebastiano.tronto.net