trans.c (10747B)
1 #include "trans.h" 2 3 /* Local functions ***********************************************************/ 4 5 static bool read_ttables_file(void); 6 static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f); 7 static bool write_ttables_file(void); 8 9 /* Tables and other data *****************************************************/ 10 11 static int ep_mirror[12] = { 12 [UF] = UF, [UL] = UR, [UB] = UB, [UR] = UL, 13 [DF] = DF, [DL] = DR, [DB] = DB, [DR] = DL, 14 [FR] = FL, [FL] = FR, [BL] = BR, [BR] = BL 15 }; 16 17 static int cp_mirror[8] = { 18 [UFR] = UFL, [UFL] = UFR, [UBL] = UBR, [UBR] = UBL, 19 [DFR] = DFL, [DFL] = DFR, [DBL] = DBR, [DBR] = DBL 20 }; 21 22 static int cpos_mirror[6] = { 23 [U_center] = U_center, [D_center] = D_center, 24 [R_center] = L_center, [L_center] = R_center, 25 [F_center] = F_center, [B_center] = B_center 26 }; 27 28 static char rotation_alg_string[100][NROTATIONS] = { 29 [uf] = "", [ur] = "y", [ub] = "y2", [ul] = "y3", 30 [df] = "z2", [dr] = "y z2", [db] = "x2", [dl] = "y3 z2", 31 [rf] = "z3", [rd] = "z3 y", [rb] = "z3 y2", [ru] = "z3 y3", 32 [lf] = "z", [ld] = "z y3", [lb] = "z y2", [lu] = "z y", 33 [fu] = "x y2", [fr] = "x y", [fd] = "x", [fl] = "x y3", 34 [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3", 35 }; 36 37 static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */ 38 static int eposs_source[NTRANS]; 39 static int eposm_source[NTRANS]; 40 static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */ 41 static int eorl_source[NTRANS]; 42 static int eoud_source[NTRANS]; 43 static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */ 44 static int cofb_source[NTRANS]; 45 static int corl_source[NTRANS]; 46 47 int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8]; 48 int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8]; 49 int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8]; 50 int eo_ttable[NTRANS][POW2TO11]; 51 int cp_ttable[NTRANS][FACTORIAL8]; 52 int co_ttable[NTRANS][POW3TO7]; 53 int cpos_ttable[NTRANS][FACTORIAL6]; 54 Move moves_ttable[NTRANS][NMOVES]; 55 56 /* Local functions implementation ********************************************/ 57 58 static bool 59 read_ttables_file(void) 60 { 61 init_env(); 62 63 FILE *f; 64 char fname[strlen(tabledir)+20]; 65 int b = sizeof(int); 66 bool r = true; 67 Move m; 68 69 /* Table sizes, used for reading and writing files */ 70 uint64_t me[11] = { 71 [0] = FACTORIAL12/FACTORIAL8, 72 [1] = FACTORIAL12/FACTORIAL8, 73 [2] = FACTORIAL12/FACTORIAL8, 74 [3] = POW2TO11, 75 [4] = FACTORIAL8, 76 [5] = POW3TO7, 77 [6] = FACTORIAL6, 78 [7] = NMOVES 79 }; 80 81 strcpy(fname, tabledir); 82 strcat(fname, "/"); 83 strcat(fname, "ttables"); 84 85 if ((f = fopen(fname, "rb")) == NULL) 86 return false; 87 88 for (m = 0; m < NTRANS; m++) { 89 r = r && fread(epose_ttable[m], b, me[0], f) == me[0]; 90 r = r && fread(eposs_ttable[m], b, me[1], f) == me[1]; 91 r = r && fread(eposm_ttable[m], b, me[2], f) == me[2]; 92 r = r && fread(eo_ttable[m], b, me[3], f) == me[3]; 93 r = r && fread(cp_ttable[m], b, me[4], f) == me[4]; 94 r = r && fread(co_ttable[m], b, me[5], f) == me[5]; 95 r = r && fread(cpos_ttable[m], b, me[6], f) == me[6]; 96 r = r && fread(moves_ttable[m], b, me[7], f) == me[7]; 97 } 98 99 fclose(f); 100 return r; 101 } 102 103 static Cube 104 rotate_via_compose(Trans r, Cube c, PieceFilter f) 105 { 106 static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 107 static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 108 static CubeArray ma = { 109 .ep = ep_mirror, 110 .eofb = zero12, 111 .eorl = zero12, 112 .eoud = zero12, 113 .cp = cp_mirror, 114 .coud = zero8, 115 .corl = zero8, 116 .cofb = zero8, 117 .cpos = cpos_mirror 118 }; 119 120 Alg *inv = inverse_alg(rotation_alg(r)); 121 Cube ret = {0}; 122 123 if (r >= NROTATIONS) 124 ret = move_via_arrays(&ma, ret, f); 125 ret = apply_alg_generic(inv, ret, f, true); 126 127 ret = compose_filtered(c, ret, f); 128 129 ret = apply_alg_generic(rotation_alg(r), ret, f, true); 130 if (r >= NROTATIONS) 131 ret = move_via_arrays(&ma, ret, f); 132 133 free_alg(inv); 134 return ret; 135 } 136 137 static bool 138 write_ttables_file(void) 139 { 140 init_env(); 141 142 FILE *f; 143 char fname[strlen(tabledir)+20]; 144 bool r = true; 145 int b = sizeof(int); 146 Move m; 147 148 /* Table sizes, used for reading and writing files */ 149 uint64_t me[11] = { 150 [0] = FACTORIAL12/FACTORIAL8, 151 [1] = FACTORIAL12/FACTORIAL8, 152 [2] = FACTORIAL12/FACTORIAL8, 153 [3] = POW2TO11, 154 [4] = FACTORIAL8, 155 [5] = POW3TO7, 156 [6] = FACTORIAL6, 157 [7] = NMOVES 158 }; 159 160 strcpy(fname, tabledir); 161 strcat(fname, "/ttables"); 162 163 if ((f = fopen(fname, "wb")) == NULL) 164 return false; 165 166 for (m = 0; m < NTRANS; m++) { 167 r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0]; 168 r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1]; 169 r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2]; 170 r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3]; 171 r = r && fwrite(cp_ttable[m], b, me[4], f) == me[4]; 172 r = r && fwrite(co_ttable[m], b, me[5], f) == me[5]; 173 r = r && fwrite(cpos_ttable[m], b, me[6], f) == me[6]; 174 r = r && fwrite(moves_ttable[m], b, me[7], f) == me[7]; 175 } 176 177 fclose(f); 178 return r; 179 } 180 181 /* Public functions **********************************************************/ 182 183 Cube 184 apply_trans(Trans t, Cube cube) 185 { 186 /*init_trans();*/ 187 188 int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm }; 189 int aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb }; 190 int aux_co[3] = { cube.coud, cube.corl, cube.cofb }; 191 192 return (Cube) { 193 .epose = epose_ttable[t][aux_epos[epose_source[t]]], 194 .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]], 195 .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]], 196 .eofb = eo_ttable[t][aux_eo[eofb_source[t]]], 197 .eorl = eo_ttable[t][aux_eo[eorl_source[t]]], 198 .eoud = eo_ttable[t][aux_eo[eoud_source[t]]], 199 .coud = co_ttable[t][aux_co[coud_source[t]]], 200 .corl = co_ttable[t][aux_co[corl_source[t]]], 201 .cofb = co_ttable[t][aux_co[cofb_source[t]]], 202 .cp = cp_ttable[t][cube.cp], 203 .cpos = cpos_ttable[t][cube.cpos] 204 }; 205 } 206 207 Trans 208 inverse_trans(Trans t) 209 { 210 static Trans inverse_trans_aux[NTRANS] = { 211 [uf] = uf, [ur] = ul, [ul] = ur, [ub] = ub, 212 [df] = df, [dr] = dr, [dl] = dl, [db] = db, 213 [rf] = lf, [rd] = bl, [rb] = rb, [ru] = fr, 214 [lf] = rf, [ld] = br, [lb] = lb, [lu] = fl, 215 [fu] = fu, [fr] = ru, [fd] = bu, [fl] = lu, 216 [bu] = fd, [br] = ld, [bd] = bd, [bl] = rd, 217 218 [uf_mirror] = uf_mirror, [ur_mirror] = ur_mirror, 219 [ul_mirror] = ul_mirror, [ub_mirror] = ub_mirror, 220 [df_mirror] = df_mirror, [dr_mirror] = dl_mirror, 221 [dl_mirror] = dr_mirror, [db_mirror] = db_mirror, 222 [rf_mirror] = rf_mirror, [rd_mirror] = br_mirror, 223 [rb_mirror] = lb_mirror, [ru_mirror] = fl_mirror, 224 [lf_mirror] = lf_mirror, [ld_mirror] = bl_mirror, 225 [lb_mirror] = rb_mirror, [lu_mirror] = fr_mirror, 226 [fu_mirror] = fu_mirror, [fr_mirror] = lu_mirror, 227 [fd_mirror] = bu_mirror, [fl_mirror] = ru_mirror, 228 [bu_mirror] = fd_mirror, [br_mirror] = rd_mirror, 229 [bd_mirror] = bd_mirror, [bl_mirror] = ld_mirror 230 }; 231 232 return inverse_trans_aux[t]; 233 } 234 235 Alg * 236 rotation_alg(Trans t) 237 { 238 int i; 239 240 static Alg *rotation_alg_arr[NROTATIONS]; 241 static bool initialized = false; 242 243 if (!initialized) { 244 for (i = 0; i < NROTATIONS; i++) 245 rotation_alg_arr[i] = new_alg(rotation_alg_string[i]); 246 247 initialized = true; 248 } 249 250 return rotation_alg_arr[t % NROTATIONS]; 251 } 252 253 void 254 transform_alg(Trans t, Alg *alg) 255 { 256 int i; 257 258 /*init_trans();*/ 259 260 for (i = 0; i < alg->len; i++) 261 alg->move[i] = moves_ttable[t][alg->move[i]]; 262 } 263 264 void 265 init_trans(void) 266 { 267 static bool initialized = false; 268 if (initialized) 269 return; 270 initialized = true; 271 272 init_moves(); 273 274 Cube aux, cube, c[3]; 275 CubeArray epcp; 276 int i, eparr[12], eoarr[12], cparr[8], coarr[8]; 277 unsigned int ui; 278 Move mi, move; 279 Trans m; 280 281 /* Compute sources */ 282 for (i = 0; i < NTRANS; i++) { 283 cube = apply_alg(rotation_alg(i), (Cube){0}); 284 285 epose_source[i] = edge_slice(what_edge_at(cube, FR)); 286 eposs_source[i] = edge_slice(what_edge_at(cube, UR)); 287 eposm_source[i] = edge_slice(what_edge_at(cube, UF)); 288 eofb_source[i] = what_center_at(cube, F_center)/2; 289 eorl_source[i] = what_center_at(cube, R_center)/2; 290 eoud_source[i] = what_center_at(cube, U_center)/2; 291 coud_source[i] = what_center_at(cube, U_center)/2; 292 cofb_source[i] = what_center_at(cube, F_center)/2; 293 corl_source[i] = what_center_at(cube, R_center)/2; 294 } 295 296 if (read_ttables_file()) 297 return; 298 299 fprintf(stderr, "Cannot load %s, generating it\n", "ttables"); 300 301 /* Initialize tables */ 302 for (m = 0; m < NTRANS; m++) { 303 epcp = (CubeArray){ .ep = eparr, .cp = cparr }; 304 cube = apply_alg(rotation_alg(m), (Cube){0}); 305 cube_to_arrays(cube, &epcp, pf_epcp); 306 if (m >= NROTATIONS) { 307 apply_permutation(ep_mirror, eparr, 12); 308 apply_permutation(cp_mirror, cparr, 8); 309 } 310 311 for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) { 312 c[0] = admissible_ep((Cube){ .epose = ui }, pf_e); 313 c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s); 314 c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m); 315 316 cube = rotate_via_compose(m,c[epose_source[m]],pf_ep); 317 epose_ttable[m][ui] = cube.epose; 318 319 cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep); 320 eposs_ttable[m][ui] = cube.eposs; 321 322 cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep); 323 eposm_ttable[m][ui] = cube.eposm; 324 } 325 for (ui = 0; ui < POW2TO11; ui++ ) { 326 int_to_sum_zero_array(ui, 2, 12, eoarr); 327 apply_permutation(eparr, eoarr, 12); 328 eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2); 329 } 330 for (ui = 0; ui < POW3TO7; ui++) { 331 int_to_sum_zero_array(ui, 3, 8, coarr); 332 apply_permutation(cparr, coarr, 8); 333 co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3); 334 if (m >= NROTATIONS) 335 co_ttable[m][ui] = 336 invert_digits(co_ttable[m][ui], 3, 7); 337 } 338 for (ui = 0; ui < FACTORIAL8; ui++) { 339 cube = (Cube){ .cp = ui }; 340 cube = rotate_via_compose(m, cube, pf_cp); 341 cp_ttable[m][ui] = cube.cp; 342 } 343 for (ui = 0; ui < FACTORIAL6; ui++) { 344 cube = (Cube){ .cpos = ui }; 345 cube = rotate_via_compose(m, cube, pf_cpos); 346 cpos_ttable[m][ui] = cube.cpos; 347 } 348 for (mi = 0; mi < NMOVES; mi++) { 349 /* Old version: 350 * 351 aux = apply_trans(m, apply_move(mi, (Cube){0})); 352 for (move = 0; move < NMOVES; move++) { 353 cube = apply_move(inverse_move(move), aux); 354 mirr = apply_trans(uf_mirror, cube); 355 if (is_solved(cube) || is_solved(mirr)) 356 moves_ttable[m][mi] = move; 357 } 358 */ 359 360 aux = apply_trans(m, apply_move(mi, (Cube){0})); 361 for (move = 0; move < NMOVES; move++) { 362 cube = apply_move(inverse_move(move), aux); 363 if (is_solved(cube)) { 364 moves_ttable[m][mi] = move; 365 break; 366 } 367 } 368 } 369 } 370 371 if (!write_ttables_file()) 372 fprintf(stderr, "Error writing ttables\n"); 373 } 374