aboutsummaryrefslogtreecommitdiff
path: root/src/trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/trans.c')
-rw-r--r--src/trans.c381
1 files changed, 282 insertions, 99 deletions
diff --git a/src/trans.c b/src/trans.c
index 898c2be..e267a17 100644
--- a/src/trans.c
+++ b/src/trans.c
@@ -1,23 +1,31 @@
1#define TRANS_C
2
3#include "trans.h" 1#include "trans.h"
4 2
5/* Local functions ***********************************************************/ 3/* Local functions ***********************************************************/
6 4
5static bool read_ttables_file();
6static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
7static bool write_ttables_file();
8
7/* Tables and other data *****************************************************/ 9/* Tables and other data *****************************************************/
8 10
9static Cube mirror_cube = { 11static int ep_mirror[12] = {
10.ep = { [UF] = UF, [UL] = UR, [UB] = UB, [UR] = UL, 12 [UF] = UF, [UL] = UR, [UB] = UB, [UR] = UL,
11 [DF] = DF, [DL] = DR, [DB] = DB, [DR] = DL, 13 [DF] = DF, [DL] = DR, [DB] = DB, [DR] = DL,
12 [FR] = FL, [FL] = FR, [BL] = BR, [BR] = BL }, 14 [FR] = FL, [FL] = FR, [BL] = BR, [BR] = BL
13.cp = { [UFR] = UFL, [UFL] = UFR, [UBL] = UBR, [UBR] = UBL, 15};
14 [DFR] = DFL, [DFL] = DFR, [DBL] = DBR, [DBR] = DBL }, 16
15.xp = { [U_center] = U_center, [D_center] = D_center, 17static int cp_mirror[8] = {
18 [UFR] = UFL, [UFL] = UFR, [UBL] = UBR, [UBR] = UBL,
19 [DFR] = DFL, [DFL] = DFR, [DBL] = DBR, [DBR] = DBL
20};
21
22static int cpos_mirror[6] = {
23 [U_center] = U_center, [D_center] = D_center,
16 [R_center] = L_center, [L_center] = R_center, 24 [R_center] = L_center, [L_center] = R_center,
17 [F_center] = F_center, [B_center] = B_center } 25 [F_center] = F_center, [B_center] = B_center
18}; 26};
19 27
20static char rotation_alg_string[100][NROTATIONS] = { 28static char rotation_alg_string[100][NROTATIONS] = {
21 [uf] = "", [ur] = "y", [ub] = "y2", [ul] = "y3", 29 [uf] = "", [ur] = "y", [ub] = "y2", [ul] = "y3",
22 [df] = "z2", [dr] = "y z2", [db] = "x2", [dl] = "y3 z2", 30 [df] = "z2", [dr] = "y z2", [db] = "x2", [dl] = "y3 z2",
23 [rf] = "z3", [rd] = "z3 y", [rb] = "z3 y2", [ru] = "z3 y3", 31 [rf] = "z3", [rd] = "z3 y", [rb] = "z3 y2", [ru] = "z3 y3",
@@ -26,39 +34,176 @@ static char rotation_alg_string[100][NROTATIONS] = {
26 [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3", 34 [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3",
27}; 35};
28 36
29Alg *rotation_alg_arr[NROTATIONS]; 37static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
30Move moves_ttable[NTRANS][NMOVES]; 38static int eposs_source[NTRANS];
31Trans trans_ttable[NTRANS][NTRANS]; 39static int eposm_source[NTRANS];
32Trans trans_itable[NTRANS]; 40static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
41static int eorl_source[NTRANS];
42static int eoud_source[NTRANS];
43static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
44static int cofb_source[NTRANS];
45static int corl_source[NTRANS];
33 46
34/* Public functions **********************************************************/ 47int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
48int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
49int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
50int eo_ttable[NTRANS][POW2TO11];
51int cp_ttable[NTRANS][FACTORIAL8];
52int co_ttable[NTRANS][POW3TO7];
53int cpos_ttable[NTRANS][FACTORIAL6];
54Move moves_ttable[NTRANS][NMOVES];
35 55
36void 56/* Local functions implementation ********************************************/
37apply_trans(Trans t, Cube *cube) 57
58static bool
59read_ttables_file()
38{ 60{
39 Cube aux; 61 init_env();
40 Alg *inv; 62
41 int i; 63 FILE *f;
64 char fname[strlen(tabledir)+20];
65 int b = sizeof(int);
66 bool r = true;
67 Move m;
42 68
43 inv = inverse_alg(rotation_alg(t % NROTATIONS)); 69 /* Table sizes, used for reading and writing files */
44 copy_cube(cube, &aux); 70 uint64_t me[11] = {
45 make_solved(cube); 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;
46 87
47 if (t >= NROTATIONS) 88 for (m = 0; m < NTRANS; m++) {
48 compose(&mirror_cube, cube); 89 r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
49 apply_alg(inv, cube); 90 r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
50 compose(&aux, cube); 91 r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
51 apply_alg(rotation_alg(t % NROTATIONS), cube); 92 r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
52 if (t >= NROTATIONS) { 93 r = r && fread(cp_ttable[m], b, me[4], f) == me[4];
53 compose(&mirror_cube, cube); 94 r = r && fread(co_ttable[m], b, me[5], f) == me[5];
54 for (i = 0; i < 8; i++) 95 r = r && fread(cpos_ttable[m], b, me[6], f) == me[6];
55 cube->co[i] = (3 - cube->co[i]) % 3; 96 r = r && fread(moves_ttable[m], b, me[7], f) == me[7];
56 } 97 }
57 98
99 fclose(f);
100 return r;
101}
102
103static Cube
104rotate_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
58 free_alg(inv); 133 free_alg(inv);
134 return ret;
135}
136
137static bool
138write_ttables_file()
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
183Cube
184apply_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 };
59} 205}
60 206
61/*
62Trans 207Trans
63inverse_trans(Trans t) 208inverse_trans(Trans t)
64{ 209{
@@ -86,18 +231,23 @@ inverse_trans(Trans t)
86 231
87 return inverse_trans_aux[t]; 232 return inverse_trans_aux[t];
88} 233}
89*/
90
91Trans
92inverse_trans(Trans t)
93{
94 return trans_itable[t];
95}
96 234
97Alg * 235Alg *
98rotation_alg(Trans i) 236rotation_alg(Trans t)
99{ 237{
100 return rotation_alg_arr[i % NROTATIONS]; 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];
101} 251}
102 252
103void 253void
@@ -105,20 +255,10 @@ transform_alg(Trans t, Alg *alg)
105{ 255{
106 int i; 256 int i;
107 257
258 /*init_trans();*/
259
108 for (i = 0; i < alg->len; i++) 260 for (i = 0; i < alg->len; i++)
109 alg->move[i] = transform_move(t, alg->move[i]); 261 alg->move[i] = moves_ttable[t][alg->move[i]];
110}
111
112Move
113transform_move(Trans t, Move m)
114{
115 return moves_ttable[t][m];
116}
117
118Trans
119transform_trans(Trans t, Trans m)
120{
121 return trans_ttable[t][m];
122} 262}
123 263
124void 264void
@@ -128,63 +268,106 @@ init_trans() {
128 return; 268 return;
129 initialized = true; 269 initialized = true;
130 270
131 int i; 271 init_moves();
132 Alg *nonsym_alg, *nonsym_inv; 272
133 Cube aux, cube; 273 Cube aux, cube, c[3];
274 CubeArray epcp;
275 int i, eparr[12], eoarr[12], cparr[8], coarr[8];
276 unsigned int ui;
134 Move mi, move; 277 Move mi, move;
135 Trans t, u, v; 278 Trans m;
136 279
137 init_moves(); 280 /* Compute sources */
281 for (i = 0; i < NTRANS; i++) {
282 cube = apply_alg(rotation_alg(i), (Cube){0});
283
284 epose_source[i] = edge_slice(what_edge_at(cube, FR));
285 eposs_source[i] = edge_slice(what_edge_at(cube, UR));
286 eposm_source[i] = edge_slice(what_edge_at(cube, UF));
287 eofb_source[i] = what_center_at(cube, F_center)/2;
288 eorl_source[i] = what_center_at(cube, R_center)/2;
289 eoud_source[i] = what_center_at(cube, U_center)/2;
290 coud_source[i] = what_center_at(cube, U_center)/2;
291 cofb_source[i] = what_center_at(cube, F_center)/2;
292 corl_source[i] = what_center_at(cube, R_center)/2;
293 }
138 294
139 for (i = 0; i < NROTATIONS; i++) 295 if (read_ttables_file())
140 rotation_alg_arr[i] = new_alg(rotation_alg_string[i]); 296 return;
297
298 fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
141 299
142 for (t = 0; t < NTRANS; t++) { 300 /* Initialize tables */
301 for (m = 0; m < NTRANS; m++) {
302 epcp = (CubeArray){ .ep = eparr, .cp = cparr };
303 cube = apply_alg(rotation_alg(m), (Cube){0});
304 cube_to_arrays(cube, &epcp, pf_epcp);
305 if (m >= NROTATIONS) {
306 apply_permutation(ep_mirror, eparr, 12);
307 apply_permutation(cp_mirror, cparr, 8);
308 }
309
310 for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
311 c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
312 c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
313 c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
314
315 cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
316 epose_ttable[m][ui] = cube.epose;
317
318 cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
319 eposs_ttable[m][ui] = cube.eposs;
320
321 cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
322 eposm_ttable[m][ui] = cube.eposm;
323 }
324 for (ui = 0; ui < POW2TO11; ui++ ) {
325 int_to_sum_zero_array(ui, 2, 12, eoarr);
326 apply_permutation(eparr, eoarr, 12);
327 eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
328 }
329 for (ui = 0; ui < POW3TO7; ui++) {
330 int_to_sum_zero_array(ui, 3, 8, coarr);
331 apply_permutation(cparr, coarr, 8);
332 co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
333 if (m >= NROTATIONS)
334 co_ttable[m][ui] =
335 invert_digits(co_ttable[m][ui], 3, 7);
336 }
337 for (ui = 0; ui < FACTORIAL8; ui++) {
338 cube = (Cube){ .cp = ui };
339 cube = rotate_via_compose(m, cube, pf_cp);
340 cp_ttable[m][ui] = cube.cp;
341 }
342 for (ui = 0; ui < FACTORIAL6; ui++) {
343 cube = (Cube){ .cpos = ui };
344 cube = rotate_via_compose(m, cube, pf_cpos);
345 cpos_ttable[m][ui] = cube.cpos;
346 }
143 for (mi = 0; mi < NMOVES; mi++) { 347 for (mi = 0; mi < NMOVES; mi++) {
144 make_solved(&aux); 348 /* Old version:
145 apply_move(mi, &aux); 349 *
146 apply_trans(t, &aux); 350 aux = apply_trans(m, apply_move(mi, (Cube){0}));
147 for (move = 0; move < NMOVES; move++) { 351 for (move = 0; move < NMOVES; move++) {
148 copy_cube(&aux, &cube); 352 cube = apply_move(inverse_move(move), aux);
149 apply_move(inverse_move(move), &cube); 353 mirr = apply_trans(uf_mirror, cube);
150 if (is_solved(&cube)) { 354 if (is_solved(cube) || is_solved(mirr))
151 moves_ttable[t][mi] = move; 355 moves_ttable[m][mi] = move;
152 break;
153 }
154 } 356 }
155 } 357 */
156 }
157 358
158 nonsym_alg = new_alg("R' U' F"); 359 aux = apply_trans(m, apply_move(mi, (Cube){0}));
159 nonsym_inv = inverse_alg(nonsym_alg); 360 for (move = 0; move < NMOVES; move++) {
160 361 cube = apply_move(inverse_move(move), aux);
161 for (t = 0; t < NTRANS; t++) { 362 if (is_solved(cube)) {
162 for (u = 0; u < NTRANS; u++) { 363 moves_ttable[m][mi] = move;
163 make_solved(&aux);
164 apply_alg(nonsym_alg, &aux);
165 apply_trans(u, &aux);
166 apply_trans(t, &aux);
167 for (v = 0; v < NTRANS; v++) {
168 copy_cube(&aux, &cube);
169 apply_trans(v, &cube);
170 apply_alg(nonsym_inv, &cube);
171 if (is_solved(&cube)) {
172 /* This is the inverse of the correct
173 value, it will be inverted later */
174 trans_ttable[t][u] = v;
175 if (v == uf)
176 trans_itable[t] = u;
177 break; 364 break;
178 } 365 }
179 } 366 }
180 } 367 }
181 } 368 }
182 for (t = 0; t < NTRANS; t++)
183 for (u = 0; u < NTRANS; u++)
184 trans_ttable[t][u] = trans_itable[trans_ttable[t][u]];
185
186 369
187 free_alg(nonsym_alg); 370 if (!write_ttables_file())
188 free_alg(nonsym_inv); 371 fprintf(stderr, "Error writing ttables\n");
189} 372}
190 373

Generated with cgit - Back to sebastiano.tronto.net