transform.h (10175B)
1 #define TRANS_EDGES_ROTATION(T, c) \ 2 compose_edges(compose_edges(TRANS_CUBE_ ## T, c), \ 3 TRANS_CUBE_ ## T ## _INVERSE) 4 #define TRANS_EDGES_MIRRORED(T, c) TRANS_EDGES_ROTATION(T, c) 5 6 #define TRANS_CORNERS_ROTATION(T, c) \ 7 compose_corners(compose_corners(TRANS_CUBE_ ## T, c), \ 8 TRANS_CUBE_ ## T ## _INVERSE) 9 #define TRANS_CORNERS_MIRRORED(T, c) \ 10 invertco(compose_corners( \ 11 compose_corners(TRANS_CUBE_ ## T, c), TRANS_CUBE_ ## T ## _INVERSE)) 12 13 #define TRANS_ROTATION(T, c) \ 14 compose(compose(TRANS_CUBE_ ## T, c), \ 15 TRANS_CUBE_ ## T ## _INVERSE) 16 #define TRANS_MIRRORED(T, c) \ 17 invertco(compose(compose(TRANS_CUBE_ ## T, c), \ 18 TRANS_CUBE_ ## T ## _INVERSE)) 19 20 STATIC cube_t transform_edges(cube_t, uint8_t); 21 STATIC cube_t transform_corners(cube_t, uint8_t); 22 STATIC cube_t transform(cube_t, uint8_t); 23 STATIC cube_t applytrans(cube_t, const char *); 24 STATIC_INLINE uint8_t inverse_trans(uint8_t); 25 STATIC uint8_t transform_move(uint8_t, uint8_t); 26 STATIC uint64_t symmetry_mask(cube_t); 27 28 STATIC cube_t 29 transform_edges(cube_t c, uint8_t t) 30 { 31 switch (t) { 32 case TRANS_UFr: 33 return c; 34 case TRANS_ULr: 35 return TRANS_EDGES_ROTATION(ULr, c); 36 case TRANS_UBr: 37 return TRANS_EDGES_ROTATION(UBr, c); 38 case TRANS_URr: 39 return TRANS_EDGES_ROTATION(URr, c); 40 case TRANS_DFr: 41 return TRANS_EDGES_ROTATION(DFr, c); 42 case TRANS_DLr: 43 return TRANS_EDGES_ROTATION(DLr, c); 44 case TRANS_DBr: 45 return TRANS_EDGES_ROTATION(DBr, c); 46 case TRANS_DRr: 47 return TRANS_EDGES_ROTATION(DRr, c); 48 case TRANS_RUr: 49 return TRANS_EDGES_ROTATION(RUr, c); 50 case TRANS_RFr: 51 return TRANS_EDGES_ROTATION(RFr, c); 52 case TRANS_RDr: 53 return TRANS_EDGES_ROTATION(RDr, c); 54 case TRANS_RBr: 55 return TRANS_EDGES_ROTATION(RBr, c); 56 case TRANS_LUr: 57 return TRANS_EDGES_ROTATION(LUr, c); 58 case TRANS_LFr: 59 return TRANS_EDGES_ROTATION(LFr, c); 60 case TRANS_LDr: 61 return TRANS_EDGES_ROTATION(LDr, c); 62 case TRANS_LBr: 63 return TRANS_EDGES_ROTATION(LBr, c); 64 case TRANS_FUr: 65 return TRANS_EDGES_ROTATION(FUr, c); 66 case TRANS_FRr: 67 return TRANS_EDGES_ROTATION(FRr, c); 68 case TRANS_FDr: 69 return TRANS_EDGES_ROTATION(FDr, c); 70 case TRANS_FLr: 71 return TRANS_EDGES_ROTATION(FLr, c); 72 case TRANS_BUr: 73 return TRANS_EDGES_ROTATION(BUr, c); 74 case TRANS_BRr: 75 return TRANS_EDGES_ROTATION(BRr, c); 76 case TRANS_BDr: 77 return TRANS_EDGES_ROTATION(BDr, c); 78 case TRANS_BLr: 79 return TRANS_EDGES_ROTATION(BLr, c); 80 case TRANS_UFm: 81 return TRANS_EDGES_MIRRORED(UFm, c); 82 case TRANS_ULm: 83 return TRANS_EDGES_MIRRORED(ULm, c); 84 case TRANS_UBm: 85 return TRANS_EDGES_MIRRORED(UBm, c); 86 case TRANS_URm: 87 return TRANS_EDGES_MIRRORED(URm, c); 88 case TRANS_DFm: 89 return TRANS_EDGES_MIRRORED(DFm, c); 90 case TRANS_DLm: 91 return TRANS_EDGES_MIRRORED(DLm, c); 92 case TRANS_DBm: 93 return TRANS_EDGES_MIRRORED(DBm, c); 94 case TRANS_DRm: 95 return TRANS_EDGES_MIRRORED(DRm, c); 96 case TRANS_RUm: 97 return TRANS_EDGES_MIRRORED(RUm, c); 98 case TRANS_RFm: 99 return TRANS_EDGES_MIRRORED(RFm, c); 100 case TRANS_RDm: 101 return TRANS_EDGES_MIRRORED(RDm, c); 102 case TRANS_RBm: 103 return TRANS_EDGES_MIRRORED(RBm, c); 104 case TRANS_LUm: 105 return TRANS_EDGES_MIRRORED(LUm, c); 106 case TRANS_LFm: 107 return TRANS_EDGES_MIRRORED(LFm, c); 108 case TRANS_LDm: 109 return TRANS_EDGES_MIRRORED(LDm, c); 110 case TRANS_LBm: 111 return TRANS_EDGES_MIRRORED(LBm, c); 112 case TRANS_FUm: 113 return TRANS_EDGES_MIRRORED(FUm, c); 114 case TRANS_FRm: 115 return TRANS_EDGES_MIRRORED(FRm, c); 116 case TRANS_FDm: 117 return TRANS_EDGES_MIRRORED(FDm, c); 118 case TRANS_FLm: 119 return TRANS_EDGES_MIRRORED(FLm, c); 120 case TRANS_BUm: 121 return TRANS_EDGES_MIRRORED(BUm, c); 122 case TRANS_BRm: 123 return TRANS_EDGES_MIRRORED(BRm, c); 124 case TRANS_BDm: 125 return TRANS_EDGES_MIRRORED(BDm, c); 126 case TRANS_BLm: 127 return TRANS_EDGES_MIRRORED(BLm, c); 128 default: 129 LOG("transform error, unknown transformation %" PRIu8 "\n", t); 130 return ZERO_CUBE; 131 } 132 } 133 134 STATIC cube_t 135 transform_corners(cube_t c, uint8_t t) 136 { 137 switch (t) { 138 case TRANS_UFr: 139 return c; 140 case TRANS_ULr: 141 return TRANS_CORNERS_ROTATION(ULr, c); 142 case TRANS_UBr: 143 return TRANS_CORNERS_ROTATION(UBr, c); 144 case TRANS_URr: 145 return TRANS_CORNERS_ROTATION(URr, c); 146 case TRANS_DFr: 147 return TRANS_CORNERS_ROTATION(DFr, c); 148 case TRANS_DLr: 149 return TRANS_CORNERS_ROTATION(DLr, c); 150 case TRANS_DBr: 151 return TRANS_CORNERS_ROTATION(DBr, c); 152 case TRANS_DRr: 153 return TRANS_CORNERS_ROTATION(DRr, c); 154 case TRANS_RUr: 155 return TRANS_CORNERS_ROTATION(RUr, c); 156 case TRANS_RFr: 157 return TRANS_CORNERS_ROTATION(RFr, c); 158 case TRANS_RDr: 159 return TRANS_CORNERS_ROTATION(RDr, c); 160 case TRANS_RBr: 161 return TRANS_CORNERS_ROTATION(RBr, c); 162 case TRANS_LUr: 163 return TRANS_CORNERS_ROTATION(LUr, c); 164 case TRANS_LFr: 165 return TRANS_CORNERS_ROTATION(LFr, c); 166 case TRANS_LDr: 167 return TRANS_CORNERS_ROTATION(LDr, c); 168 case TRANS_LBr: 169 return TRANS_CORNERS_ROTATION(LBr, c); 170 case TRANS_FUr: 171 return TRANS_CORNERS_ROTATION(FUr, c); 172 case TRANS_FRr: 173 return TRANS_CORNERS_ROTATION(FRr, c); 174 case TRANS_FDr: 175 return TRANS_CORNERS_ROTATION(FDr, c); 176 case TRANS_FLr: 177 return TRANS_CORNERS_ROTATION(FLr, c); 178 case TRANS_BUr: 179 return TRANS_CORNERS_ROTATION(BUr, c); 180 case TRANS_BRr: 181 return TRANS_CORNERS_ROTATION(BRr, c); 182 case TRANS_BDr: 183 return TRANS_CORNERS_ROTATION(BDr, c); 184 case TRANS_BLr: 185 return TRANS_CORNERS_ROTATION(BLr, c); 186 case TRANS_UFm: 187 return TRANS_CORNERS_MIRRORED(UFm, c); 188 case TRANS_ULm: 189 return TRANS_CORNERS_MIRRORED(ULm, c); 190 case TRANS_UBm: 191 return TRANS_CORNERS_MIRRORED(UBm, c); 192 case TRANS_URm: 193 return TRANS_CORNERS_MIRRORED(URm, c); 194 case TRANS_DFm: 195 return TRANS_CORNERS_MIRRORED(DFm, c); 196 case TRANS_DLm: 197 return TRANS_CORNERS_MIRRORED(DLm, c); 198 case TRANS_DBm: 199 return TRANS_CORNERS_MIRRORED(DBm, c); 200 case TRANS_DRm: 201 return TRANS_CORNERS_MIRRORED(DRm, c); 202 case TRANS_RUm: 203 return TRANS_CORNERS_MIRRORED(RUm, c); 204 case TRANS_RFm: 205 return TRANS_CORNERS_MIRRORED(RFm, c); 206 case TRANS_RDm: 207 return TRANS_CORNERS_MIRRORED(RDm, c); 208 case TRANS_RBm: 209 return TRANS_CORNERS_MIRRORED(RBm, c); 210 case TRANS_LUm: 211 return TRANS_CORNERS_MIRRORED(LUm, c); 212 case TRANS_LFm: 213 return TRANS_CORNERS_MIRRORED(LFm, c); 214 case TRANS_LDm: 215 return TRANS_CORNERS_MIRRORED(LDm, c); 216 case TRANS_LBm: 217 return TRANS_CORNERS_MIRRORED(LBm, c); 218 case TRANS_FUm: 219 return TRANS_CORNERS_MIRRORED(FUm, c); 220 case TRANS_FRm: 221 return TRANS_CORNERS_MIRRORED(FRm, c); 222 case TRANS_FDm: 223 return TRANS_CORNERS_MIRRORED(FDm, c); 224 case TRANS_FLm: 225 return TRANS_CORNERS_MIRRORED(FLm, c); 226 case TRANS_BUm: 227 return TRANS_CORNERS_MIRRORED(BUm, c); 228 case TRANS_BRm: 229 return TRANS_CORNERS_MIRRORED(BRm, c); 230 case TRANS_BDm: 231 return TRANS_CORNERS_MIRRORED(BDm, c); 232 case TRANS_BLm: 233 return TRANS_CORNERS_MIRRORED(BLm, c); 234 default: 235 LOG("transform error: unknown transformation %" PRIu8 "\n", t); 236 return ZERO_CUBE; 237 } 238 } 239 240 STATIC cube_t 241 transform(cube_t c, uint8_t t) 242 { 243 switch (t) { 244 case TRANS_UFr: 245 return c; 246 case TRANS_ULr: 247 return TRANS_ROTATION(ULr, c); 248 case TRANS_UBr: 249 return TRANS_ROTATION(UBr, c); 250 case TRANS_URr: 251 return TRANS_ROTATION(URr, c); 252 case TRANS_DFr: 253 return TRANS_ROTATION(DFr, c); 254 case TRANS_DLr: 255 return TRANS_ROTATION(DLr, c); 256 case TRANS_DBr: 257 return TRANS_ROTATION(DBr, c); 258 case TRANS_DRr: 259 return TRANS_ROTATION(DRr, c); 260 case TRANS_RUr: 261 return TRANS_ROTATION(RUr, c); 262 case TRANS_RFr: 263 return TRANS_ROTATION(RFr, c); 264 case TRANS_RDr: 265 return TRANS_ROTATION(RDr, c); 266 case TRANS_RBr: 267 return TRANS_ROTATION(RBr, c); 268 case TRANS_LUr: 269 return TRANS_ROTATION(LUr, c); 270 case TRANS_LFr: 271 return TRANS_ROTATION(LFr, c); 272 case TRANS_LDr: 273 return TRANS_ROTATION(LDr, c); 274 case TRANS_LBr: 275 return TRANS_ROTATION(LBr, c); 276 case TRANS_FUr: 277 return TRANS_ROTATION(FUr, c); 278 case TRANS_FRr: 279 return TRANS_ROTATION(FRr, c); 280 case TRANS_FDr: 281 return TRANS_ROTATION(FDr, c); 282 case TRANS_FLr: 283 return TRANS_ROTATION(FLr, c); 284 case TRANS_BUr: 285 return TRANS_ROTATION(BUr, c); 286 case TRANS_BRr: 287 return TRANS_ROTATION(BRr, c); 288 case TRANS_BDr: 289 return TRANS_ROTATION(BDr, c); 290 case TRANS_BLr: 291 return TRANS_ROTATION(BLr, c); 292 case TRANS_UFm: 293 return TRANS_MIRRORED(UFm, c); 294 case TRANS_ULm: 295 return TRANS_MIRRORED(ULm, c); 296 case TRANS_UBm: 297 return TRANS_MIRRORED(UBm, c); 298 case TRANS_URm: 299 return TRANS_MIRRORED(URm, c); 300 case TRANS_DFm: 301 return TRANS_MIRRORED(DFm, c); 302 case TRANS_DLm: 303 return TRANS_MIRRORED(DLm, c); 304 case TRANS_DBm: 305 return TRANS_MIRRORED(DBm, c); 306 case TRANS_DRm: 307 return TRANS_MIRRORED(DRm, c); 308 case TRANS_RUm: 309 return TRANS_MIRRORED(RUm, c); 310 case TRANS_RFm: 311 return TRANS_MIRRORED(RFm, c); 312 case TRANS_RDm: 313 return TRANS_MIRRORED(RDm, c); 314 case TRANS_RBm: 315 return TRANS_MIRRORED(RBm, c); 316 case TRANS_LUm: 317 return TRANS_MIRRORED(LUm, c); 318 case TRANS_LFm: 319 return TRANS_MIRRORED(LFm, c); 320 case TRANS_LDm: 321 return TRANS_MIRRORED(LDm, c); 322 case TRANS_LBm: 323 return TRANS_MIRRORED(LBm, c); 324 case TRANS_FUm: 325 return TRANS_MIRRORED(FUm, c); 326 case TRANS_FRm: 327 return TRANS_MIRRORED(FRm, c); 328 case TRANS_FDm: 329 return TRANS_MIRRORED(FDm, c); 330 case TRANS_FLm: 331 return TRANS_MIRRORED(FLm, c); 332 case TRANS_BUm: 333 return TRANS_MIRRORED(BUm, c); 334 case TRANS_BRm: 335 return TRANS_MIRRORED(BRm, c); 336 case TRANS_BDm: 337 return TRANS_MIRRORED(BDm, c); 338 case TRANS_BLm: 339 return TRANS_MIRRORED(BLm, c); 340 default: 341 return ZERO_CUBE; 342 } 343 } 344 345 STATIC cube_t 346 applytrans(cube_t cube, const char *buf) 347 { 348 uint8_t t; 349 350 DBG_ASSERT(isconsistent(cube), ZERO_CUBE, 351 "transformation error: inconsistent cube\n"); 352 353 t = readtrans(buf); 354 355 if (t == UINT8_ERROR) 356 LOG("Unknown transformation '%s'\n", buf); 357 358 return transform(cube, t); 359 } 360 361 STATIC_INLINE uint8_t 362 inverse_trans(uint8_t t) 363 { 364 return inverse_trans_table[t]; 365 } 366 367 STATIC uint8_t 368 transform_move(uint8_t m, uint8_t t) 369 { 370 uint8_t a, base, modifier; 371 372 a = moveaxis(m); 373 base = trans_move_table[t][a]; 374 if (movebase(m) != 2 * a) 375 base = moveopposite(base); 376 377 modifier = m % 3; 378 if (t >= TRANS_UFm) 379 modifier = 2 - modifier; 380 381 return base + modifier; 382 } 383 384 STATIC uint64_t 385 symmetry_mask(cube_t cube) 386 { 387 uint64_t t, ret; 388 cube_t transformed; 389 390 for (t = 0, ret = 0; t < NTRANS; t++) { 391 transformed = transform(cube, t); 392 ret |= ((uint64_t)equal(cube, transformed)) << t; 393 } 394 395 return ret; 396 }