diff options
Diffstat (limited to 'src/core/moves.h')
| -rw-r--r-- | src/core/moves.h | 97 |
1 files changed, 92 insertions, 5 deletions
diff --git a/src/core/moves.h b/src/core/moves.h index 8ed267d..20544a3 100644 --- a/src/core/moves.h +++ b/src/core/moves.h | |||
| @@ -14,8 +14,13 @@ STATIC_INLINE uint8_t movebase(uint8_t); | |||
| 14 | STATIC_INLINE uint8_t moveaxis(uint8_t); | 14 | STATIC_INLINE uint8_t moveaxis(uint8_t); |
| 15 | STATIC_INLINE bool isbase(uint8_t); | 15 | STATIC_INLINE bool isbase(uint8_t); |
| 16 | STATIC_INLINE bool parallel(uint8_t, uint8_t); | 16 | STATIC_INLINE bool parallel(uint8_t, uint8_t); |
| 17 | STATIC_INLINE uint8_t moveopposite(uint8_t); | ||
| 18 | STATIC_INLINE uint8_t reorient_move(uint8_t, uint8_t); | ||
| 19 | STATIC_INLINE uint8_t movefollow(uint8_t); | ||
| 20 | STATIC uint8_t transform_move(uint8_t, uint8_t); | ||
| 17 | 21 | ||
| 18 | STATIC cube_t move(cube_t, uint8_t); | 22 | STATIC cube_t move(cube_t, uint8_t); |
| 23 | STATIC oriented_cube_t move_extended(oriented_cube_t, uint8_t); | ||
| 19 | STATIC cube_t premove(cube_t, uint8_t); | 24 | STATIC cube_t premove(cube_t, uint8_t); |
| 20 | STATIC uint8_t inverse_move(uint8_t); | 25 | STATIC uint8_t inverse_move(uint8_t); |
| 21 | STATIC void sortparallel_moves(size_t n, uint8_t [n]); | 26 | STATIC void sortparallel_moves(size_t n, uint8_t [n]); |
| @@ -112,14 +117,14 @@ countmoves(const char *buf) | |||
| 112 | { | 117 | { |
| 113 | uint8_t m; | 118 | uint8_t m; |
| 114 | uint64_t c; | 119 | uint64_t c; |
| 120 | int64_t count; | ||
| 115 | 121 | ||
| 122 | count = 0; | ||
| 116 | FOREACH_READMOVE(buf, m, c, INT_MAX, NISSY_ERROR_INVALID_MOVES, | 123 | FOREACH_READMOVE(buf, m, c, INT_MAX, NISSY_ERROR_INVALID_MOVES, |
| 117 | {} | 124 | count += m <= MOVE_Bw3 ? 1 : (m <= MOVE_E3 ? 2 : 0); |
| 118 | ) | 125 | ) |
| 119 | 126 | ||
| 120 | (void)m; /* Ignore "variable set but not used" warning */ | 127 | return count; |
| 121 | |||
| 122 | return (int64_t)c; | ||
| 123 | } | 128 | } |
| 124 | 129 | ||
| 125 | STATIC int64_t | 130 | STATIC int64_t |
| @@ -188,6 +193,9 @@ movebase(uint8_t move) | |||
| 188 | STATIC_INLINE uint8_t | 193 | STATIC_INLINE uint8_t |
| 189 | moveaxis(uint8_t move) | 194 | moveaxis(uint8_t move) |
| 190 | { | 195 | { |
| 196 | if (move > MOVE_B3) | ||
| 197 | return UINT8_ERROR; | ||
| 198 | |||
| 191 | return move / 6; | 199 | return move / 6; |
| 192 | } | 200 | } |
| 193 | 201 | ||
| @@ -209,6 +217,44 @@ moveopposite(uint8_t move) | |||
| 209 | return movebase(move) == 2 * moveaxis(move) ? move + 3 : move - 3; | 217 | return movebase(move) == 2 * moveaxis(move) ? move + 3 : move - 3; |
| 210 | } | 218 | } |
| 211 | 219 | ||
| 220 | STATIC_INLINE uint8_t | ||
| 221 | reorient_move(uint8_t m, uint8_t or) | ||
| 222 | { | ||
| 223 | return transform_move(m, orientation_trans[or]); | ||
| 224 | } | ||
| 225 | |||
| 226 | /* This is currently unused, but it may turn out to be useful at some point */ | ||
| 227 | STATIC_INLINE uint8_t | ||
| 228 | movefollow(uint8_t move) | ||
| 229 | { | ||
| 230 | uint8_t b, m; | ||
| 231 | |||
| 232 | if (move <= MOVE_B3) | ||
| 233 | return move; | ||
| 234 | |||
| 235 | if (move <= MOVE_Bw3) | ||
| 236 | return move - MOVE_Uw; | ||
| 237 | |||
| 238 | b = UINT8_C(3) * (move / UINT8_C(3)); | ||
| 239 | m = move - b; | ||
| 240 | switch (b) { | ||
| 241 | case MOVE_M: | ||
| 242 | return MOVE_L + m; | ||
| 243 | case MOVE_S: | ||
| 244 | return MOVE_F + m; | ||
| 245 | case MOVE_E: | ||
| 246 | return MOVE_D + m; | ||
| 247 | case MOVE_x: | ||
| 248 | return MOVE_R + m; | ||
| 249 | case MOVE_y: | ||
| 250 | return MOVE_U + m; | ||
| 251 | case MOVE_z: | ||
| 252 | return MOVE_F + m; | ||
| 253 | default: | ||
| 254 | return UINT8_ERROR; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | |||
| 212 | STATIC cube_t | 258 | STATIC cube_t |
| 213 | move(cube_t c, uint8_t m) | 259 | move(cube_t c, uint8_t m) |
| 214 | { | 260 | { |
| @@ -255,6 +301,47 @@ move(cube_t c, uint8_t m) | |||
| 255 | } | 301 | } |
| 256 | } | 302 | } |
| 257 | 303 | ||
| 304 | STATIC uint8_t | ||
| 305 | transform_move(uint8_t m, uint8_t t) | ||
| 306 | { | ||
| 307 | uint8_t a, base, modifier; | ||
| 308 | |||
| 309 | a = moveaxis(m); | ||
| 310 | if (a == UINT8_ERROR) | ||
| 311 | return UINT8_ERROR; | ||
| 312 | |||
| 313 | base = trans_move_table[t][a]; | ||
| 314 | if (movebase(m) != 2 * a) | ||
| 315 | base = moveopposite(base); | ||
| 316 | |||
| 317 | modifier = m % 3; | ||
| 318 | if (t >= TRANS_UFm) | ||
| 319 | modifier = 2 - modifier; | ||
| 320 | |||
| 321 | return base + modifier; | ||
| 322 | } | ||
| 323 | |||
| 324 | STATIC oriented_cube_t | ||
| 325 | move_extended(oriented_cube_t c, uint8_t m) | ||
| 326 | { | ||
| 327 | int i; | ||
| 328 | equivalent_moves_t eqm; | ||
| 329 | oriented_cube_t ret; | ||
| 330 | |||
| 331 | eqm = equivalent_moves_table[m]; | ||
| 332 | ret = c; | ||
| 333 | |||
| 334 | for (i = 0; eqm.move[i] != UINT8_MAX; i++) | ||
| 335 | ret.cube = move( | ||
| 336 | ret.cube, reorient_move(eqm.move[i], ret.orientation)); | ||
| 337 | |||
| 338 | for (i = 0; eqm.rotation[i] != UINT8_MAX; i++) | ||
| 339 | ret.orientation = orientation_transition_table[ | ||
| 340 | ret.orientation][eqm.rotation[i]]; | ||
| 341 | |||
| 342 | return ret; | ||
| 343 | } | ||
| 344 | |||
| 258 | /* Applies the INVERSE of m BEFORE the scramble corresponding to c */ | 345 | /* Applies the INVERSE of m BEFORE the scramble corresponding to c */ |
| 259 | STATIC cube_t | 346 | STATIC cube_t |
| 260 | premove(cube_t c, uint8_t m) | 347 | premove(cube_t c, uint8_t m) |
| @@ -345,7 +432,7 @@ applymoves(oriented_cube_t cube, const char *buf) | |||
| 345 | "move error: inconsistent cube\n"); | 432 | "move error: inconsistent cube\n"); |
| 346 | 433 | ||
| 347 | FOREACH_READMOVE(buf, m, c, -1, ZERO_ORIENTED_CUBE, | 434 | FOREACH_READMOVE(buf, m, c, -1, ZERO_ORIENTED_CUBE, |
| 348 | cube.cube = move(cube.cube, m); | 435 | cube = move_extended(cube, m); |
| 349 | ) | 436 | ) |
| 350 | 437 | ||
| 351 | return cube; | 438 | return cube; |
