aboutsummaryrefslogtreecommitdiff
path: root/src/cube.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-10-22 14:48:42 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2023-10-22 14:48:42 +0200
commit0c49ed5afc2ae9e4bc4aa1af9c655bbe1f3d14b8 (patch)
tree4e69457ed87cb06decc12889a1ded18c17610dad /src/cube.c
parent259c7326f78d5495f5dc51c619932599a5279f68 (diff)
downloadnissy-core-0c49ed5afc2ae9e4bc4aa1af9c655bbe1f3d14b8.tar.gz
nissy-core-0c49ed5afc2ae9e4bc4aa1af9c655bbe1f3d14b8.zip
Small change of plans, moved stuff around
Diffstat (limited to 'src/cube.c')
-rw-r--r--src/cube.c911
1 files changed, 911 insertions, 0 deletions
diff --git a/src/cube.c b/src/cube.c
new file mode 100644
index 0000000..f6e6a8f
--- /dev/null
+++ b/src/cube.c
@@ -0,0 +1,911 @@
1#include <inttypes.h>
2#include <stdbool.h>
3#include <string.h>
4
5#ifdef DEBUG
6#include <stdio.h>
7#endif
8
9#include "cube.h"
10
11#define _c_ufr 0U
12#define _c_ubl 1U
13#define _c_dfl 2U
14#define _c_dbr 3U
15#define _c_ufl 4U
16#define _c_ubr 5U
17#define _c_dfr 6U
18#define _c_dbl 7U
19
20#define _e_uf 0U
21#define _e_ub 1U
22#define _e_db 2U
23#define _e_df 3U
24#define _e_ur 4U
25#define _e_ul 5U
26#define _e_dl 6U
27#define _e_dr 7U
28#define _e_fr 8U
29#define _e_fl 9U
30#define _e_bl 10U
31#define _e_br 11U
32
33#define _eoshift 4U
34#define _coshift 5U
35
36#define _pbits 0xFU
37#define _eobit 0x10U
38#define _cobits 0xF0U
39#define _cobits2 0x60U
40#define _ctwist_cw 0x20U
41#define _ctwist_ccw 0x40U
42#define _eflip 0x10U
43#define _error 0xFFU
44
45static char *cornerstr[] = {
46 [_c_ufr] = "UFR",
47 [_c_ubl] = "UBL",
48 [_c_dfl] = "DFL",
49 [_c_dbr] = "DBR",
50 [_c_ufl] = "UFL",
51 [_c_ubr] = "UBR",
52 [_c_dfr] = "DFR",
53 [_c_dbl] = "DBL"
54};
55
56static char *cornerstralt[] = {
57 [_c_ufr] = "URF",
58 [_c_ubl] = "ULB",
59 [_c_dfl] = "DLF",
60 [_c_dbr] = "DRB",
61 [_c_ufl] = "ULF",
62 [_c_ubr] = "URB",
63 [_c_dfr] = "DRF",
64 [_c_dbl] = "DLB"
65};
66
67static char *edgestr[] = {
68 [_e_uf] = "UF",
69 [_e_ub] = "UB",
70 [_e_db] = "DB",
71 [_e_df] = "DF",
72 [_e_ur] = "UR",
73 [_e_ul] = "UL",
74 [_e_dl] = "DL",
75 [_e_dr] = "DR",
76 [_e_fr] = "FR",
77 [_e_fl] = "FL",
78 [_e_bl] = "BL",
79 [_e_br] = "BR"
80};
81
82static char *movestr[] = {
83 [U] = "U",
84 [U2] = "U2",
85 [U3] = "U'",
86 [D] = "D",
87 [D2] = "D2",
88 [D3] = "D'",
89 [R] = "R",
90 [R2] = "R2",
91 [R3] = "R'",
92 [L] = "L",
93 [L2] = "L2",
94 [L3] = "L'",
95 [F] = "F",
96 [F2] = "F2",
97 [F3] = "F'",
98 [B] = "B",
99 [B2] = "B2",
100 [B3] = "B'",
101};
102
103static char *transstr[] = {
104 [UFr] = "rotation UF",
105 [UFm] = "mirrored UF",
106 [ULr] = "rotation UL",
107 [ULm] = "mirrored UL",
108 [UBr] = "rotation UB",
109 [UBm] = "mirrored UB",
110 [URr] = "rotation UR",
111 [URm] = "mirrored UR",
112 [DFr] = "rotation DF",
113 [DFm] = "mirrored DF",
114 [DLr] = "rotation DL",
115 [DLm] = "mirrored DL",
116 [DBr] = "rotation DB",
117 [DBm] = "mirrored DB",
118 [DRr] = "rotation DR",
119 [DRm] = "mirrored DR",
120 [RUr] = "rotation RU",
121 [RUm] = "mirrored RU",
122 [RFr] = "rotation RF",
123 [RFm] = "mirrored RF",
124 [RDr] = "rotation RD",
125 [RDm] = "mirrored RD",
126 [RBr] = "rotation RB",
127 [RBm] = "mirrored RB",
128 [LUr] = "rotation LU",
129 [LUm] = "mirrored LU",
130 [LFr] = "rotation LF",
131 [LFm] = "mirrored LF",
132 [LDr] = "rotation LD",
133 [LDm] = "mirrored LD",
134 [LBr] = "rotation LB",
135 [LBm] = "mirrored LB",
136 [FUr] = "rotation FU",
137 [FUm] = "mirrored FU",
138 [FRr] = "rotation FR",
139 [FRm] = "mirrored FR",
140 [FDr] = "rotation FD",
141 [FDm] = "mirrored FD",
142 [FLr] = "rotation FL",
143 [FLm] = "mirrored FL",
144 [BUr] = "rotation BU",
145 [BUm] = "mirrored BU",
146 [BRr] = "rotation BR",
147 [BRm] = "mirrored BR",
148 [BDr] = "rotation BD",
149 [BDm] = "mirrored BD",
150 [BLr] = "rotation BL",
151 [BLm] = "mirrored BL",
152};
153
154cube_t solvedcube = {
155 .c = {
156 [_c_ufr] = _c_ufr,
157 [_c_ubl] = _c_ubl,
158 [_c_dfl] = _c_dfl,
159 [_c_dbr] = _c_dbr,
160 [_c_ufl] = _c_ufl,
161 [_c_ubr] = _c_ubr,
162 [_c_dfr] = _c_dfr,
163 [_c_dbl] = _c_dbl
164 },
165 .e = {
166 [_e_uf] = _e_uf,
167 [_e_ub] = _e_ub,
168 [_e_db] = _e_db,
169 [_e_df] = _e_df,
170 [_e_ur] = _e_ur,
171 [_e_ul] = _e_ul,
172 [_e_dl] = _e_dl,
173 [_e_dr] = _e_dr,
174 [_e_fr] = _e_fr,
175 [_e_fl] = _e_fl,
176 [_e_bl] = _e_bl,
177 [_e_br] = _e_br
178 }
179};
180
181static cube_t errorcube = { .e = {0}, .c = {0} };
182
183static bool isconsistent(cube_t);
184static uint8_t readco(char *);
185static uint8_t readcp(char *);
186static uint8_t readeo(char *);
187static uint8_t readep(char *);
188static uint8_t readmove(char);
189static uint8_t readmodifier(char);
190static cube_t readcube_H48(char *);
191static void writecube_H48(cube_t, char *);
192static int writepiece_SRC(uint8_t, char *);
193static void writecube_SRC(cube_t, char *);
194static int permsign(uint8_t *, int);
195
196static uint8_t
197readco(char *str)
198{
199 if (*str == '0')
200 return 0;
201 if (*str == '1')
202 return _ctwist_cw;
203 if (*str == '2')
204 return _ctwist_ccw;
205
206#ifdef DEBUG
207 fprintf(stderr, "Error reading CO\n");
208#endif
209 return _error;
210}
211
212static uint8_t
213readcp(char *str)
214{
215 uint8_t c;
216
217 for (c = 0; c < 8; c++)
218 if (!strncmp(str, cornerstr[c], 3) ||
219 !strncmp(str, cornerstralt[c], 3))
220 return c;
221
222#ifdef DEBUG
223 fprintf(stderr, "Error reading CP\n");
224#endif
225 return _error;
226}
227
228static uint8_t
229readeo(char *str)
230{
231 if (*str == '0')
232 return 0;
233 if (*str == '1')
234 return _eflip;
235
236#ifdef DEBUG
237 fprintf(stderr, "Error reading EO\n");
238#endif
239 return _error;
240}
241
242static uint8_t
243readep(char *str)
244{
245 uint8_t e;
246
247 for (e = 0; e < 12; e++)
248 if (!strncmp(str, edgestr[e], 2))
249 return e;
250
251#ifdef DEBUG
252 fprintf(stderr, "Error reading EP\n");
253#endif
254 return _error;
255}
256
257static cube_t
258readcube_H48(char *buf)
259{
260 int i;
261 uint8_t piece, orient;
262 cube_t ret = {0};
263 char *b = buf;
264
265 for (i = 0; i < 12; i++) {
266 while (*b == ' ' || *b == '\t' || *b == '\n')
267 b++;
268 if ((piece = readep(b)) == _error)
269 return errorcube;
270 b += 2;
271 if ((orient = readeo(b)) == _error)
272 return errorcube;
273 b++;
274 ret.e[i] = piece | orient;
275 }
276 for (i = 0; i < 8; i++) {
277 while (*b == ' ' || *b == '\t' || *b == '\n')
278 b++;
279 if ((piece = readcp(b)) == _error)
280 return errorcube;
281 b += 3;
282 if ((orient = readco(b)) == _error)
283 return errorcube;
284 b++;
285 ret.c[i] = piece | orient;
286 }
287
288 return ret;
289}
290
291cube_t
292readcube(format_t format, char *buf)
293{
294 cube_t ret;
295
296 switch (format) {
297 case H48:
298 ret = readcube_H48(buf);
299 break;
300 default:
301 #ifdef DEBUG
302 fprintf(stderr, "Cannot read cube in the given format\n");
303 #endif
304 ret = errorcube;
305 }
306
307#ifdef DEBUG
308 if (iserror(ret))
309 fprintf(stderr, "readcube error\n");
310#endif
311 return ret;
312}
313
314static void
315writecube_H48(cube_t cube, char *buf)
316{
317 uint8_t piece, orient;
318 int i;
319
320 for (i = 0; i < 12; i++) {
321 piece = cube.e[i] & _pbits;
322 orient = (cube.e[i] & _eobit) >> _eoshift;
323 buf[4*i ] = edgestr[piece][0];
324 buf[4*i + 1] = edgestr[piece][1];
325 buf[4*i + 2] = orient + '0';
326 buf[4*i + 3] = ' ';
327 }
328 for (i = 0; i < 8; i++) {
329 piece = cube.c[i] & _pbits;
330 orient = (cube.c[i] & _cobits) >> _coshift;
331 buf[48 + 5*i ] = cornerstr[piece][0];
332 buf[48 + 5*i + 1] = cornerstr[piece][1];
333 buf[48 + 5*i + 2] = cornerstr[piece][2];
334 buf[48 + 5*i + 3] = orient + '0';
335 buf[48 + 5*i + 4] = ' ';
336 }
337
338 buf[48+39] = '\0';
339}
340
341static int
342writepiece_SRC(uint8_t piece, char *buf)
343{
344 char digits[3];
345 int i, len = 0;
346
347 while (piece != 0) {
348 digits[len++] = (piece % 10) + '0';
349 piece /= 10;
350 }
351
352 if (len == 0)
353 digits[len++] = '0';
354
355 for (i = 0; i < len; i++)
356 buf[i] = digits[len-i-1];
357
358 buf[len] = ',';
359 buf[len+1] = ' ';
360
361 return len+2;
362}
363
364static void
365writecube_SRC(cube_t cube, char *buf)
366{
367 int i, ptr;
368
369 memcpy(buf, "{\n\t.c = {", 9);
370 ptr = 9;
371
372 for (i = 0; i < 8; i++)
373 ptr += writepiece_SRC(cube.c[i], buf + ptr);
374
375 memcpy(buf+ptr-2, "},\n\t.e = {", 10);
376 ptr += 8;
377
378 for (i = 0; i < 12; i++)
379 ptr += writepiece_SRC(cube.e[i], buf + ptr);
380
381 memcpy(buf+ptr-2, "}\n}\0", 4);
382}
383
384void
385writecube(format_t format, cube_t cube, char *buf)
386{
387 char *errormsg;
388 size_t len;
389
390 if (!isconsistent(cube)) {
391 errormsg = "ERROR: cannot write inconsistent cube";
392 goto writecube_error;
393 }
394
395 switch (format) {
396 case H48:
397 writecube_H48(cube, buf);
398 break;
399 case SRC:
400 writecube_SRC(cube, buf);
401 break;
402 default:
403 errormsg = "ERROR: cannot write cube in the given format";
404 goto writecube_error;
405 }
406
407 return;
408
409writecube_error:
410#ifdef DEBUG
411 fprintf(stderr, "writecube error, see stdout for details\n");
412#endif
413 len = strlen(errormsg);
414 memcpy(buf, errormsg, len);
415 buf[len] = '\n';
416 buf[len+1] = '\0';
417}
418
419static uint8_t
420readmove(char c)
421{
422 switch (c) {
423 case 'U':
424 return U;
425 case 'D':
426 return D;
427 case 'R':
428 return R;
429 case 'L':
430 return L;
431 case 'F':
432 return F;
433 case 'B':
434 return B;
435 default:
436 return _error;
437 }
438}
439
440static uint8_t
441readmodifier(char c)
442{
443 switch (c) {
444 case '1': /* Fallthrough */
445 case '2': /* Fallthrough */
446 case '3':
447 return c - '0' - 1;
448 case '\'':
449 return 2;
450 default:
451 return 0;
452 }
453}
454
455int
456readmoves(char *buf, move_t *m)
457{
458 int n;
459 uint64_t r;
460 char *b;
461
462 for (b = buf, n = 0; *b != '\0'; b++) {
463 while (*b == ' ' || *b == '\t' || *b == '\n')
464 b++;
465 if (*b == '\0')
466 return n;
467 if ((r = readmove(*b)) == _error)
468 goto readmoves_error;
469 m[n] = (move_t)r;
470 if ((r = readmodifier(*(b+1))) != 0) {
471 b++;
472 m[n] += r;
473 }
474 n++;
475 }
476
477 return n;
478
479readmoves_error:
480#ifdef DEBUG
481 fprintf(stderr, "readmoves error\n");
482#endif
483 return -1;
484}
485
486trans_t
487readtrans(char *buf)
488{
489 uint8_t t;
490
491 for (t = 0; t < 48; t++)
492 if (!strncmp(buf, transstr[t], 11))
493 return t;
494
495#ifdef DEBUG
496 fprintf(stderr, "readtrans error\n");
497#endif
498 return errortrans;
499}
500
501void
502writemoves(move_t *m, int n, char *buf)
503{
504 int i;
505 size_t len;
506 char *b, *s;
507
508 for (i = 0, b = buf; i < n; i++, b++) {
509 s = movestr[m[i]];
510 len = strlen(s);
511 memcpy(b, s, len);
512 b += len;
513 *b = ' ';
514 }
515 *b = '\0';
516}
517
518void
519writetrans(trans_t t, char *buf)
520{
521 if (t >= 48)
522 memcpy(buf, "error trans", 11);
523 else
524 memcpy(buf, transstr[t], 11);
525 buf[11] = '\0';
526}
527
528static int
529permsign(uint8_t *a, int n)
530{
531 int i, j;
532 uint8_t ret = 0;
533
534 for (i = 0; i < n; i++)
535 for (j = i+1; j < n; j++)
536 ret += (a[i] & _pbits) > (a[j] & _pbits) ? 1 : 0;
537
538 return ret % 2;
539}
540
541static bool
542isconsistent(cube_t c)
543{
544 uint8_t i, p, e;
545 bool found[12];
546
547 for (i = 0; i < 12; i++)
548 found[i] = false;
549 for (i = 0; i < 12; i++) {
550 p = c.e[i] & _pbits;
551 e = c.e[i] & ~_pbits;
552 if (p >= 12)
553 goto inconsistent_ep;
554 if (e != 0 && e != _eobit)
555 goto inconsistent_eo;
556 found[p] = true;
557 }
558 for (i = 0; i < 12; i++)
559 if (!found[i])
560 goto inconsistent_ep;
561
562 for (i = 0; i < 8; i++)
563 found[i] = false;
564 for (i = 0; i < 8; i++) {
565 p = c.c[i] & _pbits;
566 e = c.c[i] & ~_pbits;
567 if (p >= 8)
568 goto inconsistent_cp;
569 if (e != 0 && e != _ctwist_cw && e != _ctwist_ccw)
570 goto inconsistent_co;
571 found[p] = true;
572 }
573 for (i = 0; i < 8; i++)
574 if (!found[i])
575 goto inconsistent_co;
576
577 return true;
578
579inconsistent_ep:
580#ifdef DEBUG
581 fprintf(stderr, "Inconsistent EP\n");
582#endif
583 return false;
584inconsistent_cp:
585#ifdef DEBUG
586 fprintf(stderr, "Inconsistent CP\n");
587#endif
588 return false;
589inconsistent_eo:
590#ifdef DEBUG
591 fprintf(stderr, "Inconsistent EO\n");
592#endif
593 return false;
594inconsistent_co:
595#ifdef DEBUG
596 fprintf(stderr, "Inconsistent CO\n");
597#endif
598 return false;
599}
600
601bool
602issolvable(cube_t cube)
603{
604 int8_t i, eo, co;
605
606#ifdef DEBUG
607 if (!isconsistent(cube))
608 goto issolvable_inconsistent;
609#endif
610
611 if (permsign(cube.e, 12) != permsign(cube.c, 8))
612 goto issolvable_parity;
613
614 eo = 0;
615 for (i = 0; i < 12; i++)
616 eo += (cube.e[i] & _eobit) >> _eoshift;
617 if (eo % 2 != 0)
618 goto issolvable_eo;
619
620 co = 0;
621 for (i = 0; i < 8; i++)
622 co += (cube.c[i] & _cobits) >> _coshift;
623 if (co % 3 != 0)
624 goto issolvable_co;
625
626 return true;
627
628issolvable_inconsistent:
629#ifdef DEBUG
630 fprintf(stderr, "issolvable: cube is inconsistent\n");
631#endif
632 return false;
633issolvable_parity:
634#ifdef DEBUG
635 fprintf(stderr, "EP and CP parities are different\n");
636#endif
637 return false;
638issolvable_eo:
639#ifdef DEBUG
640 fprintf(stderr, "Odd number of flipped edges\n");
641#endif
642 return false;
643issolvable_co:
644#ifdef DEBUG
645 fprintf(stderr, "Sum of corner orientation is not multiple of 3\n");
646#endif
647 return false;
648}
649
650bool
651equal(cube_t cube1, cube_t cube2)
652{
653 uint8_t i;
654
655 for (i = 0; i < 12; i++)
656 if (cube1.e[i] != cube2.e[i])
657 return false;
658
659 for (i = 0; i < 8; i++)
660 if (cube1.c[i] != cube2.c[i])
661 return false;
662
663 return true;
664}
665
666bool
667issolved(cube_t cube)
668{
669 return equal(cube, solvedcube);
670}
671
672bool
673iserror(cube_t cube)
674{
675 return equal(cube, errorcube);
676}
677
678cube_t
679move(cube_t c, move_t m)
680{
681 cube_t ret;
682 uint8_t aux, auy, auz;
683
684#ifdef DEBUG
685 if (!isconsistent(c))
686 goto move_inconsistent;
687#endif
688
689#define PERM4(r, i, j, k, l) \
690 aux = r[i]; \
691 r[i] = r[l]; \
692 r[l] = r[k]; \
693 r[k] = r[j]; \
694 r[j] = aux;
695#define PERM22(r, i, j, k, l) \
696 aux = r[i]; \
697 r[i] = r[j]; \
698 r[j] = aux; \
699 aux = r[k]; \
700 r[k] = r[l]; \
701 r[l] = aux;
702#define CO(a, b) \
703 aux = (a & _cobits) + (b & _cobits); \
704 auy = (aux + _ctwist_cw) >> 2U; \
705 auz = (aux + auy) & _cobits2; \
706 a = (a & _pbits) | auz;
707#define CO4(r, i, j, k, l) \
708 CO(r[i], _ctwist_cw) \
709 CO(r[j], _ctwist_cw) \
710 CO(r[k], _ctwist_ccw) \
711 CO(r[l], _ctwist_ccw)
712#define EO4(r, i, j, k, l) \
713 r[i] ^= _eobit; \
714 r[j] ^= _eobit; \
715 r[k] ^= _eobit; \
716 r[l] ^= _eobit;
717
718 ret = c;
719
720 switch (m) {
721 case U:
722 PERM4(ret.e, _e_uf, _e_ul, _e_ub, _e_ur)
723 PERM4(ret.c, _c_ufr, _c_ufl, _c_ubl, _c_ubr)
724
725 return ret;
726 case U2:
727 PERM22(ret.e, _e_uf, _e_ub, _e_ul, _e_ur)
728 PERM22(ret.c, _c_ufr, _c_ubl, _c_ufl, _c_ubr)
729
730 return ret;
731 case U3:
732 PERM4(ret.e, _e_uf, _e_ur, _e_ub, _e_ul)
733 PERM4(ret.c, _c_ufr, _c_ubr, _c_ubl, _c_ufl)
734
735 return ret;
736 case D:
737 PERM4(ret.e, _e_df, _e_dr, _e_db, _e_dl)
738 PERM4(ret.c, _c_dfr, _c_dbr, _c_dbl, _c_dfl)
739
740 return ret;
741 case D2:
742 PERM22(ret.e, _e_df, _e_db, _e_dr, _e_dl)
743 PERM22(ret.c, _c_dfr, _c_dbl, _c_dbr, _c_dfl)
744
745 return ret;
746 case D3:
747 PERM4(ret.e, _e_df, _e_dl, _e_db, _e_dr)
748 PERM4(ret.c, _c_dfr, _c_dfl, _c_dbl, _c_dbr)
749
750 return ret;
751 case R:
752 PERM4(ret.e, _e_ur, _e_br, _e_dr, _e_fr)
753 PERM4(ret.c, _c_ufr, _c_ubr, _c_dbr, _c_dfr)
754
755 CO4(ret.c, _c_ubr, _c_dfr, _c_ufr, _c_dbr)
756
757 return ret;
758 case R2:
759 PERM22(ret.e, _e_ur, _e_dr, _e_fr, _e_br)
760 PERM22(ret.c, _c_ufr, _c_dbr, _c_ubr, _c_dfr)
761
762 return ret;
763 case R3:
764 PERM4(ret.e, _e_ur, _e_fr, _e_dr, _e_br)
765 PERM4(ret.c, _c_ufr, _c_dfr, _c_dbr, _c_ubr)
766
767 CO4(ret.c, _c_ubr, _c_dfr, _c_ufr, _c_dbr)
768
769 return ret;
770 case L:
771 PERM4(ret.e, _e_ul, _e_fl, _e_dl, _e_bl)
772 PERM4(ret.c, _c_ufl, _c_dfl, _c_dbl, _c_ubl)
773
774 CO4(ret.c, _c_ufl, _c_dbl, _c_dfl, _c_ubl)
775
776 return ret;
777 case L2:
778 PERM22(ret.e, _e_ul, _e_dl, _e_fl, _e_bl)
779 PERM22(ret.c, _c_ufl, _c_dbl, _c_ubl, _c_dfl)
780
781 return ret;
782 case L3:
783 PERM4(ret.e, _e_ul, _e_bl, _e_dl, _e_fl)
784 PERM4(ret.c, _c_ufl, _c_ubl, _c_dbl, _c_dfl)
785
786 CO4(ret.c, _c_ufl, _c_dbl, _c_dfl, _c_ubl)
787
788 return ret;
789 case F:
790 PERM4(ret.e, _e_uf, _e_fr, _e_df, _e_fl)
791 PERM4(ret.c, _c_ufr, _c_dfr, _c_dfl, _c_ufl)
792
793 EO4(ret.e, _e_uf, _e_fr, _e_df, _e_fl)
794 CO4(ret.c, _c_ufr, _c_dfl, _c_dfr, _c_ufl)
795
796 return ret;
797 case F2:
798 PERM22(ret.e, _e_uf, _e_df, _e_fr, _e_fl)
799 PERM22(ret.c, _c_ufr, _c_dfl, _c_ufl, _c_dfr)
800
801 return ret;
802 case F3:
803 PERM4(ret.e, _e_uf, _e_fl, _e_df, _e_fr)
804 PERM4(ret.c, _c_ufr, _c_ufl, _c_dfl, _c_dfr)
805
806 EO4(ret.e, _e_uf, _e_fr, _e_df, _e_fl)
807 CO4(ret.c, _c_ufr, _c_dfl, _c_dfr, _c_ufl)
808
809 return ret;
810 case B:
811 PERM4(ret.e, _e_ub, _e_bl, _e_db, _e_br)
812 PERM4(ret.c, _c_ubr, _c_ubl, _c_dbl, _c_dbr)
813
814 EO4(ret.e, _e_ub, _e_br, _e_db, _e_bl)
815 CO4(ret.c, _c_ubl, _c_dbr, _c_dbl, _c_ubr)
816
817 return ret;
818 case B2:
819 PERM22(ret.e, _e_ub, _e_db, _e_br, _e_bl)
820 PERM22(ret.c, _c_ubr, _c_dbl, _c_ubl, _c_dbr)
821
822 return ret;
823 case B3:
824 PERM4(ret.e, _e_ub, _e_br, _e_db, _e_bl)
825 PERM4(ret.c, _c_ubr, _c_dbr, _c_dbl, _c_ubl)
826
827 EO4(ret.e, _e_ub, _e_br, _e_db, _e_bl)
828 CO4(ret.c, _c_ubl, _c_dbr, _c_dbl, _c_ubr)
829
830 return ret;
831 default:
832 goto move_unknown;
833 }
834
835move_inconsistent:
836 fprintf(stderr, "move error, inconsistent cube\n");
837 goto move_error;
838move_unknown:
839 fprintf(stderr, "mover error, unknown move\n");
840 goto move_error;
841move_error:
842 return errorcube;
843}
844
845cube_t
846inverse(cube_t c)
847{
848 uint8_t i, piece, orien;
849 cube_t ret = {0};
850
851#ifdef DEBUG
852 if (!isconsistent(c))
853 goto inverse_inconsistent;
854#endif
855
856 for (i = 0; i < 12; i++) {
857 piece = c.e[i & _pbits];
858 orien = piece & _eobit;
859 ret.e[piece & _pbits] = i | orien;
860 }
861
862 for (i = 0; i < 8; i++) {
863 piece = c.c[i & _pbits];
864 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
865 ret.c[piece & _pbits] = i | orien;
866 }
867
868 return ret;
869
870inverse_inconsistent:
871 fprintf(stderr, "inverse error, inconsistent cube\n");
872 return errorcube;
873}
874
875cube_t
876compose(cube_t c1, cube_t c2)
877{
878 uint8_t i, piece, orien, aux, auy;
879 cube_t ret = {0};
880
881#ifdef DEBUG
882 if (!isconsistent(c1) || !isconsistent(c2))
883 goto compose_inconsistent;
884#endif
885
886 for (i = 0; i < 12; i++) {
887 piece = c2.e[i] & _pbits;
888 orien = (c2.e[i] ^ c1.e[piece]) & _eobit;
889 ret.e[i] = (c1.e[piece] & _pbits) | orien;
890 }
891
892 for (i = 0; i < 8; i++) {
893 piece = c2.c[i] & _pbits;
894 aux = (c2.c[i] & _cobits) + (c1.c[piece] & _cobits);
895 auy = (aux + _ctwist_cw) >> 2U;
896 orien = (aux + auy) & _cobits2;
897 ret.c[i] = (c1.c[piece] & _pbits) | orien;
898 }
899
900 return ret;
901
902compose_inconsistent:
903 fprintf(stderr, "compose error, inconsistent cube\n");
904 return errorcube;
905}
906
907cube_t
908transform(cube_t c, trans_t t)
909{
910 return errorcube;
911}

Generated with cgit - Back to sebastiano.tronto.net