aboutsummaryrefslogtreecommitdiff
path: root/src/cube.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cube.c')
-rw-r--r--src/cube.c920
1 files changed, 72 insertions, 848 deletions
diff --git a/src/cube.c b/src/cube.c
index aae3a6e..0ccffa4 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -1,531 +1,121 @@
1#include "cube.h" 1#define CUBE_C
2
3/* Local functions ***********************************************************/
4
5static void init_inverse();
6static bool read_invtables_file();
7static bool write_invtables_file();
8
9/* Tables ********************************************************************/
10
11static uint16_t eo_invtable_e[POW2TO11][BINOM12ON4*FACTORIAL4];
12static uint16_t eo_invtable_s[POW2TO11][BINOM12ON4*FACTORIAL4];
13static uint16_t eo_invtable_m[POW2TO11][BINOM12ON4*FACTORIAL4];
14static uint16_t co_invtable[POW3TO7][FACTORIAL8];
15static uint16_t cp_invtable[FACTORIAL8];
16static uint16_t cpos_invtable[FACTORIAL6];
17
18/* Functions implementation **************************************************/
19
20int
21array_ep_to_epos(int *ep, int *ss)
22{
23 int epos[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
24 int eps[4];
25 int i, j, is;
26
27 for (i = 0, is = 0; i < 12; i++) {
28 for (j = 0; j < 4; j++) {
29 if (ep[i] == ss[j]) {
30 eps[is++] = j;
31 epos[i] = 1;
32 }
33 }
34 }
35
36 for (i = 0; i < 4; i++)
37 swap(&epos[ss[i]], &epos[i+8]);
38
39 return 24 * subset_to_index(epos, 12, 4) + perm_to_index(eps, 4);
40}
41
42Cube
43arrays_to_cube(CubeArray *arr, PieceFilter f)
44{
45 Cube ret = {0};
46
47 static int epe_solved[4] = {FR, FL, BL, BR};
48 static int eps_solved[4] = {UL, UR, DL, DR};
49 static int epm_solved[4] = {UF, UB, DF, DB};
50 2
51 if (f.epose) 3#include "cube.h"
52 ret.epose = array_ep_to_epos(arr->ep, epe_solved);
53 if (f.eposs)
54 ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
55 if (f.eposm)
56 ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
57 if (f.eofb)
58 ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
59 if (f.eorl)
60 ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
61 if (f.eoud)
62 ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
63 if (f.cp)
64 ret.cp = perm_to_index(arr->cp, 8);
65 if (f.coud)
66 ret.coud = digit_array_to_int(arr->coud, 7, 3);
67 if (f.corl)
68 ret.corl = digit_array_to_int(arr->corl, 7, 3);
69 if (f.cofb)
70 ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
71 if (f.cpos)
72 ret.cpos = perm_to_index(arr->cpos, 6);
73
74 return ret;
75}
76 4
77Cube 5void
78compose_filtered(Cube c2, Cube c1, PieceFilter f) 6compose(Cube *c2, Cube *c1)
79{ 7{
80 CubeArray *arr = new_cubearray(c2, f); 8 apply_permutation(c2->ep, c1->ep, 12);
81 Cube ret; 9 apply_permutation(c2->ep, c1->eo, 12);
10 sum_arrays_mod(c2->eo, c1->eo, 12, 2);
82 11
83 ret = move_via_arrays(arr, c1, f); 12 apply_permutation(c2->cp, c1->cp, 8);
84 free_cubearray(arr, f); 13 apply_permutation(c2->cp, c1->co, 8);
14 sum_arrays_mod(c2->co, c1->co, 8, 3);
85 15
86 return ret; 16 apply_permutation(c2->xp, c1->xp, 6);
87} 17}
88 18
89void 19void
90cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f) 20copy_cube(Cube *src, Cube *dst)
91{ 21{
92 int i; 22 memcpy(dst->ep, src->ep, 12 * sizeof(int));
93 23 memcpy(dst->eo, src->eo, 12 * sizeof(int));
94 static int epe_solved[4] = {FR, FL, BL, BR}; 24 memcpy(dst->cp, src->cp, 8 * sizeof(int));
95 static int eps_solved[4] = {UL, UR, DL, DR}; 25 memcpy(dst->co, src->co, 8 * sizeof(int));
96 static int epm_solved[4] = {UF, UB, DF, DB}; 26 memcpy(dst->xp, src->xp, 6 * sizeof(int));
97
98 if (f.epose || f.eposs || f.eposm)
99 for (i = 0; i < 12; i++)
100 arr->ep[i] = -1;
101
102 if (f.epose)
103 epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
104 if (f.eposs)
105 epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
106 if (f.eposm)
107 epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
108 if (f.eofb)
109 int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
110 if (f.eorl)
111 int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
112 if (f.eoud)
113 int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
114 if (f.cp)
115 index_to_perm(cube.cp, 8, arr->cp);
116 if (f.coud)
117 int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
118 if (f.corl)
119 int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
120 if (f.cofb)
121 int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
122 if (f.cpos)
123 index_to_perm(cube.cpos, 6, arr->cpos);
124} 27}
125 28
126void 29bool
127epos_to_compatible_ep(int epos, int *ep, int *ss) 30equal(Cube *c1, Cube *c2)
128{ 31{
129 int i, j, k, other[8]; 32 int i;
130 bool flag;
131 33
132 for (i = 0; i < 12; i++) 34 for (i = 0; i < 12; i++)
133 ep[i] = -1; 35 if (c1->ep[i] != c2->ep[i] || c1->eo[i] != c2->eo[i])
134 36 return false;
135 epos_to_partial_ep(epos, ep, ss);
136
137 for (i = 0, j = 0; i < 12; i++) {
138 flag = false;
139 for (k = 0; k < 4; k++)
140 flag = flag || (i == ss[k]);
141 if (!flag)
142 other[j++] = i;
143 }
144
145 for (i = 0, j = 0; i < 12; i++)
146 if (ep[i] == -1)
147 ep[i] = other[j++];
148}
149
150void
151epos_to_partial_ep(int epos, int *ep, int *ss)
152{
153 int i, is, eposs[12], eps[4];
154 37
155 index_to_perm(epos % FACTORIAL4, 4, eps); 38 for (i = 0; i < 8; i++)
156 index_to_subset(epos / FACTORIAL4, 12, 4, eposs); 39 if (c1->cp[i] != c2->cp[i] || c1->co[i] != c2->co[i])
40 return false;
157 41
158 for (i = 0; i < 4; i++) 42 for (i = 0; i < 6; i++)
159 swap(&eposs[ss[i]], &eposs[i+8]); 43 if (c1->xp[i] != c2->xp[i])
44 return false;
160 45
161 for (i = 0, is = 0; i < 12; i++) 46 return true;
162 if (eposs[i])
163 ep[i] = ss[eps[is++]];
164} 47}
165 48
166void 49void
167fix_eorleoud(CubeArray *arr) 50invert_cube(Cube *cube)
168{ 51{
52 Cube aux;
169 int i; 53 int i;
170 54
171 for (i = 0; i < 12; i++) { 55 copy_cube(cube, &aux);
172 if ((edge_slice(i) == 0 && edge_slice(arr->ep[i]) != 0) ||
173 (edge_slice(i) != 0 && edge_slice(arr->ep[i]) == 0)) {
174 arr->eorl[i] = 1 - arr->eofb[i];
175 } else {
176 arr->eorl[i] = arr->eofb[i];
177 }
178 56
179 if ((edge_slice(i) == 2 && edge_slice(arr->ep[i]) != 2) || 57 for (i = 0; i < 12; i++) {
180 (edge_slice(i) != 2 && edge_slice(arr->ep[i]) == 2)) { 58 cube->ep[aux.ep[i]] = i;
181 arr->eoud[i] = 1 - arr->eofb[i]; 59 cube->eo[aux.ep[i]] = aux.eo[i];
182 } else {
183 arr->eoud[i] = arr->eofb[i];
184 }
185 } 60 }
186}
187
188void
189fix_cofbcorl(CubeArray *arr)
190{
191 int i;
192 61
193 for (i = 0; i < 8; i++) { 62 for (i = 0; i < 8; i++) {
194 if (i % 2 == arr->cp[i] % 2) { 63 cube->cp[aux.cp[i]] = i;
195 arr->cofb[i] = arr->coud[i]; 64 cube->co[aux.cp[i]] = (3 - aux.co[i]) % 3;
196 arr->corl[i] = arr->coud[i];
197 } else {
198 if (arr->cp[i] % 2 == 0) {
199 arr->cofb[i] = (arr->coud[i]+1)%3;
200 arr->corl[i] = (arr->coud[i]+2)%3;
201 } else {
202 arr->cofb[i] = (arr->coud[i]+2)%3;
203 arr->corl[i] = (arr->coud[i]+1)%3;
204 }
205 }
206 } 65 }
207}
208
209Cube
210fourval_to_cube(int eofb, int ep, int coud, int cp)
211{
212 CubeArray *arr;
213
214 arr = new_cubearray((Cube){0}, pf_all);
215 66
216 index_to_perm(ep, 12, arr->ep); 67 for (i = 0; i < 6; i++)
217 index_to_perm(cp, 8, arr->cp); 68 cube->xp[aux.xp[i]] = i;
218 int_to_sum_zero_array(eofb, 2, 12, arr->eofb);
219 int_to_sum_zero_array(coud, 3, 8, arr->coud);
220
221 /* fix parity */
222 if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
223 swap(&(arr->ep[0]), &(arr->ep[1]));
224
225 fix_eorleoud(arr);
226 fix_cofbcorl(arr);
227
228 return arrays_to_cube(arr, pf_all);
229}
230
231void
232free_cubearray(CubeArray *arr, PieceFilter f)
233{
234 if (f.epose || f.eposs || f.eposm)
235 free(arr->ep);
236 if (f.eofb)
237 free(arr->eofb);
238 if (f.eorl)
239 free(arr->eorl);
240 if (f.eoud)
241 free(arr->eoud);
242 if (f.cp)
243 free(arr->cp);
244 if (f.coud)
245 free(arr->coud);
246 if (f.corl)
247 free(arr->corl);
248 if (f.cofb)
249 free(arr->cofb);
250 if (f.cpos)
251 free(arr->cpos);
252
253 free(arr);
254}
255
256Cube
257move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
258{
259 CubeArray *arrc = new_cubearray(c, f);
260 Cube ret;
261
262 if (f.epose || f.eposs || f.eposm)
263 apply_permutation(arr->ep, arrc->ep, 12);
264
265 if (f.eofb) {
266 apply_permutation(arr->ep, arrc->eofb, 12);
267 sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
268 }
269
270 if (f.eorl) {
271 apply_permutation(arr->ep, arrc->eorl, 12);
272 sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
273 }
274
275 if (f.eoud) {
276 apply_permutation(arr->ep, arrc->eoud, 12);
277 sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
278 }
279
280 if (f.cp)
281 apply_permutation(arr->cp, arrc->cp, 8);
282
283 if (f.coud) {
284 apply_permutation(arr->cp, arrc->coud, 8);
285 sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
286 }
287
288 if (f.corl) {
289 apply_permutation(arr->cp, arrc->corl, 8);
290 sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
291 }
292
293 if (f.cofb) {
294 apply_permutation(arr->cp, arrc->cofb, 8);
295 sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
296 }
297
298 if (f.cpos)
299 apply_permutation(arr->cpos, arrc->cpos, 6);
300
301 ret = arrays_to_cube(arrc, f);
302 free_cubearray(arrc, f);
303
304 return ret;
305}
306
307CubeArray *
308new_cubearray(Cube cube, PieceFilter f)
309{
310 CubeArray *arr = malloc(sizeof(CubeArray));
311
312 if (f.epose || f.eposs || f.eposm)
313 arr->ep = malloc(12 * sizeof(int));
314 if (f.eofb)
315 arr->eofb = malloc(12 * sizeof(int));
316 if (f.eorl)
317 arr->eorl = malloc(12 * sizeof(int));
318 if (f.eoud)
319 arr->eoud = malloc(12 * sizeof(int));
320 if (f.cp)
321 arr->cp = malloc(8 * sizeof(int));
322 if (f.coud)
323 arr->coud = malloc(8 * sizeof(int));
324 if (f.corl)
325 arr->corl = malloc(8 * sizeof(int));
326 if (f.cofb)
327 arr->cofb = malloc(8 * sizeof(int));
328 if (f.cpos)
329 arr->cpos = malloc(6 * sizeof(int));
330
331 cube_to_arrays(cube, arr, f);
332
333 return arr;
334}
335
336Cube
337admissible_ep(Cube cube, PieceFilter f)
338{
339 CubeArray *arr = new_cubearray(cube, f);
340 Cube ret;
341 bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
342 int i, j;
343
344 for (i = 0; i < 12; i++)
345 if (arr->ep[i] != -1)
346 used[arr->ep[i]] = true;
347
348 for (i = 0, j = 0; i < 12; i++) {
349 for ( ; j < 11 && used[j]; j++);
350 if (arr->ep[i] == -1)
351 arr->ep[i] = j++;
352 }
353
354 ret = arrays_to_cube(arr, pf_ep);
355 free_cubearray(arr, f);
356
357 return ret;
358}
359
360Cube
361compose(Cube c2, Cube c1)
362{
363 return compose_filtered(c2, c1, pf_all);
364}
365
366int
367edge_slice(Edge e) {
368 if (e < 0 || e > 11)
369 return -1;
370
371 if (e == FR || e == FL || e == BL || e == BR)
372 return 0;
373 if (e == UR || e == UL || e == DR || e == DL)
374 return 1;
375
376 return 2;
377}
378
379bool
380equal(Cube c1, Cube c2)
381{
382 return c1.eofb == c2.eofb &&
383 c1.epose == c2.epose &&
384 c1.eposs == c2.eposs &&
385 c1.eposm == c2.eposm &&
386 c1.coud == c2.coud &&
387 c1.cp == c2.cp &&
388 c1.cpos == c2.cpos;
389}
390
391Cube
392inverse_cube(Cube cube)
393{
394 CubeArray inv;
395 Cube ret;
396 int i, ep[12];
397
398 for (i = 0; i < 12; i++)
399 ep[i] = where_is_edge(cube, i);
400 inv = (CubeArray){.ep = ep};
401 ret = arrays_to_cube(&inv, pf_ep);
402
403 ret.eofb = ((int)eo_invtable_e[cube.eofb][cube.epose]) |
404 ((int)eo_invtable_m[cube.eofb][cube.eposm]) |
405 ((int)eo_invtable_s[cube.eofb][cube.eposs]);
406 ret.eorl = ((int)eo_invtable_e[cube.eorl][cube.epose]) |
407 ((int)eo_invtable_m[cube.eorl][cube.eposm]) |
408 ((int)eo_invtable_s[cube.eorl][cube.eposs]);
409 ret.eoud = ((int)eo_invtable_e[cube.eoud][cube.epose]) |
410 ((int)eo_invtable_m[cube.eoud][cube.eposm]) |
411 ((int)eo_invtable_s[cube.eoud][cube.eposs]);
412 ret.cp = cp_invtable[cube.cp];
413 ret.cpos = cpos_invtable[cube.cpos];
414 ret.coud = co_invtable[cube.coud][cube.cp];
415 ret.corl = co_invtable[cube.corl][cube.cp];
416 ret.cofb = co_invtable[cube.cofb][cube.cp];
417
418 return ret;
419} 69}
420 70
421bool 71bool
422is_admissible(Cube cube) { 72is_admissible(Cube *c) {
423
424 /* TODO: this should check consistency of different orientations */
425 /* check also that centers are opposite and admissible */
426
427 CubeArray *a = new_cubearray(cube, pf_all);
428 int parity;
429 bool perm; 73 bool perm;
74 int sign, i;
75 int sum_e, sum_c;
430 76
431 perm = is_perm(a->ep, 12) && 77 perm = is_perm(c->ep, 12) && is_perm(c->cp, 8) && is_perm(c->xp, 6);
432 is_perm(a->cp, 8) &&
433 is_perm(a->cpos, 6);
434 parity = perm_sign(a->ep, 12) +
435 perm_sign(a->cp, 8) +
436 perm_sign(a->cpos, 6);
437
438 free_cubearray(a, pf_all);
439 78
440 return perm && parity % 2 == 0; 79 sign = perm_sign(c->ep,12) + perm_sign(c->cp,8) + perm_sign(c->xp,6);
441}
442
443bool
444is_solved(Cube cube)
445{
446 return equal(cube, (Cube){0});
447}
448
449bool
450is_block_solved(Cube cube, Block block)
451{
452 int i;
453 80
454 for (i = 0; i < 12; i++) 81 for (i = 0, sum_e = 0; i < 12; i++)
455 if (block.edge[i] && !is_solved_edge(cube, i)) 82 if (c->eo[i] > 1)
456 return false;
457 for (i = 0; i < 8; i++)
458 if (block.corner[i] && !is_solved_corner(cube, i))
459 return false;
460 for (i = 0; i < 6; i++)
461 if (block.center[i] && !is_solved_center(cube, i))
462 return false; 83 return false;
84 else
85 sum_e += c->eo[i];
463 86
464 return true; 87 for (i = 0, sum_c = 0; i < 8; i++)
465} 88 if (c->co[i] > 2)
89 return false;
90 else
91 sum_c += c->co[i];
466 92
467bool 93 return (perm && sign % 2 == 0 && sum_e % 2 == 0 && sum_c % 2 == 0);
468is_solved_center(Cube cube, Center c)
469{
470 return what_center_at(cube, c) == c;
471} 94}
472 95
473bool 96bool
474is_solved_corner(Cube cube, Corner c) 97is_solved(Cube *cube)
475{ 98{
476 return what_corner_at(cube, c) == c && 99 Cube solved_cube;
477 what_orientation_corner(cube.coud, c); 100 make_solved(&solved_cube);
478}
479 101
480bool 102 return equal(cube, &solved_cube);
481is_solved_edge(Cube cube, Edge e)
482{
483 return what_edge_at(cube, e) == e &&
484 what_orientation_edge(cube.eofb, e);
485} 103}
486 104
487int 105void
488piece_orientation(Cube cube, int piece, char *orientation) 106make_solved(Cube *cube)
489{ 107{
490 int arr[12], n, b, x; 108 static int sorted[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
491 109
492 if (!strcmp(orientation, "eofb")) { 110 memcpy(cube->ep, sorted, 12 * sizeof(int));
493 x = cube.eofb; 111 memset(cube->eo, 0, 12 * sizeof(int));
494 n = 12; 112 memcpy(cube->cp, sorted, 8 * sizeof(int));
495 b = 2; 113 memset(cube->co, 0, 8 * sizeof(int));
496 } else if (!strcmp(orientation, "eorl")) { 114 memcpy(cube->xp, sorted, 6 * sizeof(int));
497 x = cube.eorl;
498 n = 12;
499 b = 2;
500 } else if (!strcmp(orientation, "eoud")) {
501 x = cube.eoud;
502 n = 12;
503 b = 2;
504 } else if (!strcmp(orientation, "coud")) {
505 x = cube.coud;
506 n = 8;
507 b = 3;
508 } else if (!strcmp(orientation, "corl")) {
509 x = cube.corl;
510 n = 8;
511 b = 3;
512 } else if (!strcmp(orientation, "cofb")) {
513 x = cube.cofb;
514 n = 8;
515 b = 3;
516 } else {
517 return -1;
518 }
519
520 int_to_sum_zero_array(x, b, n, arr);
521 if (piece < n)
522 return arr[piece];
523
524 return -1;
525} 115}
526 116
527void 117void
528print_cube(Cube cube) 118print_cube(Cube *cube)
529{ 119{
530 static char edge_string[12][7] = { 120 static char edge_string[12][7] = {
531 [UF] = "UF", [UL] = "UL", [UB] = "UB", [UR] = "UR", 121 [UF] = "UF", [UL] = "UL", [UB] = "UB", [UR] = "UR",
@@ -545,388 +135,22 @@ print_cube(Cube cube)
545 }; 135 };
546 136
547 for (int i = 0; i < 12; i++) 137 for (int i = 0; i < 12; i++)
548 printf(" %s ", edge_string[what_edge_at(cube, i)]); 138 printf(" %s ", edge_string[cube->ep[i]]);
549 printf("\n"); 139 printf("\n");
550 140
551 for (int i = 0; i < 12; i++) 141 for (int i = 0; i < 12; i++)
552 printf(" %d ", what_orientation_edge(cube.eofb, i)); 142 printf(" %" PRIu8 " ", cube->eo[i]);
553 printf("\n"); 143 printf("\n");
554 144
555 for (int i = 0; i < 8; i++) 145 for (int i = 0; i < 8; i++)
556 printf("%s ", corner_string[what_corner_at(cube, i)]); 146 printf("%s ", corner_string[cube->cp[i]]);
557 printf("\n"); 147 printf("\n");
558 148
559 for (int i = 0; i < 8; i++) 149 for (int i = 0; i < 8; i++)
560 printf(" %d ", what_orientation_corner(cube.coud, i)); 150 printf(" %" PRIu8 " ", cube->co[i]);
561 printf("\n"); 151 printf("\n");
562 152
563 for (int i = 0; i < 6; i++) 153 for (int i = 0; i < 6; i++)
564 printf(" %s ", center_string[what_center_at(cube, i)]); 154 printf(" %s ", center_string[cube->xp[i]]);
565 printf("\n"); 155 printf("\n");
566} 156}
567
568Center
569what_center_at(Cube cube, Center c)
570{
571 static bool initialized = false;
572 static Center aux[FACTORIAL6][6];
573 static int i;
574 static unsigned int ui;
575 static CubeArray *arr;
576
577 if (!initialized) {
578 for (ui = 0; ui < FACTORIAL6; ui++) {
579 arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
580 for (i = 0; i < 6; i++)
581 aux[ui][i] = arr->cpos[i];
582 free_cubearray(arr, pf_cpos);
583 }
584
585 initialized = true;
586 }
587
588 return aux[cube.cpos][c];
589}
590
591Corner
592what_corner_at(Cube cube, Corner c)
593{
594 int i;
595 unsigned int ui;
596 CubeArray *arr;
597
598 static bool initialized = false;
599 static Corner aux[FACTORIAL8][8];
600
601 if (!initialized) {
602 for (ui = 0; ui < FACTORIAL8; ui++) {
603 arr = new_cubearray((Cube){.cp = ui}, pf_cp);
604 for (i = 0; i < 8; i++)
605 aux[ui][i] = arr->cp[i];
606 free_cubearray(arr, pf_cp);
607 }
608
609 initialized = true;
610 }
611
612 return aux[cube.cp][c];
613}
614
615Edge
616what_edge_at(Cube cube, Edge e)
617{
618 Edge ret;
619 CubeArray *arr = new_cubearray(cube, pf_ep);
620
621 ret = arr->ep[e];
622
623 free_cubearray(arr, pf_ep);
624 return ret;
625}
626
627int
628what_orientation_corner(int co, Corner c)
629{
630 static bool initialized = false;
631 static int auxlast[POW3TO7];
632 static int auxarr[8];
633 static unsigned int ui;
634
635 if (!initialized) {
636 for (ui = 0; ui < POW3TO7; ui++) {
637 int_to_sum_zero_array(ui, 3, 8, auxarr);
638 auxlast[ui] = auxarr[7];
639 }
640
641 initialized = true;
642 }
643
644 if (c < 7)
645 return (co / powint(3, c)) % 3;
646 else
647 return auxlast[co];
648}
649
650int
651what_orientation_edge(int eo, Edge e)
652{
653 static bool initialized = false;
654 static int auxlast[POW2TO11];
655 static int auxarr[12];
656 static unsigned int ui;
657
658 if (!initialized) {
659 for (ui = 0; ui < POW2TO11; ui++) {
660 int_to_sum_zero_array(ui, 2, 12, auxarr);
661 auxlast[ui] = auxarr[11];
662 }
663
664 initialized = true;
665 }
666
667 if (e < 11)
668 return (eo & (1 << e)) ? 1 : 0;
669 else
670 return auxlast[eo];
671}
672
673Center
674where_is_center(Cube cube, Center c)
675{
676 static bool initialized = false;
677 static Center aux[FACTORIAL6][6];
678 static int i;
679 static unsigned int ui;
680 static CubeArray *arr;
681
682 if (!initialized) {
683 for (ui = 0; ui < FACTORIAL6; ui++) {
684 arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
685 for (i = 0; i < 6; i++)
686 aux[ui][arr->cpos[i]] = i;
687 free_cubearray(arr, pf_cpos);
688 }
689
690 initialized = true;
691 }
692
693 return aux[cube.cpos][c];
694}
695
696Corner
697where_is_corner(Cube cube, Corner c)
698{
699 static bool initialized = false;
700 static Corner aux[FACTORIAL8][8];
701 static int i;
702 static unsigned int ui;
703 static CubeArray *arr;
704
705 if (!initialized) {
706 for (ui = 0; ui < FACTORIAL8; ui++) {
707 arr = new_cubearray((Cube){.cp = ui}, pf_cp);
708 for (i = 0; i < 8; i++)
709 aux[ui][arr->cp[i]] = i;
710 free_cubearray(arr, pf_cp);
711 }
712
713 initialized = true;
714 }
715 return aux[cube.cp][c];
716}
717
718Edge
719where_is_edge(Cube c, Edge e)
720{
721 int r0, r1, r2;
722
723 static bool initialized = false;
724 static int aux[3][BINOM12ON4*FACTORIAL4][12];
725 static int i, j;
726 static unsigned int ui;
727 static CubeArray *arr;
728
729 if (!initialized) {
730 for (ui = 0; ui < BINOM12ON4*FACTORIAL4; ui++) {
731 for (i = 0; i < 3; i++)
732 for (j = 0; j < 12; j++)
733 aux[i][ui][j] = -1;
734
735 arr = new_cubearray((Cube){.epose = ui}, pf_e);
736 for (i = 0; i < 12; i++)
737 if (edge_slice(arr->ep[i]) == 0)
738 aux[0][ui][arr->ep[i]] = i;
739 free_cubearray(arr, pf_e);
740
741 arr = new_cubearray((Cube){.eposs = ui}, pf_s);
742 for (i = 0; i < 12; i++)
743 if (edge_slice(arr->ep[i]) == 1)
744 aux[1][ui][arr->ep[i]] = i;
745 free_cubearray(arr, pf_s);
746
747 arr = new_cubearray((Cube){.eposm = ui}, pf_m);
748 for (i = 0; i < 12; i++)
749 if (edge_slice(arr->ep[i]) == 2)
750 aux[2][ui][arr->ep[i]] = i;
751 free_cubearray(arr, pf_m);
752 }
753
754 initialized = true;
755 }
756
757 r0 = aux[0][c.epose][e];
758 r1 = aux[1][c.eposs][e];
759 r2 = aux[2][c.eposm][e];
760 return MAX(r0, MAX(r1, r2));
761}
762
763static bool
764read_invtables_file()
765{
766 init_env();
767
768 FILE *f;
769 char fname[strlen(tabledir)+20];
770 int b;
771 unsigned int ui, meeo, meco, mecp, mecpos;
772 bool r;
773
774 strcpy(fname, tabledir);
775 strcat(fname, "/invtables");
776
777 if ((f = fopen(fname, "rb")) == NULL)
778 return false;
779
780 b = sizeof(uint16_t);
781 r = true;
782 meeo = BINOM12ON4*FACTORIAL4;
783 meco = FACTORIAL8;
784 mecp = FACTORIAL8;
785 mecpos = FACTORIAL6;
786
787 for (ui = 0; ui < POW2TO11; ui++) {
788 r = r && fread(eo_invtable_e[ui], b, meeo, f) == meeo;
789 r = r && fread(eo_invtable_m[ui], b, meeo, f) == meeo;
790 r = r && fread(eo_invtable_s[ui], b, meeo, f) == meeo;
791 }
792
793 for (ui = 0; ui < POW3TO7; ui++) {
794 r = r && fread(co_invtable[ui], b, meco, f) == meco;
795 }
796
797 r = r && fread(cp_invtable, b, mecp, f) == mecp;
798 r = r && fread(cpos_invtable, b, mecpos, f) == mecpos;
799
800 fclose(f);
801 return r;
802}
803
804static bool
805write_invtables_file()
806{
807 init_env();
808
809 FILE *f;
810 char fname[strlen(tabledir)+20];
811 unsigned int ui, meeo, meco, mecp, mecpos;
812 int b;
813 bool r;
814
815 strcpy(fname, tabledir);
816 strcat(fname, "/invtables");
817
818 if ((f = fopen(fname, "wb")) == NULL)
819 return false;
820
821 b = sizeof(uint16_t);
822 r = true;
823 meeo = BINOM12ON4*FACTORIAL4;
824 meco = FACTORIAL8;
825 mecp = FACTORIAL8;
826 mecpos = FACTORIAL6;
827
828 for (ui = 0; ui < POW2TO11; ui++) {
829 r = r && fwrite(eo_invtable_e[ui], b, meeo, f) == meeo;
830 r = r && fwrite(eo_invtable_m[ui], b, meeo, f) == meeo;
831 r = r && fwrite(eo_invtable_s[ui], b, meeo, f) == meeo;
832 }
833
834 for (ui = 0; ui < POW3TO7; ui++) {
835 r = r && fwrite(co_invtable[ui], b, meco, f) == meco;
836 }
837
838 r = r && fwrite(cp_invtable, b, mecp, f) == mecp;
839 r = r && fwrite(cpos_invtable, b, mecpos, f) == mecpos;
840
841 fclose(f);
842 return r;
843}
844
845void
846init_inverse()
847{
848 static bool initialized = false;
849 if (initialized)
850 return;
851 initialized = true;
852
853 if (read_invtables_file())
854 return;
855
856 fprintf(stderr, "Cannot load invtables, generating it\n");
857
858 CubeArray *aux, *inv;
859 Cube c;
860 int i, j, eoaux[12], eoinv[12];
861 unsigned int ui, uj;
862
863 aux = new_cubearray((Cube){0}, pf_all);
864 inv = new_cubearray((Cube){0}, pf_all);
865
866 for (ui = 0; ui < POW2TO11; ui++) {
867 int_to_sum_zero_array(ui, 2, 12, eoaux);
868 for (uj = 0; uj < BINOM12ON4*FACTORIAL4; uj++) {
869 for (j = 0; j < 12; j++)
870 eoinv[j] = 0;
871 c = (Cube){.epose = uj, .eposm = 0, .eposs = 0};
872 eoinv[FR] = eoaux[where_is_edge(c, FR)];
873 eoinv[FL] = eoaux[where_is_edge(c, FL)];
874 eoinv[BL] = eoaux[where_is_edge(c, BL)];
875 eoinv[BR] = eoaux[where_is_edge(c, BR)];
876 eo_invtable_e[ui][uj] = digit_array_to_int(eoinv,11,2);
877
878 for (j = 0; j < 12; j++)
879 eoinv[j] = 0;
880 c = (Cube){.epose = 0, .eposm = uj, .eposs = 0};
881 eoinv[UF] = eoaux[where_is_edge(c, UF)];
882 eoinv[UB] = eoaux[where_is_edge(c, UB)];
883 eoinv[DF] = eoaux[where_is_edge(c, DF)];
884 eoinv[DB] = eoaux[where_is_edge(c, DB)];
885 eo_invtable_m[ui][uj] = digit_array_to_int(eoinv,11,2);
886
887 for (j = 0; j < 12; j++)
888 eoinv[j] = 0;
889 c = (Cube){.epose = 0, .eposm = 0, .eposs = uj};
890 eoinv[UL] = eoaux[where_is_edge(c, UL)];
891 eoinv[UR] = eoaux[where_is_edge(c, UR)];
892 eoinv[DL] = eoaux[where_is_edge(c, DL)];
893 eoinv[DR] = eoaux[where_is_edge(c, DR)];
894 eo_invtable_s[ui][uj] = digit_array_to_int(eoinv,11,2);
895 }
896 }
897
898 for (ui = 0; ui < FACTORIAL8; ui++) {
899 cube_to_arrays((Cube){.cp = ui}, aux, pf_cp);
900 for (i = 0; i < 8; i++)
901 inv->cp[aux->cp[i]] = i;
902 cp_invtable[ui] = (uint16_t)arrays_to_cube(inv, pf_cp).cp;
903
904 for (uj = 0; uj < POW3TO7; uj++) {
905 cube_to_arrays((Cube){.coud = uj}, aux, pf_coud);
906 for (i = 0; i < 8; i++)
907 inv->coud[aux->cp[i]] = (3-aux->coud[i])%3;
908 co_invtable[uj][ui] =
909 (uint16_t)arrays_to_cube(inv, pf_coud).coud;
910 }
911 }
912
913 for (ui = 0; ui < FACTORIAL6; ui++) {
914 cube_to_arrays((Cube){.cpos = ui}, aux, pf_cpos);
915 for (i = 0; i < 6; i++)
916 inv->cpos[aux->cpos[i]] = i;
917 cpos_invtable[ui] =
918 (uint16_t)arrays_to_cube(inv, pf_cpos).cpos;
919 }
920
921 free_cubearray(aux, pf_all);
922 free_cubearray(inv, pf_all);
923
924 if (!write_invtables_file())
925 fprintf(stderr, "Error writing invtables\n");
926}
927
928void
929init_cube()
930{
931 init_inverse();
932}

Generated with cgit - Back to sebastiano.tronto.net