aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/constants.h76
-rw-r--r--src/core/core.h1
-rw-r--r--src/core/cube.h8
-rw-r--r--src/core/moves.h84
-rw-r--r--src/core/oriented_cube.h78
5 files changed, 166 insertions, 81 deletions
diff --git a/src/core/constants.h b/src/core/constants.h
index 2908f28..fb1450e 100644
--- a/src/core/constants.h
+++ b/src/core/constants.h
@@ -348,22 +348,22 @@
348#define NMOVES_EXTENDED (1+MOVE_z3) 348#define NMOVES_EXTENDED (1+MOVE_z3)
349#define NTRANS (1+TRANS_BLm) 349#define NTRANS (1+TRANS_BLm)
350 350
351#define MM_ALLMOVES UINT32_C(0x3FFFF) 351#define MM_SINGLE(m) (UINT64_C(1) << (uint64_t)(m))
352#define MM_NOHALFTURNS UINT32_C(0x2DB6D) 352#define MM18_ALLMOVES UINT64_C(0x3FFFF)
353#define MM_SINGLE(m) (UINT32_C(1) << (uint32_t)(m)) 353#define MM18_NOHALFTURNS UINT64_C(0x2DB6D)
354#define MM_FACE(m) (UINT32_C(7) << (uint32_t)(m)) 354#define MM18_FACE(m) (UINT64_C(7) << (uint64_t)(m))
355#define MM_EO (\ 355#define MM18_EO (\
356 MM_FACE(MOVE_U) | MM_FACE(MOVE_D) |\ 356 MM18_FACE(MOVE_U) | MM18_FACE(MOVE_D) |\
357 MM_FACE(MOVE_R) | MM_FACE(MOVE_L) |\ 357 MM18_FACE(MOVE_R) | MM18_FACE(MOVE_L) |\
358 MM_SINGLE(MOVE_F2) | MM_SINGLE(MOVE_B2)) 358 MM_SINGLE(MOVE_F2) | MM_SINGLE(MOVE_B2))
359#define MM_DR (\ 359#define MM18_DR (\
360 MM_FACE(MOVE_U) | MM_FACE(MOVE_D) |\ 360 MM18_FACE(MOVE_U) | MM18_FACE(MOVE_D) |\
361 MM_SINGLE(MOVE_R2) | MM_SINGLE(MOVE_L2) |\ 361 MM_SINGLE(MOVE_R2) | MM_SINGLE(MOVE_L2) |\
362 MM_SINGLE(MOVE_F2) | MM_SINGLE(MOVE_B2)) 362 MM_SINGLE(MOVE_F2) | MM_SINGLE(MOVE_B2))
363#define MM_HTR (MM_ALLMOVES & ~MM_NOHALFTURNS) 363#define MM18_HTR (MM18_ALLMOVES & ~MM18_NOHALFTURNS)
364 364
365#define TM_ALLTRANS UINT64_C(0xFFFFFFFFFFFF)
366#define TM_SINGLE(t) (UINT64_C(1) << (uint64_t)(t)) 365#define TM_SINGLE(t) (UINT64_C(1) << (uint64_t)(t))
366#define TM_ALLTRANS UINT64_C(0xFFFFFFFFFFFF)
367#define TM_UDRLFIX (\ 367#define TM_UDRLFIX (\
368 TM_SINGLE(TRANS_UFr) | TM_SINGLE(TRANS_UBr) | TM_SINGLE(TRANS_UFm) | \ 368 TM_SINGLE(TRANS_UFr) | TM_SINGLE(TRANS_UBr) | TM_SINGLE(TRANS_UFm) | \
369 TM_SINGLE(TRANS_UBm) | TM_SINGLE(TRANS_DFr) | TM_SINGLE(TRANS_DBr) | \ 369 TM_SINGLE(TRANS_UBm) | TM_SINGLE(TRANS_DFr) | TM_SINGLE(TRANS_DBr) | \
@@ -423,13 +423,26 @@
423#define ORIENTATION_BU UINT8_C(22) 423#define ORIENTATION_BU UINT8_C(22)
424#define ORIENTATION_BL UINT8_C(23) 424#define ORIENTATION_BL UINT8_C(23)
425 425
426STATIC const uint32_t allowedmask[] = { 426/* This is only meant to work for the 18 base moves, for now */
427 UINT32_C(0x3FFF8), 427STATIC const uint64_t allowedmask[] = {
428 UINT32_C(0x3FFC0), 428 [MOVE_U / 3] = UINT64_C(0x3FFF8),
429 UINT32_C(0x3FE3F), 429 [MOVE_D / 3] = UINT64_C(0x3FFC0),
430 UINT32_C(0x3F03F), 430 [MOVE_R / 3] = UINT64_C(0x3FE3F),
431 UINT32_C(0x38FFF), 431 [MOVE_L / 3] = UINT64_C(0x3F03F),
432 UINT32_C(0x00FFF) 432 [MOVE_F / 3] = UINT64_C(0x38FFF),
433 [MOVE_B / 3] = UINT64_C(0x00FFF),
434 [MOVE_Uw / 3] = 0,
435 [MOVE_Dw / 3] = 0,
436 [MOVE_Rw / 3] = 0,
437 [MOVE_Lw / 3] = 0,
438 [MOVE_Fw / 3] = 0,
439 [MOVE_Bw / 3] = 0,
440 [MOVE_M / 3] = 0,
441 [MOVE_S / 3] = 0,
442 [MOVE_E / 3] = 0,
443 [MOVE_x / 3] = 0,
444 [MOVE_y / 3] = 0,
445 [MOVE_z / 3] = 0,
433}; 446};
434 447
435STATIC const char *cornerstr[] = { 448STATIC const char *cornerstr[] = {
@@ -682,6 +695,33 @@ STATIC uint8_t trans_move_table[][3] = {
682 [TRANS_BLm] = { MOVE_B, MOVE_U, MOVE_R }, 695 [TRANS_BLm] = { MOVE_B, MOVE_U, MOVE_R },
683}; 696};
684 697
698STATIC uint8_t orientation_moves[][3] = {
699 [ORIENTATION_UF] = { UINT8_MAX },
700 [ORIENTATION_UR] = { MOVE_y, UINT8_MAX },
701 [ORIENTATION_UB] = { MOVE_y2, UINT8_MAX },
702 [ORIENTATION_UL] = { MOVE_y3, UINT8_MAX },
703 [ORIENTATION_DF] = { MOVE_z2, UINT8_MAX },
704 [ORIENTATION_DR] = { MOVE_y, MOVE_z2, UINT8_MAX },
705 [ORIENTATION_DB] = { MOVE_y2, MOVE_z2, UINT8_MAX },
706 [ORIENTATION_DL] = { MOVE_y3, MOVE_z2, UINT8_MAX },
707 [ORIENTATION_RF] = { MOVE_z3, UINT8_MAX },
708 [ORIENTATION_RD] = { MOVE_z3, MOVE_y, UINT8_MAX },
709 [ORIENTATION_RB] = { MOVE_z3, MOVE_y2, UINT8_MAX },
710 [ORIENTATION_RU] = { MOVE_z3, MOVE_y3, UINT8_MAX },
711 [ORIENTATION_LF] = { MOVE_z, UINT8_MAX },
712 [ORIENTATION_LD] = { MOVE_z, MOVE_y3, UINT8_MAX },
713 [ORIENTATION_LB] = { MOVE_z, MOVE_y2, UINT8_MAX },
714 [ORIENTATION_LU] = { MOVE_z, MOVE_y, UINT8_MAX },
715 [ORIENTATION_FD] = { MOVE_x, UINT8_MAX },
716 [ORIENTATION_FR] = { MOVE_x, MOVE_y, UINT8_MAX },
717 [ORIENTATION_FU] = { MOVE_x, MOVE_y2, UINT8_MAX },
718 [ORIENTATION_FL] = { MOVE_x, MOVE_y3, UINT8_MAX },
719 [ORIENTATION_BD] = { MOVE_x3, MOVE_y2, UINT8_MAX },
720 [ORIENTATION_BR] = { MOVE_x3, MOVE_y, UINT8_MAX },
721 [ORIENTATION_BU] = { MOVE_x3, UINT8_MAX },
722 [ORIENTATION_BL] = { MOVE_x3, MOVE_y3, UINT8_MAX },
723};
724
685STATIC uint8_t orientation_transition_table[][3] = { 725STATIC uint8_t orientation_transition_table[][3] = {
686 [ORIENTATION_UF] = { ORIENTATION_FD, ORIENTATION_UR, ORIENTATION_LF }, 726 [ORIENTATION_UF] = { ORIENTATION_FD, ORIENTATION_UR, ORIENTATION_LF },
687 [ORIENTATION_UR] = { ORIENTATION_RD, ORIENTATION_UB, ORIENTATION_FR }, 727 [ORIENTATION_UR] = { ORIENTATION_RD, ORIENTATION_UB, ORIENTATION_FR },
diff --git a/src/core/core.h b/src/core/core.h
index b56106e..5e0faaa 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -3,3 +3,4 @@
3#include "cube.h" 3#include "cube.h"
4#include "moves.h" 4#include "moves.h"
5#include "transform.h" 5#include "transform.h"
6#include "oriented_cube.h"
diff --git a/src/core/cube.h b/src/core/cube.h
index 88e1ca9..842ec59 100644
--- a/src/core/cube.h
+++ b/src/core/cube.h
@@ -1,4 +1,3 @@
1STATIC oriented_cube_t solvedcube(void);
2STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); 1STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
3STATIC bool isconsistent(oriented_cube_t); 2STATIC bool isconsistent(oriented_cube_t);
4STATIC bool issolvable(oriented_cube_t); 3STATIC bool issolvable(oriented_cube_t);
@@ -20,13 +19,6 @@ STATIC uint8_t b32tocorner(char);
20STATIC char edgetob32(uint8_t); 19STATIC char edgetob32(uint8_t);
21STATIC char cornertob32(uint8_t); 20STATIC char cornertob32(uint8_t);
22 21
23/* This is used only in tests, use SOLVED_ORIENTED_CUBE everywhere else */
24STATIC oriented_cube_t
25solvedcube(void)
26{
27 return SOLVED_ORIENTED_CUBE;
28}
29
30STATIC cube_t 22STATIC cube_t
31cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) 23cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
32{ 24{
diff --git a/src/core/moves.h b/src/core/moves.h
index dc580be..008e928 100644
--- a/src/core/moves.h
+++ b/src/core/moves.h
@@ -2,7 +2,8 @@
2#define PREMOVE(M, c) compose(MOVE_CUBE_ ## M, c) 2#define PREMOVE(M, c) compose(MOVE_CUBE_ ## M, c)
3 3
4STATIC uint8_t readmove(char); 4STATIC uint8_t readmove(char);
5STATIC int64_t readmoves(const char *, size_t n, uint8_t [n]); 5STATIC int64_t readmoves(const char *,
6 size_t n, size_t m, uint64_t *, uint64_t *, uint8_t [n], uint8_t [m]);
6STATIC int64_t countmoves(const char *); 7STATIC int64_t countmoves(const char *);
7STATIC uint8_t readmodifier(char); 8STATIC uint8_t readmodifier(char);
8STATIC int64_t writemoves(size_t n, const uint8_t [n], size_t m, char [m]); 9STATIC int64_t writemoves(size_t n, const uint8_t [n], size_t m, char [m]);
@@ -21,14 +22,11 @@ STATIC_INLINE uint8_t movefollow(uint8_t);
21STATIC uint8_t transform_move(uint8_t, uint8_t); 22STATIC uint8_t transform_move(uint8_t, uint8_t);
22 23
23STATIC cube_t move(cube_t, uint8_t); 24STATIC cube_t move(cube_t, uint8_t);
24STATIC oriented_cube_t move_extended(oriented_cube_t, uint8_t);
25STATIC cube_t premove(cube_t, uint8_t); 25STATIC cube_t premove(cube_t, uint8_t);
26STATIC uint8_t inverse_move(uint8_t); 26STATIC uint8_t inverse_move(uint8_t);
27STATIC void sortparallel_moves(size_t n, uint8_t [n]); 27STATIC void sortparallel_moves(size_t n, uint8_t [n]);
28STATIC bool are_lastmoves_singlecw(size_t n, const uint8_t [n]); 28STATIC bool are_lastmoves_singlecw(size_t n, const uint8_t [n]);
29 29
30STATIC oriented_cube_t applymoves(oriented_cube_t, const char *);
31
32#define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ 30#define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \
33 RET_ERROR, ARG_ACTION) \ 31 RET_ERROR, ARG_ACTION) \
34 const char *VAR_B; \ 32 const char *VAR_B; \
@@ -118,14 +116,34 @@ readmodifier(char c)
118} 116}
119 117
120STATIC int64_t 118STATIC int64_t
121readmoves(const char *buf, size_t n, uint8_t ret[n]) 119readmoves(
120 const char *buf,
121 size_t nsize,
122 size_t invsize,
123 uint64_t *n,
124 uint64_t *i,
125 uint8_t normal[nsize],
126 uint8_t inverse[invsize]
127)
122{ 128{
123// TODO: modify to accept NISS
124 uint8_t m; 129 uint8_t m;
125 uint64_t c; 130 uint64_t c;
126 131
127 FOREACH_READMOVE(buf, m, c, n, NISSY_ERROR_INVALID_MOVES, 132 *n = *i = 0;
128 ret[c] = m; 133 FOREACH_READMOVE(buf, m, c, nsize+invsize, NISSY_ERROR_INVALID_MOVES,
134 if (!VAR_IN_PARENTHESES) {
135 if (*n >= nsize-1) {
136 LOG("Error in readmoves: normal buffer\n");
137 return NISSY_ERROR_BUFFER_SIZE;
138 }
139 normal[(*n)++] = m;
140 } else {
141 if (*i >= invsize-1) {
142 LOG("Error in readmoves: inverse buffer\n");
143 return NISSY_ERROR_BUFFER_SIZE;
144 }
145 inverse[(*i)++] = m;
146 }
129 ) 147 )
130 148
131 return (int64_t)c; 149 return (int64_t)c;
@@ -188,9 +206,7 @@ writemoves_error:
188STATIC_INLINE bool 206STATIC_INLINE bool
189allowednextmove(uint8_t m1, uint8_t m2) 207allowednextmove(uint8_t m1, uint8_t m2)
190{ 208{
191// TODO: adjust allowedmask 209 return allowedmask[movebase(m1)] & MM_SINGLE(m2);
192// TODO: movemask is now 64 bits
193 return allowedmask[movebase(m1)] & (UINT32_C(1) << m2);
194} 210}
195 211
196STATIC bool 212STATIC bool
@@ -226,9 +242,7 @@ isbase(uint8_t move)
226STATIC_INLINE bool 242STATIC_INLINE bool
227parallel(uint8_t m1, uint8_t m2) 243parallel(uint8_t m1, uint8_t m2)
228{ 244{
229// TODO add unit tests 245 return moveaxis(movefollow(m1)) == moveaxis(movefollow(m2));
230//TODO fix the logic (maybe use moveaxis(movefollow)), then remove comment
231 return moveaxis(m1) == moveaxis(m2);
232} 246}
233 247
234STATIC_INLINE uint8_t 248STATIC_INLINE uint8_t
@@ -249,7 +263,6 @@ inverse_reorient_move(uint8_t m, uint8_t or)
249 return transform_move(m, inverse_trans_table[orientation_trans[or]]); 263 return transform_move(m, inverse_trans_table[orientation_trans[or]]);
250} 264}
251 265
252/* This is currently unused, but it may turn out to be useful at some point */
253STATIC_INLINE uint8_t 266STATIC_INLINE uint8_t
254movefollow(uint8_t move) 267movefollow(uint8_t move)
255{ 268{
@@ -351,27 +364,6 @@ transform_move(uint8_t m, uint8_t t)
351 return base + modifier; 364 return base + modifier;
352} 365}
353 366
354STATIC oriented_cube_t
355move_extended(oriented_cube_t c, uint8_t m)
356{
357 int i;
358 equivalent_moves_t eqm;
359 oriented_cube_t ret;
360
361 eqm = equivalent_moves_table[m];
362 ret = c;
363
364 for (i = 0; eqm.move[i] != UINT8_MAX; i++)
365 ret.cube = move(
366 ret.cube, reorient_move(eqm.move[i], ret.orientation));
367
368 for (i = 0; eqm.rotation[i] != UINT8_MAX; i++)
369 ret.orientation = orientation_transition_table[
370 ret.orientation][eqm.rotation[i]];
371
372 return ret;
373}
374
375/* Applies the INVERSE of m BEFORE the scramble corresponding to c */ 367/* Applies the INVERSE of m BEFORE the scramble corresponding to c */
376STATIC cube_t 368STATIC cube_t
377premove(cube_t c, uint8_t m) 369premove(cube_t c, uint8_t m)
@@ -428,15 +420,13 @@ inverse_move(uint8_t m)
428STATIC void 420STATIC void
429sortparallel_moves(size_t n, uint8_t moves[n]) 421sortparallel_moves(size_t n, uint8_t moves[n])
430{ 422{
431// TODO: fix for wide moves...
432 uint8_t i; 423 uint8_t i;
433 424
434 if (n < 2) 425 if (n < 2)
435 return; 426 return;
436 427
437 for (i = 0; i < n-1; i++) 428 for (i = 0; i < n-1; i++)
438 if (moveaxis(moves[i]) == moveaxis(moves[i+1]) && 429 if (parallel(moves[i], moves[i+1]) && moves[i] > moves[i+1])
439 movebase(moves[i]) == movebase(moves[i+1]) + 1)
440 SWAP(moves[i], moves[i+1]); 430 SWAP(moves[i], moves[i+1]);
441} 431}
442 432
@@ -452,19 +442,3 @@ are_lastmoves_singlecw(size_t n, const uint8_t moves[n])
452 442
453 return isbase(moves[n-1]) && (!two || isbase(moves[n-2])); 443 return isbase(moves[n-1]) && (!two || isbase(moves[n-2]));
454} 444}
455
456STATIC oriented_cube_t
457applymoves(oriented_cube_t cube, const char *buf)
458{
459 int c;
460 uint8_t m;
461
462 DBG_ASSERT(isconsistent(cube), ZERO_ORIENTED_CUBE,
463 "move error: inconsistent cube\n");
464
465 FOREACH_READMOVE(buf, m, c, -1, ZERO_ORIENTED_CUBE,
466 cube = move_extended(cube, m);
467 )
468
469 return cube;
470}
diff --git a/src/core/oriented_cube.h b/src/core/oriented_cube.h
new file mode 100644
index 0000000..2c86af0
--- /dev/null
+++ b/src/core/oriented_cube.h
@@ -0,0 +1,78 @@
1STATIC oriented_cube_t solvedcube(void);
2
3STATIC oriented_cube_t move_extended(oriented_cube_t, uint8_t);
4STATIC oriented_cube_t applymoves(oriented_cube_t, const char *);
5
6/* This is used only in tests, use SOLVED_ORIENTED_CUBE everywhere else */
7STATIC oriented_cube_t
8solvedcube(void)
9{
10 return SOLVED_ORIENTED_CUBE;
11}
12
13STATIC oriented_cube_t
14compose_oriented(oriented_cube_t c, oriented_cube_t d)
15{
16 int i;
17 cube_t transformed_d;
18 oriented_cube_t ret;
19
20 transformed_d = transform(d.cube, orientation_trans[c.orientation]);
21
22 ret.cube = compose(c.cube, transformed_d);
23 ret.orientation = c.orientation;
24
25 for (i = 0; orientation_moves[d.orientation][i] != UINT8_MAX; i++)
26 ret = move_extended(ret, orientation_moves[d.orientation][i]);
27
28 return ret;
29}
30
31STATIC oriented_cube_t
32move_extended(oriented_cube_t c, uint8_t m)
33{
34 int i;
35 equivalent_moves_t eqm;
36 oriented_cube_t ret;
37
38 eqm = equivalent_moves_table[m];
39 ret = c;
40
41 for (i = 0; eqm.move[i] != UINT8_MAX; i++)
42 ret.cube = move(
43 ret.cube, reorient_move(eqm.move[i], ret.orientation));
44
45 for (i = 0; eqm.rotation[i] != UINT8_MAX; i++)
46 ret.orientation = orientation_transition_table[
47 ret.orientation][eqm.rotation[i]];
48
49 return ret;
50}
51
52STATIC oriented_cube_t
53applymoves(oriented_cube_t cube, const char *buf)
54{
55 int count;
56 uint8_t m;
57 oriented_cube_t c, cinv;
58
59 DBG_ASSERT(isconsistent(cube), ZERO_ORIENTED_CUBE,
60 "move error: inconsistent cube\n");
61
62 c = cube;
63 cinv = SOLVED_ORIENTED_CUBE;
64 FOREACH_READMOVE(buf, m, count, -1, ZERO_ORIENTED_CUBE,
65 if (!VAR_IN_PARENTHESES)
66 c = move_extended(c, m);
67 else
68 cinv = move_extended(cinv, m);
69 )
70
71 if (cinv.orientation != ORIENTATION_UF) {
72 LOG("Error applying moves: NISS part must not move centers\n");
73 return ZERO_ORIENTED_CUBE;
74 }
75
76 cinv.cube = inverse(cinv.cube);
77 return compose_oriented(cinv, c);
78}

Generated with cgit - Back to sebastiano.tronto.net