h48

A prototype for an optimal Rubik's cube solver, work in progress.
git clone https://git.tronto.net/h48
Download | Log | Files | Refs | README | LICENSE

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 }