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