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