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