diff options
Diffstat (limited to 'src/core/moves.h')
| -rw-r--r-- | src/core/moves.h | 84 |
1 files changed, 29 insertions, 55 deletions
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 | } | ||
