aboutsummaryrefslogtreecommitdiff
path: root/src/steps.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/steps.c')
-rw-r--r--src/steps.c1514
1 files changed, 127 insertions, 1387 deletions
diff --git a/src/steps.c b/src/steps.c
index 3189811..81af269 100644
--- a/src/steps.c
+++ b/src/steps.c
@@ -1,1372 +1,112 @@
1#include "steps.h" 1#define STEPS_C
2
3#define UPDATECHECKSTOP(a, b, c) if ((a=(MAX((a),(b))))>(c)) return (a);
4
5/* Checkers, estimators and validators ***************************************/
6
7static bool check_centers(Cube cube);
8static bool check_coud_HTM(Cube cube);
9static bool check_coud_URF(Cube cube);
10static bool check_corners_HTM(Cube cube);
11static bool check_corners_URF(Cube cube);
12static bool check_cornershtr(Cube cube);
13static bool check_eofb(Cube cube);
14static bool check_drud(Cube cube);
15static bool check_htr(Cube cube);
16
17static int estimate_eofb_HTM(DfsArg *arg);
18static int estimate_coud_HTM(DfsArg *arg);
19static int estimate_coud_URF(DfsArg *arg);
20static int estimate_corners_HTM(DfsArg *arg);
21static int estimate_cornershtr_HTM(DfsArg *arg);
22static int estimate_corners_URF(DfsArg *arg);
23static int estimate_cornershtr_URF(DfsArg *arg);
24static int estimate_drud_HTM(DfsArg *arg);
25static int estimate_drud_eofb(DfsArg *arg);
26static int estimate_dr_eofb(DfsArg *arg);
27static int estimate_drudfin_drud(DfsArg *arg);
28static int estimate_htr_drud(DfsArg *arg);
29static int estimate_htrfin_htr(DfsArg *arg);
30static int estimate_nxopt31_HTM(DfsArg *arg);
31static int estimate_light_HTM(DfsArg *arg);
32
33static int estimate_nxoptlike(DfsArg *arg, PruneData *pd);
34
35static bool always_valid(Alg *alg);
36static bool validate_singlecw_ending(Alg *alg);
37
38/* Pre-transformation detectors **********************************************/
39
40static int detect_pretrans_eofb(Cube cube, Trans *ret);
41static int detect_pretrans_drud(Cube cube, Trans *ret);
42static int detect_pretrans_void_3axis(Cube cube, Trans *ret);
43
44/* Messages for when cube is not ready ***************************************/
45
46static char check_centers_msg[100] = "cube must be oriented (centers solved)";
47static char check_eo_msg[100] = "EO must be solved on given axis";
48static char check_dr_msg[100] = "DR must be solved on given axis";
49static char check_htr_msg[100] = "HTR must be solved";
50static char check_drany_msg[100] = "DR must be solved on at least one axis";
51
52/* Steps *********************************************************************/
53
54/* Optimal solvers *******************/
55
56Step
57optimal_HTM = {
58 .shortname = "optimal",
59 .name = "Optimal solve (in HTM)",
60
61 .final = true,
62 .is_done = is_solved,
63 .estimate = estimate_nxopt31_HTM,
64 .ready = check_centers,
65 .ready_msg = check_centers_msg,
66 .is_valid = always_valid,
67 .moveset = &moveset_HTM,
68
69 .pre_trans = uf,
70
71 .tables = {&pd_nxopt31_HTM, &pd_corners_HTM},
72 .ntables = 2,
73};
74
75Step
76optimal_light_HTM = {
77 .shortname = "light",
78 .name = "Optimal solve (in HTM), small table (500Mb RAM total)",
79
80 .final = true,
81 .is_done = is_solved,
82 .estimate = estimate_light_HTM,
83 .ready = check_centers,
84 .ready_msg = check_centers_msg,
85 .is_valid = always_valid,
86 .moveset = &moveset_HTM,
87
88 .pre_trans = uf,
89
90 .tables = {&pd_drud_sym16_HTM, &pd_corners_HTM},
91 .ntables = 2,
92};
93
94/* Optimal after EO ******************/
95
96Step
97eofin_eo = {
98 .shortname = "eofin",
99 .name = "Optimal solve after EO without breaking EO (detected)",
100
101 .final = true,
102 .is_done = is_solved,
103 .estimate = estimate_nxopt31_HTM,
104 .ready = check_eofb,
105 .ready_msg = check_eo_msg,
106 .is_valid = always_valid,
107 .moveset = &moveset_eofb,
108
109 .detect = detect_pretrans_eofb,
110
111 .tables = {&pd_nxopt31_HTM, &pd_corners_HTM},
112 .ntables = 2,
113};
114
115Step
116eofbfin_eofb = {
117 .shortname = "eofbfin",
118 .name = "Optimal after EO on F/B without breaking EO",
119
120 .final = true,
121 .is_done = is_solved,
122 .estimate = estimate_nxopt31_HTM,
123 .ready = check_eofb,
124 .ready_msg = check_eo_msg,
125 .is_valid = always_valid,
126 .moveset = &moveset_eofb,
127
128 .pre_trans = uf,
129
130 .tables = {&pd_nxopt31_HTM, &pd_corners_HTM},
131 .ntables = 2,
132};
133
134Step
135eorlfin_eorl = {
136 .shortname = "eorlfin",
137 .name = "Optimal after EO on R/L without breaking EO",
138
139 .final = true,
140 .is_done = is_solved,
141 .estimate = estimate_nxopt31_HTM,
142 .ready = check_eofb,
143 .ready_msg = check_eo_msg,
144 .is_valid = always_valid,
145 .moveset = &moveset_eofb,
146
147 .pre_trans = ur,
148
149 .tables = {&pd_nxopt31_HTM, &pd_corners_HTM},
150 .ntables = 2,
151};
152
153Step
154eoudfin_eoud = {
155 .shortname = "eoudfin",
156 .name = "Optimal after EO on U/D without breaking EO",
157
158 .final = true,
159 .is_done = is_solved,
160 .estimate = estimate_nxopt31_HTM,
161 .ready = check_eofb,
162 .ready_msg = check_eo_msg,
163 .is_valid = always_valid,
164 .moveset = &moveset_eofb,
165
166 .pre_trans = fd,
167
168 .tables = {&pd_nxopt31_HTM, &pd_corners_HTM},
169 .ntables = 2,
170};
171
172/* EO steps **************************/
173Step
174eoany_HTM = {
175 .shortname = "eo",
176 .name = "EO on any axis",
177
178 .final = false,
179 .is_done = check_eofb,
180 .estimate = estimate_eofb_HTM,
181 .ready = check_centers,
182 .ready_msg = check_centers_msg,
183 .is_valid = validate_singlecw_ending,
184 .moveset = &moveset_HTM,
185
186 .detect = detect_pretrans_void_3axis,
187
188 .tables = {&pd_eofb_HTM},
189 .ntables = 1,
190};
191
192Step
193eofb_HTM = {
194 .shortname = "eofb",
195 .name = "EO on F/B",
196
197 .final = false,
198 .is_done = check_eofb,
199 .estimate = estimate_eofb_HTM,
200 .ready = check_centers,
201 .ready_msg = check_centers_msg,
202 .is_valid = validate_singlecw_ending,
203 .moveset = &moveset_HTM,
204
205 .pre_trans = uf,
206
207 .tables = {&pd_eofb_HTM},
208 .ntables = 1,
209};
210
211Step
212eorl_HTM = {
213 .shortname = "eorl",
214 .name = "EO on R/L",
215
216 .final = false,
217 .is_done = check_eofb,
218 .estimate = estimate_eofb_HTM,
219 .ready = check_centers,
220 .ready_msg = check_centers_msg,
221 .is_valid = validate_singlecw_ending,
222 .moveset = &moveset_HTM,
223
224 .pre_trans = ur,
225
226 .tables = {&pd_eofb_HTM},
227 .ntables = 1,
228};
229
230Step
231eoud_HTM = {
232 .shortname = "eoud",
233 .name = "EO on U/D",
234
235 .final = false,
236 .is_done = check_eofb,
237 .estimate = estimate_eofb_HTM,
238 .ready = check_centers,
239 .ready_msg = check_centers_msg,
240 .is_valid = validate_singlecw_ending,
241 .moveset = &moveset_HTM,
242
243 .pre_trans = fd,
244
245 .tables = {&pd_eofb_HTM},
246 .ntables = 1,
247};
248
249/* CO steps **************************/
250Step
251coany_HTM = {
252 .shortname = "co",
253 .name = "CO on any axis",
254
255 .final = false,
256 .is_done = check_coud_HTM,
257 .estimate = estimate_coud_HTM,
258 .ready = NULL,
259 .is_valid = validate_singlecw_ending,
260 .moveset = &moveset_HTM,
261
262 .detect = detect_pretrans_void_3axis,
263
264 .tables = {&pd_coud_HTM},
265 .ntables = 1,
266};
267
268Step
269coud_HTM = {
270 .shortname = "coud",
271 .name = "CO on U/D",
272
273 .final = false,
274 .is_done = check_coud_HTM,
275 .estimate = estimate_coud_HTM,
276 .ready = NULL,
277 .is_valid = validate_singlecw_ending,
278 .moveset = &moveset_HTM,
279
280 .pre_trans = uf,
281
282 .tables = {&pd_coud_HTM},
283 .ntables = 1,
284};
285
286Step
287corl_HTM = {
288 .shortname = "corl",
289 .name = "CO on R/L",
290
291 .final = false,
292 .is_done = check_coud_HTM,
293 .estimate = estimate_coud_HTM,
294 .ready = NULL,
295 .is_valid = validate_singlecw_ending,
296 .moveset = &moveset_HTM,
297
298 .pre_trans = rf,
299
300 .tables = {&pd_coud_HTM},
301 .ntables = 1,
302};
303
304Step
305cofb_HTM = {
306 .shortname = "cofb",
307 .name = "CO on F/B",
308
309 .final = false,
310 .is_done = check_coud_HTM,
311 .estimate = estimate_coud_HTM,
312 .ready = NULL,
313 .is_valid = validate_singlecw_ending,
314 .moveset = &moveset_HTM,
315
316 .pre_trans = fd,
317
318 .tables = {&pd_coud_HTM},
319 .ntables = 1,
320};
321
322Step
323coany_URF = {
324 .shortname = "co-URF",
325 .name = "CO any axis (URF moveset)",
326
327 .final = false,
328 .is_done = check_coud_URF,
329 .estimate = estimate_coud_URF,
330 .ready = NULL,
331 .is_valid = validate_singlecw_ending,
332 .moveset = &moveset_URF,
333
334 .detect = detect_pretrans_void_3axis,
335
336 .tables = {&pd_coud_HTM},
337 .ntables = 1,
338};
339
340Step
341coud_URF = {
342 .shortname = "coud-URF",
343 .name = "CO on U/D (URF moveset)",
344
345 .final = false,
346 .is_done = check_coud_URF,
347 .estimate = estimate_coud_URF,
348 .ready = NULL,
349 .is_valid = validate_singlecw_ending,
350 .moveset = &moveset_URF,
351
352 .pre_trans = uf,
353
354 .tables = {&pd_coud_HTM},
355 .ntables = 1,
356};
357
358Step
359corl_URF = {
360 .shortname = "corl-URF",
361 .name = "CO on R/L (URF moveset)",
362
363 .final = false,
364 .is_done = check_coud_URF,
365 .estimate = estimate_coud_URF,
366 .ready = NULL,
367 .is_valid = validate_singlecw_ending,
368 .moveset = &moveset_URF,
369
370 .pre_trans = rf,
371
372 .tables = {&pd_coud_HTM},
373 .ntables = 1,
374};
375
376Step
377cofb_URF = {
378 .shortname = "cofb-URF",
379 .name = "CO on F/B (URF moveset)",
380
381 .final = false,
382 .is_done = check_coud_URF,
383 .estimate = estimate_coud_URF,
384 .ready = NULL,
385 .is_valid = validate_singlecw_ending,
386 .moveset = &moveset_URF,
387
388 .pre_trans = fd,
389
390 .tables = {&pd_coud_HTM},
391 .ntables = 1,
392};
393
394/* Misc corner steps *****************/
395Step
396cornershtr_HTM = {
397 .shortname = "chtr",
398 .name = "Solve corners to HTR state",
399
400 .final = false,
401 .is_done = check_cornershtr,
402 .estimate = estimate_cornershtr_HTM,
403 .ready = NULL,
404 .is_valid = validate_singlecw_ending,
405 .moveset = &moveset_HTM,
406
407 .pre_trans = uf,
408
409 .tables = {&pd_cornershtr_HTM},
410 .ntables = 1,
411};
412
413Step
414cornershtr_URF = {
415 .shortname = "chtr-URF",
416 .name = "Solve corners to HTR state (URF moveset)",
417
418 .final = false,
419 .is_done = check_cornershtr,
420 .estimate = estimate_cornershtr_URF,
421 .ready = NULL,
422 .is_valid = validate_singlecw_ending,
423 .moveset = &moveset_URF,
424
425 .pre_trans = uf,
426
427 .tables = {&pd_cornershtr_HTM},
428 .ntables = 1,
429};
430
431Step
432corners_HTM = {
433 .shortname = "corners",
434 .name = "Solve corners",
435
436 .final = true,
437 .is_done = check_corners_HTM,
438 .estimate = estimate_corners_HTM,
439 .ready = NULL,
440 .is_valid = always_valid,
441 .moveset = &moveset_HTM,
442
443 .pre_trans = uf,
444
445 .tables = {&pd_corners_HTM},
446 .ntables = 1,
447};
448
449Step
450corners_URF = {
451 .shortname = "corners-URF",
452 .name = "Solve corners (URF moveset)",
453
454 .final = true, /* TODO: check if this works with reorient */
455 .is_done = check_corners_URF,
456 .estimate = estimate_corners_URF,
457 .ready = NULL,
458 .is_valid = always_valid,
459 .moveset = &moveset_URF,
460
461 .pre_trans = uf,
462
463 .tables = {&pd_corners_HTM},
464 .ntables = 1,
465};
466
467/* DR steps **************************/
468Step
469drany_HTM = {
470 .shortname = "dr",
471 .name = "DR on any axis",
472
473 .final = false,
474 .is_done = check_drud,
475 .estimate = estimate_drud_HTM,
476 .ready = check_centers,
477 .ready_msg = check_centers_msg,
478 .is_valid = validate_singlecw_ending,
479 .moveset = &moveset_HTM,
480
481 .detect = detect_pretrans_void_3axis,
482
483 .tables = {&pd_drud_sym16_HTM},
484 .ntables = 1,
485};
486
487Step
488drud_HTM = {
489 .shortname = "drud",
490 .name = "DR on U/D",
491
492 .final = false,
493 .is_done = check_drud,
494 .estimate = estimate_drud_HTM,
495 .ready = check_centers,
496 .ready_msg = check_centers_msg,
497 .is_valid = validate_singlecw_ending,
498 .moveset = &moveset_HTM,
499
500 .pre_trans = uf,
501
502 .tables = {&pd_drud_sym16_HTM},
503 .ntables = 1,
504};
505
506Step
507drrl_HTM = {
508 .shortname = "drrl",
509 .name = "DR on R/L",
510
511 .final = false,
512 .is_done = check_drud,
513 .estimate = estimate_drud_HTM,
514 .ready = check_centers,
515 .ready_msg = check_centers_msg,
516 .is_valid = validate_singlecw_ending,
517 .moveset = &moveset_HTM,
518
519 .pre_trans = rf,
520
521 .tables = {&pd_drud_sym16_HTM},
522 .ntables = 1,
523};
524
525Step
526drfb_HTM = {
527 .shortname = "drfb",
528 .name = "DR on F/B",
529
530 .final = false,
531 .is_done = check_drud,
532 .estimate = estimate_drud_HTM,
533 .ready = check_centers,
534 .ready_msg = check_centers_msg,
535 .is_valid = validate_singlecw_ending,
536 .moveset = &moveset_HTM,
537
538 .pre_trans = fd,
539
540 .tables = {&pd_drud_sym16_HTM},
541 .ntables = 1,
542};
543
544/* DR from EO */
545Step
546dr_eo = {
547 .shortname = "dr-eo",
548 .name = "DR without breaking EO (automatically detected)",
549
550 .final = false,
551 .is_done = check_drud,
552 .estimate = estimate_dr_eofb,
553 .ready = check_eofb,
554 .ready_msg = check_eo_msg,
555 .is_valid = validate_singlecw_ending,
556 .moveset = &moveset_eofb,
557
558 .detect = detect_pretrans_eofb,
559
560 .tables = {&pd_drud_eofb},
561 .ntables = 1,
562};
563
564Step
565dr_eofb = {
566 .shortname = "dr-eofb",
567 .name = "DR on U/D or R/L without breaking EO on F/B",
568
569 .final = false,
570 .is_done = check_drud,
571 .estimate = estimate_dr_eofb,
572 .ready = check_eofb,
573 .ready_msg = check_eo_msg,
574 .is_valid = validate_singlecw_ending,
575 .moveset = &moveset_eofb,
576
577 .pre_trans = uf,
578
579 .tables = {&pd_drud_eofb},
580 .ntables = 1,
581};
582
583Step
584dr_eorl = {
585 .shortname = "dr-eorl",
586 .name = "DR on U/D or F/B without breaking EO on R/L",
587
588 .final = false,
589 .is_done = check_drud,
590 .estimate = estimate_dr_eofb,
591 .ready = check_eofb,
592 .ready_msg = check_eo_msg,
593 .is_valid = validate_singlecw_ending,
594 .moveset = &moveset_eofb,
595
596 .pre_trans = ur,
597
598 .tables = {&pd_drud_eofb},
599 .ntables = 1,
600};
601
602Step
603dr_eoud = {
604 .shortname = "dr-eoud",
605 .name = "DR on R/L or F/B without breaking EO on U/D",
606
607 .final = false,
608 .is_done = check_drud,
609 .estimate = estimate_dr_eofb,
610 .ready = check_eofb,
611 .ready_msg = check_eo_msg,
612 .is_valid = validate_singlecw_ending,
613 .moveset = &moveset_eofb,
614
615 .pre_trans = fd,
616
617 .tables = {&pd_drud_eofb},
618 .ntables = 1,
619};
620
621Step
622drud_eofb = {
623 .shortname = "drud-eofb",
624 .name = "DR on U/D without breaking EO on F/B",
625
626 .final = false,
627 .is_done = check_drud,
628 .estimate = estimate_drud_eofb,
629 .ready = check_eofb,
630 .ready_msg = check_eo_msg,
631 .is_valid = validate_singlecw_ending,
632 .moveset = &moveset_eofb,
633
634 .pre_trans = uf,
635
636 .tables = {&pd_drud_eofb},
637 .ntables = 1,
638};
639
640Step
641drrl_eofb = {
642 .shortname = "drrl-eofb",
643 .name = "DR on R/L without breaking EO on F/B",
644
645 .final = false,
646 .is_done = check_drud,
647 .estimate = estimate_drud_eofb,
648 .ready = check_eofb,
649 .ready_msg = check_eo_msg,
650 .is_valid = validate_singlecw_ending,
651 .moveset = &moveset_eofb,
652
653 .pre_trans = rf,
654
655 .tables = {&pd_drud_eofb},
656 .ntables = 1,
657};
658
659Step
660drud_eorl = {
661 .shortname = "drud-eorl",
662 .name = "DR on U/D without breaking EO on R/L",
663
664 .final = false,
665 .is_done = check_drud,
666 .estimate = estimate_drud_eofb,
667 .ready = check_eofb,
668 .ready_msg = check_eo_msg,
669 .is_valid = validate_singlecw_ending,
670 .moveset = &moveset_eofb,
671
672 .pre_trans = ur,
673
674 .tables = {&pd_drud_eofb},
675 .ntables = 1,
676};
677
678Step
679drfb_eorl = {
680 .shortname = "drfb-eorl",
681 .name = "DR on F/B without breaking EO on R/L",
682
683 .final = false,
684 .is_done = check_drud,
685 .estimate = estimate_drud_eofb,
686 .ready = check_eofb,
687 .ready_msg = check_eo_msg,
688 .is_valid = validate_singlecw_ending,
689 .moveset = &moveset_eofb,
690
691 .pre_trans = fr,
692
693 .tables = {&pd_drud_eofb},
694 .ntables = 1,
695};
696
697Step
698drfb_eoud = {
699 .shortname = "drfb-eoud",
700 .name = "DR on F/B without breaking EO on U/D",
701
702 .final = false,
703 .is_done = check_drud,
704 .estimate = estimate_drud_eofb,
705 .ready = check_eofb,
706 .ready_msg = check_eo_msg,
707 .is_valid = validate_singlecw_ending,
708 .moveset = &moveset_eofb,
709
710 .pre_trans = fd,
711
712 .tables = {&pd_drud_eofb},
713 .ntables = 1,
714};
715
716Step
717drrl_eoud = {
718 .shortname = "drrl-eoud",
719 .name = "DR on R/L without breaking EO on U/D",
720
721 .final = false,
722 .is_done = check_drud,
723 .estimate = estimate_drud_eofb,
724 .ready = check_eofb,
725 .ready_msg = check_eo_msg,
726 .is_valid = validate_singlecw_ending,
727 .moveset = &moveset_eofb,
728
729 .pre_trans = rd,
730
731 .tables = {&pd_drud_eofb},
732 .ntables = 1,
733};
734
735/* DR finish steps */
736Step
737dranyfin_DR = {
738 .shortname = "drfin",
739 .name = "DR finish on any axis without breaking DR",
740
741 .final = true,
742 .is_done = is_solved,
743 .estimate = estimate_drudfin_drud,
744 .ready = check_drud,
745 .ready_msg = check_drany_msg,
746 .is_valid = always_valid,
747 .moveset = &moveset_drud,
748
749 .detect = detect_pretrans_drud,
750
751 .tables = {&pd_drudfin_noE_sym16_drud},
752 .ntables = 1,
753};
754
755Step
756drudfin_drud = {
757 .shortname = "drudfin",
758 .name = "DR finish on U/D without breaking DR",
759
760 .final = true,
761 .is_done = is_solved,
762 .estimate = estimate_drudfin_drud,
763 .ready = check_drud,
764 .ready_msg = check_dr_msg,
765 .is_valid = always_valid,
766 .moveset = &moveset_drud,
767
768 .pre_trans = uf,
769
770 .tables = {&pd_drudfin_noE_sym16_drud},
771 .ntables = 1,
772};
773
774Step
775drrlfin_drrl = {
776 .shortname = "drrlfin",
777 .name = "DR finish on R/L without breaking DR",
778
779 .final = true,
780 .is_done = is_solved,
781 .estimate = estimate_drudfin_drud,
782 .ready = check_drud,
783 .ready_msg = check_dr_msg,
784 .is_valid = always_valid,
785 .moveset = &moveset_drud,
786
787 .pre_trans = rf,
788
789 .tables = {&pd_drudfin_noE_sym16_drud},
790 .ntables = 1,
791};
792
793Step
794drfbfin_drfb = {
795 .shortname = "drfbfin",
796 .name = "DR finish on F/B without breaking DR",
797
798 .final = true,
799 .is_done = is_solved,
800 .estimate = estimate_drudfin_drud,
801 .ready = check_drud,
802 .ready_msg = check_dr_msg,
803 .is_valid = always_valid,
804 .moveset = &moveset_drud,
805
806 .pre_trans = fd,
807
808 .tables = {&pd_drudfin_noE_sym16_drud},
809 .ntables = 1,
810};
811
812/* HTR from DR */
813Step
814htr_any = {
815 .shortname = "htr",
816 .name = "HTR from DR",
817
818 .final = false,
819 .is_done = check_htr,
820 .estimate = estimate_htr_drud,
821 .ready = check_drud,
822 .ready_msg = check_drany_msg,
823 .is_valid = validate_singlecw_ending,
824 .moveset = &moveset_drud,
825 2
826 .detect = detect_pretrans_drud, 3#include "steps.h"
827
828 .tables = {&pd_htr_drud},
829 .ntables = 1,
830};
831
832Step
833htr_drud = {
834 .shortname = "htr-drud",
835 .name = "HTR from DR on U/D",
836
837 .final = false,
838 .is_done = check_htr,
839 .estimate = estimate_htr_drud,
840 .ready = check_drud,
841 .ready_msg = check_dr_msg,
842 .is_valid = validate_singlecw_ending,
843 .moveset = &moveset_drud,
844
845 .pre_trans = uf,
846
847 .tables = {&pd_htr_drud},
848 .ntables = 1,
849};
850
851Step
852htr_drrl = {
853 .shortname = "htr-drrl",
854 .name = "HTR from DR on R/L",
855
856 .final = false,
857 .is_done = check_htr,
858 .estimate = estimate_htr_drud,
859 .ready = check_drud,
860 .ready_msg = check_dr_msg,
861 .is_valid = validate_singlecw_ending,
862 .moveset = &moveset_drud,
863
864 .pre_trans = rf,
865
866 .tables = {&pd_htr_drud},
867 .ntables = 1,
868};
869
870Step
871htr_drfb = {
872 .shortname = "htr-drfb",
873 .name = "HTR from DR on F/B",
874
875 .final = false,
876 .is_done = check_htr,
877 .estimate = estimate_htr_drud,
878 .ready = check_drud,
879 .ready_msg = check_dr_msg,
880 .is_valid = validate_singlecw_ending,
881 .moveset = &moveset_drud,
882
883 .pre_trans = fd,
884
885 .tables = {&pd_htr_drud},
886 .ntables = 1,
887};
888
889/* HTR finish */
890Step
891htrfin_htr = {
892 .shortname = "htrfin",
893 .name = "HTR finish without breaking HTR",
894
895 .final = true,
896 .is_done = is_solved,
897 .estimate = estimate_htrfin_htr,
898 .ready = check_htr,
899 .ready_msg = check_htr_msg,
900 .is_valid = always_valid,
901 .moveset = &moveset_htr,
902
903 .pre_trans = uf,
904
905 .tables = {&pd_htrfin_htr},
906 .ntables = 1,
907};
908
909Step *steps[] = {
910 &optimal_HTM, /* first is default */
911 &optimal_light_HTM,
912
913 &eofin_eo,
914 &eofbfin_eofb,
915 &eorlfin_eorl,
916 &eoudfin_eoud,
917
918 &eoany_HTM,
919 &eofb_HTM,
920 &eorl_HTM,
921 &eoud_HTM,
922
923 &coany_HTM,
924 &coud_HTM,
925 &corl_HTM,
926 &cofb_HTM,
927
928 &coany_URF,
929 &coud_URF,
930 &corl_URF,
931 &cofb_URF,
932
933 &drany_HTM,
934 &drud_HTM,
935 &drrl_HTM,
936 &drfb_HTM,
937
938 &dr_eo,
939 &dr_eofb,
940 &dr_eorl,
941 &dr_eoud,
942 &drud_eofb,
943 &drrl_eofb,
944 &drud_eorl,
945 &drfb_eorl,
946 &drfb_eoud,
947 &drrl_eoud,
948
949 &dranyfin_DR,
950 &drudfin_drud,
951 &drrlfin_drrl,
952 &drfbfin_drfb,
953
954 &htr_any,
955 &htr_drud,
956 &htr_drrl,
957 &htr_drfb,
958
959 &htrfin_htr,
960
961 &cornershtr_HTM,
962 &cornershtr_URF,
963 &corners_HTM,
964 &corners_URF,
965
966 NULL
967};
968
969/* Checkers, estimators and validators ***************************************/
970
971static bool
972check_centers(Cube cube)
973{
974 return cube.cpos == 0;
975}
976
977static bool
978check_coud_HTM(Cube cube)
979{
980 return cube.coud == 0;
981}
982
983static bool
984check_coud_URF(Cube cube)
985{
986 Cube c2, c3;
987
988 c2 = apply_move(z, cube);
989 c3 = apply_move(x, cube);
990 4
991 return cube.coud == 0 || c2.coud == 0 || c3.coud == 0; 5/* TODO: change all checkers to use coordinates! */
992}
993 6
994static bool 7bool
995check_corners_URF(Cube cube) 8check_centers(Cube *cube)
996{ 9{
997 Cube c; 10 int i;
998 Trans i;
999 11
1000 for (i = 0; i < NROTATIONS; i++) { 12 for (i = 0; i < 6; i++)
1001 c = apply_alg(rotation_alg(i), cube); 13 if (cube->xp[i] != i)
1002 if (c.cp && c.coud) 14 return false;
1003 return true;
1004 }
1005 15
1006 return false; 16 return true;
1007} 17}
1008 18
1009static bool 19bool
1010check_corners_HTM(Cube cube) 20check_coud_HTM(Cube *cube)
1011{ 21{
1012 return cube.cp == 0 && cube.coud == 0; 22 int i;
1013}
1014 23
1015static bool 24 for (i = 0; i < 8; i++)
1016check_cornershtr(Cube cube) 25 if (cube->co[i] != 0)
1017{ 26 return false;
1018 return coord_cornershtr.index(cube) == 0;
1019}
1020 27
1021static bool 28 return true;
1022check_eofb(Cube cube)
1023{
1024 return cube.eofb == 0;
1025} 29}
1026 30
1027static bool 31bool
1028check_drud(Cube cube) 32check_coud_URF(Cube *cube)
1029{ 33{
1030 return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0; 34 Cube c2, c3;
1031}
1032 35
1033static bool 36 copy_cube(cube, &c2);
1034check_htr(Cube cube) 37 copy_cube(cube, &c3);
1035{
1036 return check_drud(cube) && coord_htr_drud.index(cube) == 0;
1037}
1038 38
1039static int 39 apply_move(z, &c2);
1040estimate_eofb_HTM(DfsArg *arg) 40 apply_move(x, &c3);
1041{
1042 return ptableval(&pd_eofb_HTM, arg->cube);
1043}
1044 41
1045static int 42 return check_coud_HTM(cube) ||
1046estimate_coud_HTM(DfsArg *arg) 43 check_coud_HTM(&c2) ||
1047{ 44 check_coud_HTM(&c3);
1048 return ptableval(&pd_coud_HTM, arg->cube);
1049} 45}
1050 46
1051static int 47bool
1052estimate_coud_URF(DfsArg *arg) 48check_cp_HTM(Cube *cube)
1053{ 49{
1054 /* TODO: I can improve this by checking first the orientation of 50 int i;
1055 * the corner in DBL and use that as a reference */
1056
1057 Cube c;
1058
1059 c = arg->cube;
1060
1061 int ud = estimate_coud_HTM(arg);
1062 arg->cube = apply_move(z, c);
1063 int rl = estimate_coud_HTM(arg);
1064 arg->cube = apply_move(x, c);
1065 int fb = estimate_coud_HTM(arg);
1066
1067 arg->cube = c;
1068 51
1069 return MIN(ud, MIN(rl, fb)); 52 for (i = 0; i < 8; i++)
1070} 53 if (cube->cp[i] != i)
54 return false;
1071 55
1072static int 56 return true;
1073estimate_corners_HTM(DfsArg *arg)
1074{
1075 return ptableval(&pd_corners_HTM, arg->cube);
1076}
1077
1078static int
1079estimate_cornershtr_HTM(DfsArg *arg)
1080{
1081 return ptableval(&pd_cornershtr_HTM, arg->cube);
1082} 57}
1083 58
1084static int 59bool
1085estimate_cornershtr_URF(DfsArg *arg) 60check_corners_HTM(Cube *cube)
1086{ 61{
1087 /* TODO: I can improve this by checking first the corner in DBL 62 return check_coud_HTM(cube) && check_cp_HTM(cube);
1088 * and use that as a reference */
1089
1090 int ret;
1091 Cube c;
1092 Trans i;
1093
1094 c = arg->cube;
1095 ret = 15;
1096
1097 for (i = 0; i < NROTATIONS; i++) {
1098 arg->cube = apply_alg(rotation_alg(i), c);
1099 ret = MIN(ret, estimate_cornershtr_HTM(arg));
1100 }
1101
1102 arg->cube = c;
1103
1104 return ret;
1105} 63}
1106 64
1107static int 65bool
1108estimate_corners_URF(DfsArg *arg) 66check_corners_URF(Cube *cube)
1109{ 67{
1110 /* TODO: I can improve this by checking first the corner in DBL
1111 * and use that as a reference */
1112
1113 int ret;
1114 Cube c; 68 Cube c;
1115 Trans i; 69 Trans i;
1116 70
1117 c = arg->cube;
1118 ret = 15;
1119
1120 for (i = 0; i < NROTATIONS; i++) { 71 for (i = 0; i < NROTATIONS; i++) {
1121 arg->cube = apply_alg(rotation_alg(i), c); 72 copy_cube(cube, &c);
1122 ret = MIN(ret, estimate_corners_HTM(arg)); 73 apply_alg(rotation_alg(i), &c);
74 if (check_corners_HTM(&c))
75 return true;
1123 } 76 }
1124 77
1125 arg->cube = c; 78 return false;
1126
1127 return ret;
1128}
1129
1130static int
1131estimate_drud_HTM(DfsArg *arg)
1132{
1133 return ptableval(&pd_drud_sym16_HTM, arg->cube);
1134}
1135
1136static int
1137estimate_drud_eofb(DfsArg *arg)
1138{
1139 return ptableval(&pd_drud_eofb, arg->cube);
1140}
1141
1142static int
1143estimate_dr_eofb(DfsArg *arg)
1144{
1145 int r1, r2;
1146
1147 r1 = ptableval(&pd_drud_eofb, arg->cube);
1148 r2 = ptableval(&pd_drud_eofb, apply_trans(rf, arg->cube));
1149
1150 return MIN(r1, r2);
1151}
1152
1153static int
1154estimate_drudfin_drud(DfsArg *arg)
1155{
1156 int val = ptableval(&pd_drudfin_noE_sym16_drud, arg->cube);
1157
1158 if (val != 0)
1159 return val;
1160
1161 return arg->cube.epose % 24 == 0 ? 0 : 1;
1162}
1163
1164static int
1165estimate_htr_drud(DfsArg *arg)
1166{
1167 return ptableval(&pd_htr_drud, arg->cube);
1168}
1169
1170static int
1171estimate_htrfin_htr(DfsArg *arg)
1172{
1173 return ptableval(&pd_htrfin_htr, arg->cube);
1174} 79}
1175 80
1176static int 81bool
1177estimate_nxopt31_HTM(DfsArg *arg) 82check_cornershtr(Cube *cube)
1178{ 83{
1179 return estimate_nxoptlike(arg, &pd_nxopt31_HTM); 84 /* TODO (use coord) */
85 return true;
1180} 86}
1181 87
1182/* TODO: also use generic procedure for this */ 88bool
1183static int 89check_eofb(Cube *cube)
1184estimate_light_HTM(DfsArg *arg)
1185{ 90{
1186 int target, ret; 91 /* TODO (use coord) */
1187 Cube aux; 92 return true;
1188
1189 static const uint64_t udmask = (1<<U) | (1<<U2) | (1<<U3) |
1190 (1<<D) | (1<<D2) | (1<<D3);
1191 static const uint64_t rlmask = (1<<R) | (1<<R2) | (1<<R3) |
1192 (1<<L) | (1<<L2) | (1<<L3);
1193 static const uint64_t fbmask = (1<<F) | (1<<F2) | (1<<F3) |
1194 (1<<B) | (1<<B2) | (1<<B3);
1195 static const uint64_t htmask = (1<<U2) | (1<<D2) |
1196 (1<<R2) | (1<<L2) |
1197 (1<<F2) | (1<<B2);
1198
1199 ret = -1;
1200 target = arg->d - arg->current_alg->len;
1201 arg->inverse = (Cube){0};
1202 arg->badmovesinv = 0;
1203 arg->badmoves = 0;
1204
1205 /* Corners */
1206 arg->ed->corners = ptableval(&pd_corners_HTM, arg->cube);
1207 UPDATECHECKSTOP(ret, arg->ed->corners, target);
1208
1209 /* Normal probing */
1210 arg->ed->normal_ud = ptableval(&pd_drud_sym16_HTM, arg->cube);
1211 UPDATECHECKSTOP(ret, arg->ed->normal_ud, target);
1212 aux = apply_trans(fd, arg->cube);
1213 arg->ed->normal_fb = ptableval(&pd_drud_sym16_HTM, aux);
1214 UPDATECHECKSTOP(ret, arg->ed->normal_fb, target);
1215 aux = apply_trans(rf, arg->cube);
1216 arg->ed->normal_rl = ptableval(&pd_drud_sym16_HTM, aux);
1217 UPDATECHECKSTOP(ret, arg->ed->normal_rl, target);
1218
1219 /* If ret == 0, it's solved (corners + triple slice solved) */
1220 if (ret == 0)
1221 return is_solved(arg->cube) ? 0 : 1;
1222
1223 /* Michel de Bondt's trick*/
1224 if (arg->ed->normal_ud == arg->ed->normal_fb &&
1225 arg->ed->normal_fb == arg->ed->normal_rl) {
1226 UPDATECHECKSTOP(ret, arg->ed->normal_ud + 1, target);
1227 }
1228
1229 /* Inverse probing */
1230 if (!((1<<arg->last1) & htmask)) {
1231 aux = arg->inverse = inverse_cube(arg->cube);
1232 if (!((1<<arg->last1) & udmask) || (arg->ed->inverse_ud==-1)) {
1233 arg->ed->inverse_ud =
1234 ptableval(&pd_drud_sym16_HTM, aux);
1235 }
1236 UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target);
1237 if (!((1<<arg->last1) & fbmask) || (arg->ed->inverse_fb==-1)) {
1238 aux = apply_trans(fd, arg->inverse);
1239 arg->ed->inverse_fb =
1240 ptableval(&pd_drud_sym16_HTM, aux);
1241 }
1242 UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target);
1243 if (!((1<<arg->last1) & rlmask) || (arg->ed->inverse_rl==-1)) {
1244 aux = apply_trans(rf, arg->inverse);
1245 arg->ed->inverse_rl =
1246 ptableval(&pd_drud_sym16_HTM, aux);
1247 }
1248 UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target);
1249 } else {
1250 UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target);
1251 UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target);
1252 UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target);
1253 }
1254
1255 /* Michel de Bondt's trick*/
1256 if (arg->ed->inverse_ud == arg->ed->inverse_fb &&
1257 arg->ed->inverse_fb == arg->ed->inverse_rl) {
1258 UPDATECHECKSTOP(ret, arg->ed->inverse_ud + 1, target);
1259 }
1260
1261 /* nxopt trick + half turn trick */
1262 if (arg->ed->normal_ud == target)
1263 arg->badmovesinv |= udmask | htmask;
1264 if (arg->ed->normal_fb == target)
1265 arg->badmovesinv |= fbmask | htmask;
1266 if (arg->ed->normal_rl == target)
1267 arg->badmovesinv |= rlmask | htmask;
1268
1269 if (arg->ed->inverse_ud == target)
1270 arg->badmoves |= udmask | htmask;
1271 if (arg->ed->inverse_fb == target)
1272 arg->badmoves |= fbmask | htmask;
1273 if (arg->ed->inverse_rl == target)
1274 arg->badmoves |= rlmask | htmask;
1275
1276 return arg->ed->oldret = ret;
1277} 93}
1278 94
1279static int 95bool
1280estimate_nxoptlike(DfsArg *arg, PruneData *pd) 96check_drud(Cube *cube)
1281{ 97{
1282 int target, ret; 98 /* TODO (use coord) */
1283 Cube aux; 99 return true;
1284
1285 static const uint64_t udmask = (1<<U) | (1<<U2) | (1<<U3) |
1286 (1<<D) | (1<<D2) | (1<<D3);
1287 static const uint64_t rlmask = (1<<R) | (1<<R2) | (1<<R3) |
1288 (1<<L) | (1<<L2) | (1<<L3);
1289 static const uint64_t fbmask = (1<<F) | (1<<F2) | (1<<F3) |
1290 (1<<B) | (1<<B2) | (1<<B3);
1291
1292 ret = -1;
1293 target = arg->d - arg->current_alg->len;
1294 arg->inverse = (Cube){0};
1295 arg->badmovesinv = 0;
1296 arg->badmoves = 0;
1297
1298 /* Corners */
1299 arg->ed->corners = ptableval(&pd_corners_HTM, arg->cube);
1300 UPDATECHECKSTOP(ret, arg->ed->corners, target);
1301
1302 /* Normal probing */
1303 arg->ed->normal_ud = ptableval(pd, arg->cube);
1304 UPDATECHECKSTOP(ret, arg->ed->normal_ud, target);
1305 aux = apply_trans(fd, arg->cube);
1306 arg->ed->normal_fb = ptableval(pd, aux);
1307 UPDATECHECKSTOP(ret, arg->ed->normal_fb, target);
1308 aux = apply_trans(rf, arg->cube);
1309 arg->ed->normal_rl = ptableval(pd, aux);
1310 UPDATECHECKSTOP(ret, arg->ed->normal_rl, target);
1311
1312 if (ret == 0)
1313 return arg->step->is_done(arg->cube) ? 0 : 1;
1314
1315 /* Michel de Bondt's trick*/
1316 if (arg->ed->normal_ud == arg->ed->normal_fb &&
1317 arg->ed->normal_fb == arg->ed->normal_rl) {
1318 UPDATECHECKSTOP(ret, arg->ed->normal_ud + 1, target);
1319 }
1320
1321 /* Inverse probing */
1322 aux = arg->inverse = inverse_cube(arg->cube);
1323 if (!((1<<arg->last1) & udmask) || (arg->ed->inverse_ud == -1)) {
1324 arg->ed->inverse_ud = ptableval(pd, aux);
1325 }
1326 UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target);
1327 if (!((1<<arg->last1) & fbmask) || (arg->ed->inverse_fb == -1)) {
1328 aux = apply_trans(fd, arg->inverse);
1329 arg->ed->inverse_fb = ptableval(pd, aux);
1330 }
1331 UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target);
1332 if (!((1<<arg->last1) & rlmask) || (arg->ed->inverse_rl == -1)) {
1333 aux = apply_trans(rf, arg->inverse);
1334 arg->ed->inverse_rl = ptableval(pd, aux);
1335 }
1336 UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target);
1337
1338 /* Michel de Bondt's trick*/
1339 if (arg->ed->inverse_ud == arg->ed->inverse_fb &&
1340 arg->ed->inverse_fb == arg->ed->inverse_rl) {
1341 UPDATECHECKSTOP(ret, arg->ed->inverse_ud + 1, target);
1342 }
1343
1344 /* nxopt trick */
1345 if (arg->ed->normal_ud == target)
1346 arg->badmovesinv |= udmask;
1347 if (arg->ed->normal_fb == target)
1348 arg->badmovesinv |= fbmask;
1349 if (arg->ed->normal_rl == target)
1350 arg->badmovesinv |= rlmask;
1351
1352 if (arg->ed->inverse_ud == target)
1353 arg->badmoves |= udmask;
1354 if (arg->ed->inverse_fb == target)
1355 arg->badmoves |= fbmask;
1356 if (arg->ed->inverse_rl == target)
1357 arg->badmoves |= rlmask;
1358
1359 return arg->ed->oldret = ret;
1360} 100}
1361 101
1362 102bool
1363static bool 103check_htr(Cube *cube)
1364always_valid(Alg *alg)
1365{ 104{
105 /* TODO (check_drud(cube) and coord_htr_drud == 0) */
1366 return true; 106 return true;
1367} 107}
1368 108
1369static bool 109bool
1370validate_singlecw_ending(Alg *alg) 110validate_singlecw_ending(Alg *alg)
1371{ 111{
1372 int i; 112 int i;
@@ -1389,93 +129,93 @@ validate_singlecw_ending(Alg *alg)
1389 return nor && inv; 129 return nor && inv;
1390} 130}
1391 131
1392/* Pre-transformation detectors **********************************************/ 132/* Public functions **********************************************************/
1393 133
1394static int 134void
1395detect_pretrans_eofb(Cube cube, Trans *ret) 135compute_ind(StepAlt *a, Cube *cube, Movable *ind)
1396{ 136{
1397 int i, n; 137 int i;
1398 static Trans tt[3] = {uf, ur, fd}; 138 Cube mvd;
139 Trans t, tt;
1399 140
1400 for (i = 0, n = 0; i < 3; i++) 141 for (i = 0; i < a->n_coord; i++) {
1401 if (check_eofb(apply_trans(tt[i], cube))) 142 t = a->coord_trans[i];
1402 ret[n++] = tt[i]; 143 copy_cube(cube, &mvd);
144 apply_trans(t, &mvd);
1403 145
1404 return n; 146 ind[i].val = index_coord(a->coord[i], &mvd, &tt);
147 ind[i].t = transform_trans(tt, t);
148 }
1405} 149}
1406 150
1407static int 151int
1408detect_pretrans_drud(Cube cube, Trans *ret) 152estimate_stepalt(StepAlt *a, Movable *ind, int goal)
1409{ 153{
1410 int i, n; 154 int i, ret, est[a->n_coord];
1411 static Trans tt[3] = {uf, fr, rd};
1412 155
1413 for (i = 0, n = 0; i < 3; i++) 156 for (i = 0; i < a->n_coord; i++) {
1414 if (check_drud(apply_trans(tt[i], cube))) 157 est[i] = ptableval(a->pd[i], ind[i].val);
1415 ret[n++] = tt[i]; 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*/
1416 167
1417 return n; 168 if (est[i] > goal)
1418} 169 return est[i];
170 }
1419 171
1420static int 172 for (i = 0; i < a->n_dbtrick; i++)
1421detect_pretrans_void_3axis(Cube cube, Trans *ret) 173 if (est[a->dbtrick[i][0]] > 0 &&
1422{ 174 est[a->dbtrick[i][0]] == est[a->dbtrick[i][1]] &&
1423 ret[0] = uf; 175 est[a->dbtrick[i][0]] == est[a->dbtrick[i][2]])
1424 ret[1] = fr; 176 est[a->dbtrick[i][0]] += 1;
1425 ret[2] = rd;
1426 177
1427 return 3; 178 for (i = 0, ret = -1; i < a->n_coord; i++)
1428} 179 ret = MAX(ret, est[i]);
1429 180
1430/* Public functions **********************************************************/ 181/*
182TODO: remove this debug code
183printf("Final estimate: %d\n", ret);
184*/
1431 185
1432void 186 return ret;
1433copy_estimatedata(EstimateData *src, EstimateData *dst)
1434{
1435 dst->corners = src->corners;
1436 dst->normal_ud = src->normal_ud;
1437 dst->normal_fb = src->normal_fb;
1438 dst->normal_rl = src->normal_rl;
1439 dst->inverse_ud = src->inverse_ud;
1440 dst->inverse_fb = src->inverse_fb;
1441 dst->inverse_rl = src->inverse_rl;
1442 dst->oldret = src->oldret;
1443} 187}
1444 188
1445void 189void
1446invert_estimatedata(EstimateData *ed) 190prepare_step(Step *step, SolveOptions *opts)
1447{ 191{
1448 swap(&(ed->normal_ud), &(ed->inverse_ud)); 192 int i, j;
1449 swap(&(ed->normal_fb), &(ed->inverse_fb)); 193 PDGenData pdg;
1450 swap(&(ed->normal_rl), &(ed->inverse_rl)); 194 StepAlt *a;
1451}
1452 195
1453void 196 for (i = 0; step->alt[i] != NULL; i++) {
1454reset_estimatedata(EstimateData *ed) 197 a = step->alt[i];
1455{ 198 init_moveset(a->moveset);
1456 ed->corners = -1; 199 pdg.moveset = a->moveset;
1457 ed->normal_ud = -1; 200 for (j = 0; j < a->n_coord; j++) {
1458 ed->normal_fb = -1; 201 gen_coord(a->coord[j]);
1459 ed->normal_rl = -1;
1460 ed->inverse_ud = -1;
1461 ed->inverse_fb = -1;
1462 ed->inverse_rl = -1;
1463 ed->oldret = -1;
1464}
1465 202
1466void 203 pdg.coord = a->coord[j];
1467prepare_step(Step *step, SolveOptions *opts) 204 pdg.compact = a->compact_pd[j];
1468{ 205 pdg.pd = NULL;
1469 int i;
1470 206
1471 if (step->final && opts->can_niss) { 207 a->pd[j] = genptable(&pdg, opts->nthreads);
1472 opts->can_niss = false; 208
1473 fprintf(stderr, "Step is final, NISS not used (-n ignored)\n"); 209 if (a->compact_pd[j]) {
1474 } 210 gen_coord(a->fallback_coord[j]);
1475 211
1476 for (i = 0; i < step->ntables; i++) { 212 pdg.coord = a->fallback_coord[j];
1477 genptable(step->tables[i], opts->nthreads); 213 pdg.compact = false;
1478 if (step->tables[i]->compact) 214 pdg.pd = NULL;
1479 genptable(step->tables[i]->fallback, opts->nthreads); 215
216 a->fallback_pd[j] =
217 genptable(&pdg, opts->nthreads);
218 }
219 }
1480 } 220 }
1481} 221}

Generated with cgit - Back to sebastiano.tronto.net