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

Generated with cgit - Back to sebastiano.tronto.net