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