diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-04-25 10:09:22 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-04-25 10:09:22 +0200 |
| commit | 7faca28009c5efb0ba2b897b34dbdcac47a1a6f3 (patch) | |
| tree | fd507509d00d2926175c72f4c06b9158c3a331a7 /src/core | |
| parent | 17e5a9e1e2b241c67956651f87f40236467fe7d8 (diff) | |
| download | nissy-core-7faca28009c5efb0ba2b897b34dbdcac47a1a6f3.tar.gz nissy-core-7faca28009c5efb0ba2b897b34dbdcac47a1a6f3.zip | |
NISS
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/constants.h | 76 | ||||
| -rw-r--r-- | src/core/core.h | 1 | ||||
| -rw-r--r-- | src/core/cube.h | 8 | ||||
| -rw-r--r-- | src/core/moves.h | 84 | ||||
| -rw-r--r-- | src/core/oriented_cube.h | 78 |
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 | ||
| 426 | STATIC const uint32_t allowedmask[] = { | 426 | /* This is only meant to work for the 18 base moves, for now */ |
| 427 | UINT32_C(0x3FFF8), | 427 | STATIC 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 | ||
| 435 | STATIC const char *cornerstr[] = { | 448 | STATIC 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 | ||
| 698 | STATIC 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 | |||
| 685 | STATIC uint8_t orientation_transition_table[][3] = { | 725 | STATIC 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 @@ | |||
| 1 | STATIC oriented_cube_t solvedcube(void); | ||
| 2 | STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); | 1 | STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); |
| 3 | STATIC bool isconsistent(oriented_cube_t); | 2 | STATIC bool isconsistent(oriented_cube_t); |
| 4 | STATIC bool issolvable(oriented_cube_t); | 3 | STATIC bool issolvable(oriented_cube_t); |
| @@ -20,13 +19,6 @@ STATIC uint8_t b32tocorner(char); | |||
| 20 | STATIC char edgetob32(uint8_t); | 19 | STATIC char edgetob32(uint8_t); |
| 21 | STATIC char cornertob32(uint8_t); | 20 | STATIC char cornertob32(uint8_t); |
| 22 | 21 | ||
| 23 | /* This is used only in tests, use SOLVED_ORIENTED_CUBE everywhere else */ | ||
| 24 | STATIC oriented_cube_t | ||
| 25 | solvedcube(void) | ||
| 26 | { | ||
| 27 | return SOLVED_ORIENTED_CUBE; | ||
| 28 | } | ||
| 29 | |||
| 30 | STATIC cube_t | 22 | STATIC cube_t |
| 31 | cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) | 23 | cubefromarray(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 | ||
| 4 | STATIC uint8_t readmove(char); | 4 | STATIC uint8_t readmove(char); |
| 5 | STATIC int64_t readmoves(const char *, size_t n, uint8_t [n]); | 5 | STATIC int64_t readmoves(const char *, |
| 6 | size_t n, size_t m, uint64_t *, uint64_t *, uint8_t [n], uint8_t [m]); | ||
| 6 | STATIC int64_t countmoves(const char *); | 7 | STATIC int64_t countmoves(const char *); |
| 7 | STATIC uint8_t readmodifier(char); | 8 | STATIC uint8_t readmodifier(char); |
| 8 | STATIC int64_t writemoves(size_t n, const uint8_t [n], size_t m, char [m]); | 9 | STATIC 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); | |||
| 21 | STATIC uint8_t transform_move(uint8_t, uint8_t); | 22 | STATIC uint8_t transform_move(uint8_t, uint8_t); |
| 22 | 23 | ||
| 23 | STATIC cube_t move(cube_t, uint8_t); | 24 | STATIC cube_t move(cube_t, uint8_t); |
| 24 | STATIC oriented_cube_t move_extended(oriented_cube_t, uint8_t); | ||
| 25 | STATIC cube_t premove(cube_t, uint8_t); | 25 | STATIC cube_t premove(cube_t, uint8_t); |
| 26 | STATIC uint8_t inverse_move(uint8_t); | 26 | STATIC uint8_t inverse_move(uint8_t); |
| 27 | STATIC void sortparallel_moves(size_t n, uint8_t [n]); | 27 | STATIC void sortparallel_moves(size_t n, uint8_t [n]); |
| 28 | STATIC bool are_lastmoves_singlecw(size_t n, const uint8_t [n]); | 28 | STATIC bool are_lastmoves_singlecw(size_t n, const uint8_t [n]); |
| 29 | 29 | ||
| 30 | STATIC 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 | ||
| 120 | STATIC int64_t | 118 | STATIC int64_t |
| 121 | readmoves(const char *buf, size_t n, uint8_t ret[n]) | 119 | readmoves( |
| 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: | |||
| 188 | STATIC_INLINE bool | 206 | STATIC_INLINE bool |
| 189 | allowednextmove(uint8_t m1, uint8_t m2) | 207 | allowednextmove(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 | ||
| 196 | STATIC bool | 212 | STATIC bool |
| @@ -226,9 +242,7 @@ isbase(uint8_t move) | |||
| 226 | STATIC_INLINE bool | 242 | STATIC_INLINE bool |
| 227 | parallel(uint8_t m1, uint8_t m2) | 243 | parallel(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 | ||
| 234 | STATIC_INLINE uint8_t | 248 | STATIC_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 */ | ||
| 253 | STATIC_INLINE uint8_t | 266 | STATIC_INLINE uint8_t |
| 254 | movefollow(uint8_t move) | 267 | movefollow(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 | ||
| 354 | STATIC oriented_cube_t | ||
| 355 | move_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 */ |
| 376 | STATIC cube_t | 368 | STATIC cube_t |
| 377 | premove(cube_t c, uint8_t m) | 369 | premove(cube_t c, uint8_t m) |
| @@ -428,15 +420,13 @@ inverse_move(uint8_t m) | |||
| 428 | STATIC void | 420 | STATIC void |
| 429 | sortparallel_moves(size_t n, uint8_t moves[n]) | 421 | sortparallel_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 | |||
| 456 | STATIC oriented_cube_t | ||
| 457 | applymoves(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 @@ | |||
| 1 | STATIC oriented_cube_t solvedcube(void); | ||
| 2 | |||
| 3 | STATIC oriented_cube_t move_extended(oriented_cube_t, uint8_t); | ||
| 4 | STATIC oriented_cube_t applymoves(oriented_cube_t, const char *); | ||
| 5 | |||
| 6 | /* This is used only in tests, use SOLVED_ORIENTED_CUBE everywhere else */ | ||
| 7 | STATIC oriented_cube_t | ||
| 8 | solvedcube(void) | ||
| 9 | { | ||
| 10 | return SOLVED_ORIENTED_CUBE; | ||
| 11 | } | ||
| 12 | |||
| 13 | STATIC oriented_cube_t | ||
| 14 | compose_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 | |||
| 31 | STATIC oriented_cube_t | ||
| 32 | move_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 | |||
| 52 | STATIC oriented_cube_t | ||
| 53 | applymoves(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 | } | ||
