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

Generated with cgit - Back to sebastiano.tronto.net