aboutsummaryrefslogtreecommitdiff
path: root/src/steps.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/steps.c1490
1 files changed, 1397 insertions, 93 deletions
diff --git a/src/steps.c b/src/steps.c
index cdba763..3189811 100644
--- a/src/steps.c
+++ b/src/steps.c
@@ -1,117 +1,1376 @@
1#define STEPS_C
2
3#include "steps.h" 1#include "steps.h"
4 2
5/* TODO: change all checkers to use coordinates! */ 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
826 .detect = detect_pretrans_drud,
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",
6 836
7bool 837 .final = false,
8check_centers(Cube *cube) 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)
9{ 973{
10 int i; 974 return cube.cpos == 0;
975}
11 976
12 for (i = 0; i < 6; i++) 977static bool
13 if (cube->xp[i] != i) 978check_coud_HTM(Cube cube)
14 return false; 979{
980 return cube.coud == 0;
981}
15 982
16 return true; 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
991 return cube.coud == 0 || c2.coud == 0 || c3.coud == 0;
17} 992}
18 993
19bool 994static bool
20check_coud_HTM(Cube *cube) 995check_corners_URF(Cube cube)
21{ 996{
22 int i; 997 Cube c;
998 Trans i;
23 999
24 for (i = 0; i < 8; i++) 1000 for (i = 0; i < NROTATIONS; i++) {
25 if (cube->co[i] != 0) 1001 c = apply_alg(rotation_alg(i), cube);
26 return false; 1002 if (c.cp && c.coud)
1003 return true;
1004 }
27 1005
28 return true; 1006 return false;
29} 1007}
30 1008
31bool 1009static bool
32check_coud_URF(Cube *cube) 1010check_corners_HTM(Cube cube)
33{ 1011{
34 Cube c2, c3; 1012 return cube.cp == 0 && cube.coud == 0;
1013}
35 1014
36 copy_cube(cube, &c2); 1015static bool
37 copy_cube(cube, &c3); 1016check_cornershtr(Cube cube)
1017{
1018 return coord_cornershtr.index(cube) == 0;
1019}
38 1020
39 apply_move(z, &c2); 1021static bool
40 apply_move(x, &c3); 1022check_eofb(Cube cube)
1023{
1024 return cube.eofb == 0;
1025}
41 1026
42 return check_coud_HTM(cube) || 1027static bool
43 check_coud_HTM(&c2) || 1028check_drud(Cube cube)
44 check_coud_HTM(&c3); 1029{
1030 return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
45} 1031}
46 1032
47bool 1033static bool
48check_cp_HTM(Cube *cube) 1034check_htr(Cube cube)
49{ 1035{
50 int i; 1036 return check_drud(cube) && coord_htr_drud.index(cube) == 0;
1037}
1038
1039static int
1040estimate_eofb_HTM(DfsArg *arg)
1041{
1042 return ptableval(&pd_eofb_HTM, arg->cube);
1043}
1044
1045static int
1046estimate_coud_HTM(DfsArg *arg)
1047{
1048 return ptableval(&pd_coud_HTM, arg->cube);
1049}
51 1050
52 for (i = 0; i < 8; i++) 1051static int
53 if (cube->cp[i] != i) 1052estimate_coud_URF(DfsArg *arg)
54 return false; 1053{
1054 /* TODO: I can improve this by checking first the orientation of
1055 * the corner in DBL and use that as a reference */
55 1056
56 return true; 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
1069 return MIN(ud, MIN(rl, fb));
57} 1070}
58 1071
59bool 1072static int
60check_corners_HTM(Cube *cube) 1073estimate_corners_HTM(DfsArg *arg)
61{ 1074{
62 return check_coud_HTM(cube) && check_cp_HTM(cube); 1075 return ptableval(&pd_corners_HTM, arg->cube);
63} 1076}
64 1077
65bool 1078static int
66check_corners_URF(Cube *cube) 1079estimate_cornershtr_HTM(DfsArg *arg)
67{ 1080{
1081 return ptableval(&pd_cornershtr_HTM, arg->cube);
1082}
1083
1084static int
1085estimate_cornershtr_URF(DfsArg *arg)
1086{
1087 /* TODO: I can improve this by checking first the corner in DBL
1088 * and use that as a reference */
1089
1090 int ret;
68 Cube c; 1091 Cube c;
69 Trans i; 1092 Trans i;
70 1093
1094 c = arg->cube;
1095 ret = 15;
1096
71 for (i = 0; i < NROTATIONS; i++) { 1097 for (i = 0; i < NROTATIONS; i++) {
72 copy_cube(cube, &c); 1098 arg->cube = apply_alg(rotation_alg(i), c);
73 apply_alg(rotation_alg(i), &c); 1099 ret = MIN(ret, estimate_cornershtr_HTM(arg));
74 if (check_corners_HTM(&c))
75 return true;
76 } 1100 }
77 1101
78 return false; 1102 arg->cube = c;
1103
1104 return ret;
79} 1105}
80 1106
81bool 1107static int
82check_cornershtr(Cube *cube) 1108estimate_corners_URF(DfsArg *arg)
83{ 1109{
84 /* TODO (use coord) */ 1110 /* TODO: I can improve this by checking first the corner in DBL
85 return true; 1111 * and use that as a reference */
1112
1113 int ret;
1114 Cube c;
1115 Trans i;
1116
1117 c = arg->cube;
1118 ret = 15;
1119
1120 for (i = 0; i < NROTATIONS; i++) {
1121 arg->cube = apply_alg(rotation_alg(i), c);
1122 ret = MIN(ret, estimate_corners_HTM(arg));
1123 }
1124
1125 arg->cube = c;
1126
1127 return ret;
86} 1128}
87 1129
88bool 1130static int
89check_eofb(Cube *cube) 1131estimate_drud_HTM(DfsArg *arg)
90{ 1132{
91 /* TODO (use coord) */ 1133 return ptableval(&pd_drud_sym16_HTM, arg->cube);
92 return true;
93} 1134}
94 1135
95bool 1136static int
96check_drud(Cube *cube) 1137estimate_drud_eofb(DfsArg *arg)
97{ 1138{
98 /* TODO (use coord) */ 1139 return ptableval(&pd_drud_eofb, arg->cube);
99 return true;
100} 1140}
101 1141
102bool 1142static int
103check_htr(Cube *cube) 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}
1175
1176static int
1177estimate_nxopt31_HTM(DfsArg *arg)
1178{
1179 return estimate_nxoptlike(arg, &pd_nxopt31_HTM);
1180}
1181
1182/* TODO: also use generic procedure for this */
1183static int
1184estimate_light_HTM(DfsArg *arg)
1185{
1186 int target, ret;
1187 Cube aux;
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}
1278
1279static int
1280estimate_nxoptlike(DfsArg *arg, PruneData *pd)
1281{
1282 int target, ret;
1283 Cube aux;
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}
1361
1362
1363static bool
1364always_valid(Alg *alg)
104{ 1365{
105 /* TODO (check_drud(cube) and coord_htr_drud == 0) */
106 return true; 1366 return true;
107} 1367}
108 1368
109Alg * 1369static bool
110validate_singlecw_ending(Alg *alg) 1370validate_singlecw_ending(Alg *alg)
111{ 1371{
112 int i; 1372 int i;
113 bool nor, inv; 1373 bool nor, inv;
114 Alg *ret;
115 Move l2 = NULLMOVE, l1 = NULLMOVE, l2i = NULLMOVE, l1i = NULLMOVE; 1374 Move l2 = NULLMOVE, l1 = NULLMOVE, l2i = NULLMOVE, l1i = NULLMOVE;
116 1375
117 for (i = 0; i < alg->len; i++) { 1376 for (i = 0; i < alg->len; i++) {
@@ -127,51 +1386,96 @@ validate_singlecw_ending(Alg *alg)
127 nor = l1 ==base_move(l1) && (!commute(l1, l2) ||l2 ==base_move(l2)); 1386 nor = l1 ==base_move(l1) && (!commute(l1, l2) ||l2 ==base_move(l2));
128 inv = l1i==base_move(l1i) && (!commute(l1i,l2i)||l2i==base_move(l2i)); 1387 inv = l1i==base_move(l1i) && (!commute(l1i,l2i)||l2i==base_move(l2i));
129 1388
130 if (nor && inv) { 1389 return nor && inv;
131 ret = new_alg(""); 1390}
132 copy_alg(alg, ret);
133 } else {
134 ret = NULL;
135 }
136 1391
137 return ret; 1392/* Pre-transformation detectors **********************************************/
1393
1394static int
1395detect_pretrans_eofb(Cube cube, Trans *ret)
1396{
1397 int i, n;
1398 static Trans tt[3] = {uf, ur, fd};
1399
1400 for (i = 0, n = 0; i < 3; i++)
1401 if (check_eofb(apply_trans(tt[i], cube)))
1402 ret[n++] = tt[i];
1403
1404 return n;
1405}
1406
1407static int
1408detect_pretrans_drud(Cube cube, Trans *ret)
1409{
1410 int i, n;
1411 static Trans tt[3] = {uf, fr, rd};
1412
1413 for (i = 0, n = 0; i < 3; i++)
1414 if (check_drud(apply_trans(tt[i], cube)))
1415 ret[n++] = tt[i];
1416
1417 return n;
1418}
1419
1420static int
1421detect_pretrans_void_3axis(Cube cube, Trans *ret)
1422{
1423 ret[0] = uf;
1424 ret[1] = fr;
1425 ret[2] = rd;
1426
1427 return 3;
138} 1428}
139 1429
140/* Public functions **********************************************************/ 1430/* Public functions **********************************************************/
141 1431
142/*
143void 1432void
144compute_ind(Step *s, Cube *cube, Movable *ind) 1433copy_estimatedata(EstimateData *src, EstimateData *dst)
145{ 1434{
146 int i; 1435 dst->corners = src->corners;
147 Cube mvd; 1436 dst->normal_ud = src->normal_ud;
148 Trans t, tt; 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}
149 1444
150 for (i = 0; i < s->n_coord; i++) { 1445void
151 t = s->coord_trans[i]; 1446invert_estimatedata(EstimateData *ed)
152 copy_cube(cube, &mvd); 1447{
153 apply_trans(t, &mvd); 1448 swap(&(ed->normal_ud), &(ed->inverse_ud));
1449 swap(&(ed->normal_fb), &(ed->inverse_fb));
1450 swap(&(ed->normal_rl), &(ed->inverse_rl));
1451}
154 1452
155 ind[i].val = index_coord(s->coord[i], &mvd, &tt); 1453void
156 ind[i].t = transform_trans(tt, t); 1454reset_estimatedata(EstimateData *ed)
157 } 1455{
1456 ed->corners = -1;
1457 ed->normal_ud = -1;
1458 ed->normal_fb = -1;
1459 ed->normal_rl = -1;
1460 ed->inverse_ud = -1;
1461 ed->inverse_fb = -1;
1462 ed->inverse_rl = -1;
1463 ed->oldret = -1;
158} 1464}
159*/
160 1465
161void 1466void
162prepare_cs(ChoiceStep *cs, SolveOptions *opts) 1467prepare_step(Step *step, SolveOptions *opts)
163{ 1468{
164 int i, j; 1469 int i;
165 Step *s;
166 1470
167 for (i = 0; cs->step[i] != NULL; i++) { 1471 if (step->final && opts->can_niss) {
168 s = cs->step[i]; 1472 opts->can_niss = false;
169 for (j = 0; j < s->n_coord; j++) { 1473 fprintf(stderr, "Step is final, NISS not used (-n ignored)\n");
170 s->pd[j] = malloc(sizeof(PruneData)); 1474 }
171 s->pd[j]->moveset = s->moveset; 1475
172 s->pd[j]->coord = s->coord[j]; 1476 for (i = 0; i < step->ntables; i++) {
173 s->pd[j]->compact = s->pd_compact[j]; 1477 genptable(step->tables[i], opts->nthreads);
174 s->pd[j] = genptable(s->pd[j], opts->nthreads); 1478 if (step->tables[i]->compact)
175 } 1479 genptable(step->tables[i]->fallback, opts->nthreads);
176 } 1480 }
177} 1481}

Generated with cgit - Back to sebastiano.tronto.net