aboutsummaryrefslogtreecommitdiff
path: root/src/steps.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/steps.c')
-rw-r--r--src/steps.c941
1 files changed, 941 insertions, 0 deletions
diff --git a/src/steps.c b/src/steps.c
new file mode 100644
index 0000000..56f7369
--- /dev/null
+++ b/src/steps.c
@@ -0,0 +1,941 @@
1#include "steps.h"
2
3/* Checkers, estimators and validators ***************************************/
4
5static bool check_centers(Cube cube);
6static bool check_eofb(Cube cube);
7static bool check_drud(Cube cube);
8static bool check_htr(Cube cube);
9
10static int estimate_eoany_HTM(CubeTarget ct);
11static int estimate_eofb_HTM(CubeTarget ct);
12static int estimate_coany_HTM(CubeTarget ct);
13static int estimate_coud_HTM(CubeTarget ct);
14static int estimate_coany_URF(CubeTarget ct);
15static int estimate_coud_URF(CubeTarget ct);
16static int estimate_corners_HTM(CubeTarget ct);
17static int estimate_cornershtr_HTM(CubeTarget ct);
18static int estimate_corners_URF(CubeTarget ct);
19static int estimate_cornershtr_URF(CubeTarget ct);
20static int estimate_drany_HTM(CubeTarget ct);
21static int estimate_drud_HTM(CubeTarget ct);
22static int estimate_drud_eofb(CubeTarget ct);
23static int estimate_dr_eofb(CubeTarget ct);
24static int estimate_drudfin_drud(CubeTarget ct);
25static int estimate_htr_drud(CubeTarget ct);
26static int estimate_htrfin_htr(CubeTarget ct);
27static int estimate_optimal_HTM(CubeTarget ct);
28
29static bool always_valid(Alg *alg);
30static bool validate_singlecw_ending(Alg *alg);
31
32/* Pre-transformation detectors **********************************************/
33
34static Trans detect_pretrans_eofb(Cube cube);
35static Trans detect_pretrans_drud(Cube cube);
36
37/* Messages for when cube is not ready ***************************************/
38
39static char check_centers_msg[100] = "cube must be oriented (centers solved)";
40static char check_eo_msg[100] = "EO must be solved on given axis";
41static char check_dr_msg[100] = "DR must be solved on given axis";
42static char check_htr_msg[100] = "HTR must be solved";
43static char check_drany_msg[100] = "DR must be solved on at least one axis";
44
45/* Steps *********************************************************************/
46
47Step
48optimal_HTM = {
49 .shortname = "optimal",
50 .name = "Optimal solve (in HTM)",
51
52 .estimate = estimate_optimal_HTM,
53 .ready = check_centers,
54 .ready_msg = check_centers_msg,
55 .is_valid = always_valid,
56 .moveset = moveset_HTM,
57
58 .pre_trans = uf,
59};
60
61/* EO steps **************************/
62Step
63eoany_HTM = {
64 .shortname = "eo",
65 .name = "EO on any axis",
66
67 .estimate = estimate_eoany_HTM,
68 .ready = check_centers,
69 .ready_msg = check_centers_msg,
70 .is_valid = validate_singlecw_ending,
71 .moveset = moveset_HTM,
72
73 .pre_trans = uf,
74};
75
76Step
77eofb_HTM = {
78 .shortname = "eofb",
79 .name = "EO on F/B",
80
81 .estimate = estimate_eofb_HTM,
82 .ready = check_centers,
83 .ready_msg = check_centers_msg,
84 .is_valid = validate_singlecw_ending,
85 .moveset = moveset_HTM,
86
87 .pre_trans = uf,
88};
89
90Step
91eorl_HTM = {
92 .shortname = "eorl",
93 .name = "EO on R/L",
94
95 .estimate = estimate_eofb_HTM,
96 .ready = check_centers,
97 .ready_msg = check_centers_msg,
98 .is_valid = validate_singlecw_ending,
99 .moveset = moveset_HTM,
100
101 .pre_trans = ur,
102};
103
104Step
105eoud_HTM = {
106 .shortname = "eoud",
107 .name = "EO on U/D",
108
109 .estimate = estimate_eofb_HTM,
110 .ready = check_centers,
111 .ready_msg = check_centers_msg,
112 .is_valid = validate_singlecw_ending,
113 .moveset = moveset_HTM,
114
115 .pre_trans = fd,
116};
117
118/* CO steps **************************/
119Step
120coany_HTM = {
121 .shortname = "co",
122 .name = "CO on any axis",
123
124 .estimate = estimate_coany_HTM,
125 .ready = NULL,
126 .is_valid = validate_singlecw_ending,
127 .moveset = moveset_HTM,
128
129 .pre_trans = uf,
130};
131
132Step
133coud_HTM = {
134 .shortname = "coud",
135 .name = "CO on U/D",
136
137 .estimate = estimate_coud_HTM,
138 .ready = NULL,
139 .is_valid = validate_singlecw_ending,
140 .moveset = moveset_HTM,
141
142 .pre_trans = uf,
143};
144
145Step
146corl_HTM = {
147 .shortname = "corl",
148 .name = "CO on R/L",
149
150 .estimate = estimate_coud_HTM,
151 .ready = NULL,
152 .is_valid = validate_singlecw_ending,
153 .moveset = moveset_HTM,
154
155 .pre_trans = rf,
156};
157
158Step
159cofb_HTM = {
160 .shortname = "cofb",
161 .name = "CO on F/B",
162
163 .estimate = estimate_coud_HTM,
164 .ready = NULL,
165 .is_valid = validate_singlecw_ending,
166 .moveset = moveset_HTM,
167
168 .pre_trans = fd,
169};
170
171Step
172coany_URF = {
173 .shortname = "co-URF",
174 .name = "CO any axis (URF moveset)",
175
176 .estimate = estimate_coany_URF,
177 .ready = NULL,
178 .is_valid = validate_singlecw_ending,
179 .moveset = moveset_URF,
180
181 .pre_trans = uf,
182};
183
184Step
185coud_URF = {
186 .shortname = "coud-URF",
187 .name = "CO on U/D (URF moveset)",
188
189 .estimate = estimate_coud_URF,
190 .ready = NULL,
191 .is_valid = validate_singlecw_ending,
192 .moveset = moveset_URF,
193
194 .pre_trans = uf,
195};
196
197Step
198corl_URF = {
199 .shortname = "corl-URF",
200 .name = "CO on R/L (URF moveset)",
201
202 .estimate = estimate_coud_URF,
203 .ready = NULL,
204 .is_valid = validate_singlecw_ending,
205 .moveset = moveset_URF,
206
207 .pre_trans = rf,
208};
209
210Step
211cofb_URF = {
212 .shortname = "cofb-URF",
213 .name = "CO on F/B (URF moveset)",
214
215 .estimate = estimate_coud_URF,
216 .ready = NULL,
217 .is_valid = validate_singlecw_ending,
218 .moveset = moveset_URF,
219
220 .pre_trans = fd,
221};
222
223/* Misc corner steps *****************/
224Step
225cornershtr_HTM = {
226 .shortname = "chtr",
227 .name = "Solve corners to HTR state",
228
229 .estimate = estimate_cornershtr_HTM,
230 .ready = NULL,
231 .is_valid = validate_singlecw_ending,
232 .moveset = moveset_HTM,
233
234 .pre_trans = uf,
235};
236
237Step
238cornershtr_URF = {
239 .shortname = "chtr-URF",
240 .name = "Solve corners to HTR state (URF moveset)",
241
242 .estimate = estimate_cornershtr_URF,
243 .ready = NULL,
244 .is_valid = validate_singlecw_ending,
245 .moveset = moveset_URF,
246
247 .pre_trans = uf,
248};
249
250Step
251corners_HTM = {
252 .shortname = "corners",
253 .name = "Solve corners",
254
255 .estimate = estimate_corners_HTM,
256 .ready = NULL,
257 .is_valid = always_valid,
258 .moveset = moveset_HTM,
259
260 .pre_trans = uf,
261};
262
263Step
264corners_URF = {
265 .shortname = "corners-URF",
266 .name = "Solve corners (URF moveset)",
267
268 .estimate = estimate_corners_URF,
269 .ready = NULL,
270 .is_valid = always_valid,
271 .moveset = moveset_URF,
272
273 .pre_trans = uf,
274};
275
276/* DR steps **************************/
277Step
278drany_HTM = {
279 .shortname = "dr",
280 .name = "DR on any axis",
281
282 .estimate = estimate_drany_HTM,
283 .ready = check_centers,
284 .ready_msg = check_centers_msg,
285 .is_valid = validate_singlecw_ending,
286 .moveset = moveset_HTM,
287
288 .pre_trans = uf,
289};
290
291Step
292drud_HTM = {
293 .shortname = "drud",
294 .name = "DR on U/D",
295
296 .estimate = estimate_drud_HTM,
297 .ready = check_centers,
298 .ready_msg = check_centers_msg,
299 .is_valid = validate_singlecw_ending,
300 .moveset = moveset_HTM,
301
302 .pre_trans = uf,
303};
304
305Step
306drrl_HTM = {
307 .shortname = "drrl",
308 .name = "DR on R/L",
309
310 .estimate = estimate_drud_HTM,
311 .ready = check_centers,
312 .ready_msg = check_centers_msg,
313 .is_valid = validate_singlecw_ending,
314 .moveset = moveset_HTM,
315
316 .pre_trans = rf,
317};
318
319Step
320drfb_HTM = {
321 .shortname = "drfb",
322 .name = "DR on F/B",
323
324 .estimate = estimate_drud_HTM,
325 .ready = check_centers,
326 .ready_msg = check_centers_msg,
327 .is_valid = validate_singlecw_ending,
328 .moveset = moveset_HTM,
329
330 .pre_trans = fd,
331};
332
333/* DR from EO */
334Step
335dr_eo = {
336 .shortname = "dr-eo",
337 .name = "DR without breaking EO (automatically detected)",
338
339 .estimate = estimate_dr_eofb,
340 .ready = check_eofb,
341 .ready_msg = check_eo_msg,
342 .is_valid = validate_singlecw_ending,
343 .moveset = moveset_eofb,
344
345 .detect = detect_pretrans_eofb,
346};
347
348Step
349dr_eofb = {
350 .shortname = "dr-eofb",
351 .name = "DR on U/D or R/L without breaking EO on F/B",
352
353 .estimate = estimate_dr_eofb,
354 .ready = check_eofb,
355 .ready_msg = check_eo_msg,
356 .is_valid = validate_singlecw_ending,
357 .moveset = moveset_eofb,
358
359 .pre_trans = uf,
360};
361
362Step
363dr_eorl = {
364 .shortname = "dr-eorl",
365 .name = "DR on U/D or F/B without breaking EO on R/L",
366
367 .estimate = estimate_dr_eofb,
368 .ready = check_eofb,
369 .ready_msg = check_eo_msg,
370 .is_valid = validate_singlecw_ending,
371 .moveset = moveset_eofb,
372
373 .pre_trans = ur,
374};
375
376Step
377dr_eoud = {
378 .shortname = "dr-eoud",
379 .name = "DR on R/L or F/B without breaking EO on U/R",
380
381 .estimate = estimate_dr_eofb,
382 .ready = check_eofb,
383 .ready_msg = check_eo_msg,
384 .is_valid = validate_singlecw_ending,
385 .moveset = moveset_eofb,
386
387 .pre_trans = fd,
388};
389
390Step
391drud_eofb = {
392 .shortname = "drud-eofb",
393 .name = "DR on U/D without breaking EO on F/B",
394
395 .estimate = estimate_drud_eofb,
396 .ready = check_eofb,
397 .ready_msg = check_eo_msg,
398 .is_valid = validate_singlecw_ending,
399 .moveset = moveset_eofb,
400
401 .pre_trans = uf,
402};
403
404Step
405drrl_eofb = {
406 .shortname = "drrl-eofb",
407 .name = "DR on R/L without breaking EO on F/B",
408
409 .estimate = estimate_drud_eofb,
410 .ready = check_eofb,
411 .ready_msg = check_eo_msg,
412 .is_valid = validate_singlecw_ending,
413 .moveset = moveset_eofb,
414
415 .pre_trans = rf,
416};
417
418Step
419drud_eorl = {
420 .shortname = "drud-eorl",
421 .name = "DR on U/D without breaking EO on R/L",
422
423 .estimate = estimate_drud_eofb,
424 .ready = check_eofb,
425 .ready_msg = check_eo_msg,
426 .is_valid = validate_singlecw_ending,
427 .moveset = moveset_eofb,
428
429 .pre_trans = ur,
430};
431
432Step
433drfb_eorl = {
434 .shortname = "drfb-eorl",
435 .name = "DR on F/B without breaking EO on R/L",
436
437 .estimate = estimate_drud_eofb,
438 .ready = check_eofb,
439 .ready_msg = check_eo_msg,
440 .is_valid = validate_singlecw_ending,
441 .moveset = moveset_eofb,
442
443 .pre_trans = fr,
444};
445
446Step
447drfb_eoud = {
448 .shortname = "drfb-eoud",
449 .name = "DR on F/B without breaking EO on U/D",
450
451 .estimate = estimate_drud_eofb,
452 .ready = check_eofb,
453 .ready_msg = check_eo_msg,
454 .is_valid = validate_singlecw_ending,
455 .moveset = moveset_eofb,
456
457 .pre_trans = fd,
458};
459
460Step
461drrl_eoud = {
462 .shortname = "drrl-eoud",
463 .name = "DR on R/L without breaking EO on U/D",
464
465 .estimate = estimate_drud_eofb,
466 .ready = check_eofb,
467 .ready_msg = check_eo_msg,
468 .is_valid = validate_singlecw_ending,
469 .moveset = moveset_eofb,
470
471 .pre_trans = rd,
472};
473
474/* DR finish steps */
475Step
476dranyfin_DR = {
477 .shortname = "drfin",
478 .name = "DR finish on any axis without breaking DR",
479
480 .estimate = estimate_drudfin_drud,
481 .ready = check_drud,
482 .ready_msg = check_drany_msg,
483 .is_valid = always_valid,
484 .moveset = moveset_drud,
485
486 .detect = detect_pretrans_drud,
487};
488
489Step
490drudfin_drud = {
491 .shortname = "drudfin",
492 .name = "DR finish on U/D without breaking DR",
493
494 .estimate = estimate_drudfin_drud,
495 .ready = check_drud,
496 .ready_msg = check_dr_msg,
497 .is_valid = always_valid,
498 .moveset = moveset_drud,
499
500 .pre_trans = uf,
501};
502
503Step
504drrlfin_drrl = {
505 .shortname = "drrlfin",
506 .name = "DR finish on R/L without breaking DR",
507
508 .estimate = estimate_drudfin_drud,
509 .ready = check_drud,
510 .ready_msg = check_dr_msg,
511 .is_valid = always_valid,
512 .moveset = moveset_drud,
513
514 .pre_trans = rf,
515};
516
517Step
518drfbfin_drfb = {
519 .shortname = "drfbfin",
520 .name = "DR finish on F/B without breaking DR",
521
522 .estimate = estimate_drudfin_drud,
523 .ready = check_drud,
524 .ready_msg = check_dr_msg,
525 .is_valid = always_valid,
526 .moveset = moveset_drud,
527
528 .pre_trans = fd,
529};
530
531/* HTR from DR */
532Step
533htr_any = {
534 .shortname = "htr",
535 .name = "HTR from DR",
536
537 .estimate = estimate_htr_drud,
538 .ready = check_drud,
539 .ready_msg = check_drany_msg,
540 .is_valid = validate_singlecw_ending,
541 .moveset = moveset_drud,
542
543 .detect = detect_pretrans_drud,
544};
545
546Step
547htr_drud = {
548 .shortname = "htr-drud",
549 .name = "HTR from DR on U/D",
550
551 .estimate = estimate_htr_drud,
552 .ready = check_drud,
553 .ready_msg = check_dr_msg,
554 .is_valid = validate_singlecw_ending,
555 .moveset = moveset_drud,
556
557 .pre_trans = uf,
558};
559
560Step
561htr_drrl = {
562 .shortname = "htr-drrl",
563 .name = "HTR from DR on R/L",
564
565 .estimate = estimate_htr_drud,
566 .ready = check_drud,
567 .ready_msg = check_dr_msg,
568 .is_valid = validate_singlecw_ending,
569 .moveset = moveset_drud,
570
571 .pre_trans = rf,
572};
573
574Step
575htr_drfb = {
576 .shortname = "htr-drfb",
577 .name = "HTR from DR on F/B",
578
579 .estimate = estimate_htr_drud,
580 .ready = check_drud,
581 .ready_msg = check_dr_msg,
582 .is_valid = validate_singlecw_ending,
583 .moveset = moveset_drud,
584
585 .pre_trans = fd,
586};
587
588/* HTR finish */
589Step
590htrfin_htr = {
591 .shortname = "htrfin",
592 .name = "HTR finish without breaking HTR",
593
594 .estimate = estimate_htrfin_htr,
595 .ready = check_htr,
596 .ready_msg = check_htr_msg,
597 .is_valid = always_valid,
598 .moveset = moveset_htr,
599
600 .pre_trans = uf,
601};
602
603Step *steps[NSTEPS] = {
604 &optimal_HTM, /* first is default */
605
606 &eoany_HTM,
607 &eofb_HTM,
608 &eorl_HTM,
609 &eoud_HTM,
610
611 &coany_HTM,
612 &coud_HTM,
613 &corl_HTM,
614 &cofb_HTM,
615
616 &coany_URF,
617 &coud_URF,
618 &corl_URF,
619 &cofb_URF,
620
621 &drany_HTM,
622 &drud_HTM,
623 &drrl_HTM,
624 &drfb_HTM,
625
626 &dr_eo,
627 &dr_eofb,
628 &dr_eorl,
629 &dr_eoud,
630 &drud_eofb,
631 &drrl_eofb,
632 &drud_eorl,
633 &drfb_eorl,
634 &drfb_eoud,
635 &drrl_eoud,
636
637 &dranyfin_DR,
638 &drudfin_drud,
639 &drrlfin_drrl,
640 &drfbfin_drfb,
641
642 &htr_any,
643 &htr_drud,
644 &htr_drrl,
645 &htr_drfb,
646
647 &htrfin_htr,
648
649 &cornershtr_HTM,
650 &cornershtr_URF,
651 &corners_HTM,
652 &corners_URF,
653};
654
655/* Checkers, estimators and validators ***************************************/
656
657static bool
658check_centers(Cube cube)
659{
660 return cube.cpos == 0;
661}
662
663static bool
664check_eofb(Cube cube)
665{
666 return cube.eofb == 0;
667}
668
669static bool
670check_drud(Cube cube)
671{
672 return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
673}
674
675static bool
676check_htr(Cube cube)
677{
678 return check_drud(cube) && coord_htr_drud.index(cube) == 0;
679}
680
681static int
682estimate_eoany_HTM(CubeTarget ct)
683{
684 int r1, r2, r3;
685
686 r1 = ptableval(&pd_eofb_HTM, ct.cube);
687 r2 = ptableval(&pd_eofb_HTM, apply_trans(ur, ct.cube));
688 r3 = ptableval(&pd_eofb_HTM, apply_trans(fd, ct.cube));
689
690 return MIN(r1, MIN(r2, r3));
691}
692
693static int
694estimate_eofb_HTM(CubeTarget ct)
695{
696 return ptableval(&pd_eofb_HTM, ct.cube);
697}
698
699static int
700estimate_coany_HTM(CubeTarget ct)
701{
702 int r1, r2, r3;
703
704 r1 = ptableval(&pd_coud_HTM, ct.cube);
705 r2 = ptableval(&pd_coud_HTM, apply_trans(rf, ct.cube));
706 r3 = ptableval(&pd_coud_HTM, apply_trans(fd, ct.cube));
707
708 return MIN(r1, MIN(r2, r3));
709}
710
711static int
712estimate_coud_HTM(CubeTarget ct)
713{
714 return ptableval(&pd_coud_HTM, ct.cube);
715}
716
717static int
718estimate_coany_URF(CubeTarget ct)
719{
720 int r1, r2, r3;
721 CubeTarget ct2, ct3;
722
723 ct2.cube = apply_trans(rf, ct.cube);
724 ct2.target = ct.target;
725
726 ct3.cube = apply_trans(fd, ct.cube);
727 ct3.target = ct.target;
728
729 r1 = estimate_coud_URF(ct);
730 r2 = estimate_coud_URF(ct2);
731 r3 = estimate_coud_URF(ct3);
732
733 return MIN(r1, MIN(r2, r3));
734}
735
736static int
737estimate_coud_URF(CubeTarget ct)
738{
739 /* TODO: I can improve this by checking first the orientation of
740 * the corner in DBL and use that as a reference */
741
742 CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target};
743 CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target};
744
745 int ud = estimate_coud_HTM(ct);
746 int rl = estimate_coud_HTM(ct2);
747 int fb = estimate_coud_HTM(ct3);
748
749 return MIN(ud, MIN(rl, fb));
750}
751
752static int
753estimate_corners_HTM(CubeTarget ct)
754{
755 return ptableval(&pd_corners_HTM, ct.cube);
756}
757
758static int
759estimate_cornershtr_HTM(CubeTarget ct)
760{
761 return ptableval(&pd_cornershtr_HTM, ct.cube);
762}
763
764static int
765estimate_cornershtr_URF(CubeTarget ct)
766{
767 /* TODO: I can improve this by checking first the corner in DBL
768 * and use that as a reference */
769
770 int c, ret = 15;
771 Trans i;
772
773 for (i = 0; i < NROTATIONS; i++) {
774 ct.cube = apply_alg(rotation_alg(i), ct.cube);
775 c = estimate_cornershtr_HTM(ct);
776 ret = MIN(ret, c);
777 }
778
779 return ret;
780}
781
782static int
783estimate_corners_URF(CubeTarget ct)
784{
785 /* TODO: I can improve this by checking first the corner in DBL
786 * and use that as a reference */
787
788 int c, ret = 15;
789 Trans i;
790
791 for (i = 0; i < NROTATIONS; i++) {
792 ct.cube = apply_alg(rotation_alg(i), ct.cube);
793 c = estimate_corners_HTM(ct);
794 ret = MIN(ret, c);
795 }
796
797 return ret;
798}
799
800static int
801estimate_drany_HTM(CubeTarget ct)
802{
803 int r1, r2, r3;
804
805 r1 = ptableval(&pd_drud_sym16_HTM, ct.cube);
806 r2 = ptableval(&pd_drud_sym16_HTM, apply_trans(rf, ct.cube));
807 r3 = ptableval(&pd_drud_sym16_HTM, apply_trans(fd, ct.cube));
808
809 return MIN(r1, MIN(r2, r3));
810}
811
812static int
813estimate_drud_HTM(CubeTarget ct)
814{
815 return ptableval(&pd_drud_sym16_HTM, ct.cube);
816}
817
818static int
819estimate_drud_eofb(CubeTarget ct)
820{
821 return ptableval(&pd_drud_eofb, ct.cube);
822}
823
824static int
825estimate_dr_eofb(CubeTarget ct)
826{
827 int r1, r2;
828
829 r1 = ptableval(&pd_drud_eofb, ct.cube);
830 r2 = ptableval(&pd_drud_eofb, apply_trans(rf, ct.cube));
831
832 return MIN(r1, r2);
833}
834
835static int
836estimate_drudfin_drud(CubeTarget ct)
837{
838 int val = ptableval(&pd_drudfin_noE_sym16_drud, ct.cube);
839
840 if (val != 0)
841 return val;
842
843 return ct.cube.epose % 24 == 0 ? 0 : 1;
844}
845
846static int
847estimate_htr_drud(CubeTarget ct)
848{
849 return ptableval(&pd_htr_drud, ct.cube);
850}
851
852static int
853estimate_htrfin_htr(CubeTarget ct)
854{
855 return ptableval(&pd_htrfin_htr, ct.cube);
856}
857
858static int
859estimate_optimal_HTM(CubeTarget ct)
860{
861 int dr1, dr2, dr3, cor, ret;
862 Cube cube = ct.cube;
863
864 dr1 = ptableval(&pd_khuge_HTM, cube);
865 cor = estimate_corners_HTM(ct);
866 ret = MAX(dr1, cor);
867
868 if (ret > ct.target)
869 return ret;
870
871 cube = apply_trans(rf, ct.cube);
872 dr2 = ptableval(&pd_khuge_HTM, cube);
873 ret = MAX(ret, dr2);
874
875 if (ret > ct.target)
876 return ret;
877
878 cube = apply_trans(fd, ct.cube);
879 dr3 = ptableval(&pd_khuge_HTM, cube);
880
881 /* Michiel de Bondt's trick */
882 if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
883 dr3++;
884
885 return MAX(ret, dr3);
886}
887
888static bool
889always_valid(Alg *alg)
890{
891 return true;
892}
893
894static bool
895validate_singlecw_ending(Alg *alg)
896{
897 int i;
898 bool nor, inv;
899 Move l2 = NULLMOVE, l1 = NULLMOVE, l2i = NULLMOVE, l1i = NULLMOVE;
900
901 for (i = 0; i < alg->len; i++) {
902 if (alg->inv[i]) {
903 l2i = l1i;
904 l1i = alg->move[i];
905 } else {
906 l2 = l1;
907 l1 = alg->move[i];
908 }
909 }
910
911 nor = l1 ==base_move(l1) && (!commute(l1, l2) ||l2 ==base_move(l2));
912 inv = l1i==base_move(l1i) && (!commute(l1i,l2i)||l2i==base_move(l2i));
913
914 return nor && inv;
915}
916
917/* Pre-transformation detectors **********************************************/
918
919static Trans
920detect_pretrans_eofb(Cube cube)
921{
922 Trans i;
923
924 for (i = 0; i < NROTATIONS; i++)
925 if (check_eofb(apply_trans(i, cube)))
926 return i;
927
928 return 0;
929}
930
931static Trans
932detect_pretrans_drud(Cube cube)
933{
934 Trans i;
935
936 for (i = 0; i < NROTATIONS; i++)
937 if (check_drud(apply_trans(i, cube)))
938 return i;
939
940 return 0;
941}

Generated with cgit - Back to sebastiano.tronto.net