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, 99 insertions, 282 deletions
diff --git a/src/trans.c b/src/trans.c
index e267a17..da2dca3 100644
--- a/src/trans.c
+++ b/src/trans.c
@@ -1,31 +1,23 @@
1#define TRANS_C
2
1#include "trans.h" 3#include "trans.h"
2 4
3/* Local functions ***********************************************************/ 5/* Local functions ***********************************************************/
4 6
5static bool read_ttables_file();
6static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
7static bool write_ttables_file();
8
9/* Tables and other data *****************************************************/ 7/* Tables and other data *****************************************************/
10 8
11static int ep_mirror[12] = { 9static Cube mirror_cube = {
12 [UF] = UF, [UL] = UR, [UB] = UB, [UR] = UL, 10.ep = { [UF] = UF, [UL] = UR, [UB] = UB, [UR] = UL,
13 [DF] = DF, [DL] = DR, [DB] = DB, [DR] = DL, 11 [DF] = DF, [DL] = DR, [DB] = DB, [DR] = DL,
14 [FR] = FL, [FL] = FR, [BL] = BR, [BR] = BL 12 [FR] = FL, [FL] = FR, [BL] = BR, [BR] = BL },
15}; 13.cp = { [UFR] = UFL, [UFL] = UFR, [UBL] = UBR, [UBR] = UBL,
16 14 [DFR] = DFL, [DFL] = DFR, [DBL] = DBR, [DBR] = DBL },
17static int cp_mirror[8] = { 15.xp = { [U_center] = U_center, [D_center] = D_center,
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,
24 [R_center] = L_center, [L_center] = R_center, 16 [R_center] = L_center, [L_center] = R_center,
25 [F_center] = F_center, [B_center] = B_center 17 [F_center] = F_center, [B_center] = B_center }
26}; 18};
27 19
28static char rotation_alg_string[100][NROTATIONS] = { 20static char rotation_alg_string[100][NROTATIONS] = {
29 [uf] = "", [ur] = "y", [ub] = "y2", [ul] = "y3", 21 [uf] = "", [ur] = "y", [ub] = "y2", [ul] = "y3",
30 [df] = "z2", [dr] = "y z2", [db] = "x2", [dl] = "y3 z2", 22 [df] = "z2", [dr] = "y z2", [db] = "x2", [dl] = "y3 z2",
31 [rf] = "z3", [rd] = "z3 y", [rb] = "z3 y2", [ru] = "z3 y3", 23 [rf] = "z3", [rd] = "z3 y", [rb] = "z3 y2", [ru] = "z3 y3",
@@ -34,176 +26,39 @@ static char rotation_alg_string[100][NROTATIONS] = {
34 [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3", 26 [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3",
35}; 27};
36 28
37static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */ 29static Alg *rotation_alg_arr[NROTATIONS];
38static int eposs_source[NTRANS]; 30Move moves_ttable[NTRANS][NMOVES];
39static int eposm_source[NTRANS]; 31Trans trans_ttable[NTRANS][NTRANS];
40static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */ 32Trans trans_itable[NTRANS];
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];
46 33
47int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8]; 34/* Public functions **********************************************************/
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];
55
56/* Local functions implementation ********************************************/
57 35
58static bool 36void
59read_ttables_file() 37apply_trans(Trans t, Cube *cube)
60{ 38{
61 init_env(); 39 Cube aux;
62 40 Alg *inv;
63 FILE *f; 41 int i;
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 42
85 if ((f = fopen(fname, "rb")) == NULL) 43 inv = inverse_alg(rotation_alg(t % NROTATIONS));
86 return false; 44 copy_cube(cube, &aux);
45 make_solved(cube);
87 46
88 for (m = 0; m < NTRANS; m++) { 47 if (t >= NROTATIONS)
89 r = r && fread(epose_ttable[m], b, me[0], f) == me[0]; 48 compose(&mirror_cube, cube);
90 r = r && fread(eposs_ttable[m], b, me[1], f) == me[1]; 49 apply_alg(inv, cube);
91 r = r && fread(eposm_ttable[m], b, me[2], f) == me[2]; 50 compose(&aux, cube);
92 r = r && fread(eo_ttable[m], b, me[3], f) == me[3]; 51 apply_alg(rotation_alg(t % NROTATIONS), cube);
93 r = r && fread(cp_ttable[m], b, me[4], f) == me[4]; 52 if (t >= NROTATIONS) {
94 r = r && fread(co_ttable[m], b, me[5], f) == me[5]; 53 compose(&mirror_cube, cube);
95 r = r && fread(cpos_ttable[m], b, me[6], f) == me[6]; 54 for (i = 0; i < 8; i++)
96 r = r && fread(moves_ttable[m], b, me[7], f) == me[7]; 55 cube->co[i] = (3 - cube->co[i]) % 3;
97 } 56 }
98 57
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
133 free_alg(inv); 58 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 };
205} 59}
206 60
61/*
207Trans 62Trans
208inverse_trans(Trans t) 63inverse_trans(Trans t)
209{ 64{
@@ -231,23 +86,18 @@ inverse_trans(Trans t)
231 86
232 return inverse_trans_aux[t]; 87 return inverse_trans_aux[t];
233} 88}
89*/
234 90
235Alg * 91Trans
236rotation_alg(Trans t) 92inverse_trans(Trans t)
237{ 93{
238 int i; 94 return trans_itable[t];
239 95}
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 96
250 return rotation_alg_arr[t % NROTATIONS]; 97Alg *
98rotation_alg(Trans i)
99{
100 return rotation_alg_arr[i % NROTATIONS];
251} 101}
252 102
253void 103void
@@ -255,10 +105,20 @@ transform_alg(Trans t, Alg *alg)
255{ 105{
256 int i; 106 int i;
257 107
258 /*init_trans();*/
259
260 for (i = 0; i < alg->len; i++) 108 for (i = 0; i < alg->len; i++)
261 alg->move[i] = moves_ttable[t][alg->move[i]]; 109 alg->move[i] = transform_move(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];
262} 122}
263 123
264void 124void
@@ -268,106 +128,63 @@ init_trans() {
268 return; 128 return;
269 initialized = true; 129 initialized = true;
270 130
271 init_moves(); 131 int i;
272 132 Alg *nonsym_alg, *nonsym_inv;
273 Cube aux, cube, c[3]; 133 Cube aux, cube;
274 CubeArray epcp;
275 int i, eparr[12], eoarr[12], cparr[8], coarr[8];
276 unsigned int ui;
277 Move mi, move; 134 Move mi, move;
278 Trans m; 135 Trans t, u, v;
279 136
280 /* Compute sources */ 137 init_moves();
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 }
294
295 if (read_ttables_file())
296 return;
297
298 fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
299
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 138
318 cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep); 139 for (i = 0; i < NROTATIONS; i++)
319 eposs_ttable[m][ui] = cube.eposs; 140 rotation_alg_arr[i] = new_alg(rotation_alg_string[i]);
320 141
321 cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep); 142 for (t = 0; t < NTRANS; t++) {
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 }
347 for (mi = 0; mi < NMOVES; mi++) { 143 for (mi = 0; mi < NMOVES; mi++) {
348 /* Old version: 144 make_solved(&aux);
349 * 145 apply_move(mi, &aux);
350 aux = apply_trans(m, apply_move(mi, (Cube){0})); 146 apply_trans(t, &aux);
351 for (move = 0; move < NMOVES; move++) { 147 for (move = 0; move < NMOVES; move++) {
352 cube = apply_move(inverse_move(move), aux); 148 copy_cube(&aux, &cube);
353 mirr = apply_trans(uf_mirror, cube); 149 apply_move(inverse_move(move), &cube);
354 if (is_solved(cube) || is_solved(mirr)) 150 if (is_solved(&cube)) {
355 moves_ttable[m][mi] = move; 151 moves_ttable[t][mi] = move;
152 break;
153 }
356 } 154 }
357 */ 155 }
156 }
358 157
359 aux = apply_trans(m, apply_move(mi, (Cube){0})); 158 nonsym_alg = new_alg("R' U' F");
360 for (move = 0; move < NMOVES; move++) { 159 nonsym_inv = inverse_alg(nonsym_alg);
361 cube = apply_move(inverse_move(move), aux); 160
362 if (is_solved(cube)) { 161 for (t = 0; t < NTRANS; t++) {
363 moves_ttable[m][mi] = move; 162 for (u = 0; u < NTRANS; u++) {
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;
364 break; 177 break;
365 } 178 }
366 } 179 }
367 } 180 }
368 } 181 }
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
369 186
370 if (!write_ttables_file()) 187 free_alg(nonsym_alg);
371 fprintf(stderr, "Error writing ttables\n"); 188 free_alg(nonsym_inv);
372} 189}
373 190

Generated with cgit - Back to sebastiano.tronto.net