diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/cube.h | 50 | ||||
| -rw-r--r-- | src/core/moves.h | 163 |
2 files changed, 166 insertions, 47 deletions
diff --git a/src/core/cube.h b/src/core/cube.h index fe36f90..4b28103 100644 --- a/src/core/cube.h +++ b/src/core/cube.h | |||
| @@ -13,11 +13,13 @@ _static cube_t frommoves(const char *); | |||
| 13 | _static void getcube_fix(int64_t *, int64_t *, int64_t *, int64_t *); | 13 | _static void getcube_fix(int64_t *, int64_t *, int64_t *, int64_t *); |
| 14 | _static cube_t getcube(int64_t, int64_t, int64_t, int64_t); | 14 | _static cube_t getcube(int64_t, int64_t, int64_t, int64_t); |
| 15 | 15 | ||
| 16 | _static cube_t move(cube_t, uint8_t); | ||
| 17 | _static cube_t transform_edges(cube_t, uint8_t); | 16 | _static cube_t transform_edges(cube_t, uint8_t); |
| 18 | _static cube_t transform_corners(cube_t, uint8_t); | 17 | _static cube_t transform_corners(cube_t, uint8_t); |
| 19 | _static cube_t transform(cube_t, uint8_t); | 18 | _static cube_t transform(cube_t, uint8_t); |
| 20 | 19 | ||
| 20 | /* declared in moves.h */ | ||
| 21 | _static cube_t move(cube_t, uint8_t); | ||
| 22 | |||
| 21 | _static cube_t | 23 | _static cube_t |
| 22 | cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) | 24 | cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) |
| 23 | { | 25 | { |
| @@ -239,52 +241,6 @@ applytrans(cube_t cube, const char *buf) | |||
| 239 | return transform(cube, t); | 241 | return transform(cube, t); |
| 240 | } | 242 | } |
| 241 | 243 | ||
| 242 | _static cube_t | ||
| 243 | move(cube_t c, uint8_t m) | ||
| 244 | { | ||
| 245 | switch (m) { | ||
| 246 | case _move_U: | ||
| 247 | return _move(U, c); | ||
| 248 | case _move_U2: | ||
| 249 | return _move(U2, c); | ||
| 250 | case _move_U3: | ||
| 251 | return _move(U3, c); | ||
| 252 | case _move_D: | ||
| 253 | return _move(D, c); | ||
| 254 | case _move_D2: | ||
| 255 | return _move(D2, c); | ||
| 256 | case _move_D3: | ||
| 257 | return _move(D3, c); | ||
| 258 | case _move_R: | ||
| 259 | return _move(R, c); | ||
| 260 | case _move_R2: | ||
| 261 | return _move(R2, c); | ||
| 262 | case _move_R3: | ||
| 263 | return _move(R3, c); | ||
| 264 | case _move_L: | ||
| 265 | return _move(L, c); | ||
| 266 | case _move_L2: | ||
| 267 | return _move(L2, c); | ||
| 268 | case _move_L3: | ||
| 269 | return _move(L3, c); | ||
| 270 | case _move_F: | ||
| 271 | return _move(F, c); | ||
| 272 | case _move_F2: | ||
| 273 | return _move(F2, c); | ||
| 274 | case _move_F3: | ||
| 275 | return _move(F3, c); | ||
| 276 | case _move_B: | ||
| 277 | return _move(B, c); | ||
| 278 | case _move_B2: | ||
| 279 | return _move(B2, c); | ||
| 280 | case _move_B3: | ||
| 281 | return _move(B3, c); | ||
| 282 | default: | ||
| 283 | LOG("move error, unknown move\n"); | ||
| 284 | return zero; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | |||
| 288 | /* | 244 | /* |
| 289 | TODO transform is now relegated to a separated file because it is too long. | 245 | TODO transform is now relegated to a separated file because it is too long. |
| 290 | It would be nice to make it shorter without loosing performance. | 246 | It would be nice to make it shorter without loosing performance. |
diff --git a/src/core/moves.h b/src/core/moves.h index 7da6405..8f9c8f5 100644 --- a/src/core/moves.h +++ b/src/core/moves.h | |||
| @@ -1,7 +1,23 @@ | |||
| 1 | /* probably these can be placed in constants file */ | ||
| 2 | #define NORMAL 0x00 | ||
| 3 | #define INVERSE 0x01 | ||
| 4 | #define INVERSEBRANCH 0x03 | ||
| 5 | #define NORMALBRANCH 0x02 | ||
| 6 | #define ALLMOVES 0x3FFFF | ||
| 7 | #define NOHALFTURNS 0x2DB6D | ||
| 8 | |||
| 1 | _static_inline bool allowednextmove(uint8_t *, uint8_t); | 9 | _static_inline bool allowednextmove(uint8_t *, uint8_t); |
| 10 | _static uint32_t allowednextmoveH48(uint8_t *, uint8_t, uint32_t); | ||
| 11 | |||
| 2 | _static_inline uint8_t inverse_trans(uint8_t); | 12 | _static_inline uint8_t inverse_trans(uint8_t); |
| 3 | _static_inline uint8_t movebase(uint8_t); | 13 | _static_inline uint8_t movebase(uint8_t); |
| 4 | _static_inline uint8_t moveaxis(uint8_t); | 14 | _static_inline uint8_t moveaxis(uint8_t); |
| 15 | _static_inline uint32_t disable_moves(uint32_t, uint8_t); | ||
| 16 | |||
| 17 | _static cube_t move(cube_t, uint8_t); | ||
| 18 | _static cube_t premove(cube_t, uint8_t); | ||
| 19 | _static uint8_t inverse_move(uint8_t); | ||
| 20 | _static uint8_t* invertpremoves(uint8_t *, uint8_t); | ||
| 5 | 21 | ||
| 6 | _static bool | 22 | _static bool |
| 7 | allowednextmove(uint8_t *moves, uint8_t n) | 23 | allowednextmove(uint8_t *moves, uint8_t n) |
| @@ -28,6 +44,40 @@ allowednextmove(uint8_t *moves, uint8_t n) | |||
| 28 | return axis[1] != axis[2] || base[0] != base[2]; | 44 | return axis[1] != axis[2] || base[0] != base[2]; |
| 29 | } | 45 | } |
| 30 | 46 | ||
| 47 | _static_inline uint32_t | ||
| 48 | disable_moves(uint32_t current_result, uint8_t base_index) | ||
| 49 | { | ||
| 50 | return current_result & ~(7 << base_index); | ||
| 51 | } | ||
| 52 | |||
| 53 | _static uint32_t | ||
| 54 | allowednextmoveH48(uint8_t *moves, uint8_t n, uint32_t h48branch) | ||
| 55 | { | ||
| 56 | uint32_t result = ALLMOVES; | ||
| 57 | if (h48branch & NORMALBRANCH) | ||
| 58 | result &= NOHALFTURNS; | ||
| 59 | if (n < 1) | ||
| 60 | return result; | ||
| 61 | |||
| 62 | uint8_t base1 = movebase(moves[n-1]); | ||
| 63 | uint8_t axis1 = moveaxis(moves[n-1]); | ||
| 64 | |||
| 65 | result = disable_moves(result, base1 * 3); | ||
| 66 | if (base1 % 2) | ||
| 67 | result = disable_moves(result, (base1 - 1) * 3); | ||
| 68 | |||
| 69 | if (n == 1) | ||
| 70 | return result; | ||
| 71 | |||
| 72 | uint8_t base2 = movebase(moves[n-2]); | ||
| 73 | uint8_t axis2 = moveaxis(moves[n-2]); | ||
| 74 | |||
| 75 | if(axis1 == axis2) | ||
| 76 | result = disable_moves(result, base2 * 3); | ||
| 77 | |||
| 78 | return result; | ||
| 79 | } | ||
| 80 | |||
| 31 | _static_inline uint8_t | 81 | _static_inline uint8_t |
| 32 | inverse_trans(uint8_t t) | 82 | inverse_trans(uint8_t t) |
| 33 | { | 83 | { |
| @@ -45,3 +95,116 @@ moveaxis(uint8_t move) | |||
| 45 | { | 95 | { |
| 46 | return move / 6; | 96 | return move / 6; |
| 47 | } | 97 | } |
| 98 | |||
| 99 | _static cube_t | ||
| 100 | move(cube_t c, uint8_t m) | ||
| 101 | { | ||
| 102 | switch (m) { | ||
| 103 | case _move_U: | ||
| 104 | return _move(U, c); | ||
| 105 | case _move_U2: | ||
| 106 | return _move(U2, c); | ||
| 107 | case _move_U3: | ||
| 108 | return _move(U3, c); | ||
| 109 | case _move_D: | ||
| 110 | return _move(D, c); | ||
| 111 | case _move_D2: | ||
| 112 | return _move(D2, c); | ||
| 113 | case _move_D3: | ||
| 114 | return _move(D3, c); | ||
| 115 | case _move_R: | ||
| 116 | return _move(R, c); | ||
| 117 | case _move_R2: | ||
| 118 | return _move(R2, c); | ||
| 119 | case _move_R3: | ||
| 120 | return _move(R3, c); | ||
| 121 | case _move_L: | ||
| 122 | return _move(L, c); | ||
| 123 | case _move_L2: | ||
| 124 | return _move(L2, c); | ||
| 125 | case _move_L3: | ||
| 126 | return _move(L3, c); | ||
| 127 | case _move_F: | ||
| 128 | return _move(F, c); | ||
| 129 | case _move_F2: | ||
| 130 | return _move(F2, c); | ||
| 131 | case _move_F3: | ||
| 132 | return _move(F3, c); | ||
| 133 | case _move_B: | ||
| 134 | return _move(B, c); | ||
| 135 | case _move_B2: | ||
| 136 | return _move(B2, c); | ||
| 137 | case _move_B3: | ||
| 138 | return _move(B3, c); | ||
| 139 | default: | ||
| 140 | LOG("move error, unknown move\n"); | ||
| 141 | return zero; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | _static cube_t | ||
| 146 | premove(cube_t c, uint8_t m) | ||
| 147 | { | ||
| 148 | switch (m) { | ||
| 149 | case _move_U: | ||
| 150 | return _premove(U3, c); | ||
| 151 | case _move_U2: | ||
| 152 | return _premove(U2, c); | ||
| 153 | case _move_U3: | ||
| 154 | return _premove(U, c); | ||
| 155 | case _move_D: | ||
| 156 | return _premove(D3, c); | ||
| 157 | case _move_D2: | ||
| 158 | return _premove(D2, c); | ||
| 159 | case _move_D3: | ||
| 160 | return _premove(D, c); | ||
| 161 | case _move_R: | ||
| 162 | return _premove(R3, c); | ||
| 163 | case _move_R2: | ||
| 164 | return _premove(R2, c); | ||
| 165 | case _move_R3: | ||
| 166 | return _premove(R, c); | ||
| 167 | case _move_L: | ||
| 168 | return _premove(L3, c); | ||
| 169 | case _move_L2: | ||
| 170 | return _premove(L2, c); | ||
| 171 | case _move_L3: | ||
| 172 | return _premove(L, c); | ||
| 173 | case _move_F: | ||
| 174 | return _premove(F3, c); | ||
| 175 | case _move_F2: | ||
| 176 | return _premove(F2, c); | ||
| 177 | case _move_F3: | ||
| 178 | return _premove(F, c); | ||
| 179 | case _move_B: | ||
| 180 | return _premove(B3, c); | ||
| 181 | case _move_B2: | ||
| 182 | return _premove(B2, c); | ||
| 183 | case _move_B3: | ||
| 184 | return _premove(B, c); | ||
| 185 | default: | ||
| 186 | LOG("move error, unknown move\n"); | ||
| 187 | return zero; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | _static uint8_t | ||
| 192 | inverse_move(uint8_t m) | ||
| 193 | { | ||
| 194 | return m - 2 * (m % 3) + 2; | ||
| 195 | } | ||
| 196 | |||
| 197 | _static uint8_t* | ||
| 198 | invertpremoves(uint8_t *moves, uint8_t nmoves) | ||
| 199 | { | ||
| 200 | uint8_t i; | ||
| 201 | uint8_t *ret = malloc(nmoves * sizeof(uint8_t)); | ||
| 202 | |||
| 203 | for (i = 0; i < nmoves; i++) | ||
| 204 | ret[i] = inverse_move(moves[i]); | ||
| 205 | |||
| 206 | // invert elements in the array | ||
| 207 | for (i = 0; i < nmoves / 2; i++) | ||
| 208 | _swap(ret[i], ret[nmoves - i - 1]); | ||
| 209 | return ret; | ||
| 210 | } | ||
