aboutsummaryrefslogtreecommitdiff
path: root/old/2021-11-10-beforeremovingchecker/cube.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--old/2021-11-10-beforeremovingchecker/cube.c716
1 files changed, 716 insertions, 0 deletions
diff --git a/old/2021-11-10-beforeremovingchecker/cube.c b/old/2021-11-10-beforeremovingchecker/cube.c
new file mode 100644
index 0000000..b621d7b
--- /dev/null
+++ b/old/2021-11-10-beforeremovingchecker/cube.c
@@ -0,0 +1,716 @@
1#include "cube.h"
2
3/* Local functions **********************************************************/
4
5static int array_ep_to_epos(int *ep, int *eps_solved);
6static int epos_from_arrays(int *epos, int *ep);
7
8/* Local functions implementation ********************************************/
9
10static int
11array_ep_to_epos(int *ep, int *ss)
12{
13 int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
14 int eps[4];
15 int i, j, is;
16
17 for (i = 0, is = 0; i < 12; i++) {
18 for (j = 0; j < 4; j++) {
19 if (ep[i] == ss[j]) {
20 eps[is++] = j;
21 epos[i] = 1;
22 }
23 }
24 }
25
26 for (i = 0; i < 4; i++)
27 swap(&epos[ss[i]], &epos[i+8]);
28
29 return epos_from_arrays(epos, eps);
30}
31
32static int
33epos_from_arrays(int *epos, int *ep)
34{
35 return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
36}
37
38/* Public functions implementation *******************************************/
39
40Cube
41arrays_to_cube(CubeArray *arr, PieceFilter f)
42{
43 Cube ret = {0};
44
45 static int epe_solved[4] = {FR, FL, BL, BR};
46 static int eps_solved[4] = {UL, UR, DL, DR};
47 static int epm_solved[4] = {UF, UB, DF, DB};
48
49 if (f.epose)
50 ret.epose = array_ep_to_epos(arr->ep, epe_solved);
51 if (f.eposs)
52 ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
53 if (f.eposm)
54 ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
55 if (f.eofb)
56 ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
57 if (f.eorl)
58 ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
59 if (f.eoud)
60 ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
61 if (f.cp)
62 ret.cp = perm_to_index(arr->cp, 8);
63 if (f.coud)
64 ret.coud = digit_array_to_int(arr->coud, 7, 3);
65 if (f.corl)
66 ret.corl = digit_array_to_int(arr->corl, 7, 3);
67 if (f.cofb)
68 ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
69 if (f.cpos)
70 ret.cpos = perm_to_index(arr->cpos, 6);
71
72 return ret;
73}
74
75Cube
76compose_filtered(Cube c2, Cube c1, PieceFilter f)
77{
78 CubeArray *arr = new_cubearray(c2, f);
79 Cube ret;
80
81 ret = move_via_arrays(arr, c1, f);
82 free_cubearray(arr, f);
83
84 return ret;
85}
86
87void
88cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
89{
90 int i;
91
92 static int epe_solved[4] = {FR, FL, BL, BR};
93 static int eps_solved[4] = {UL, UR, DL, DR};
94 static int epm_solved[4] = {UF, UB, DF, DB};
95
96 if (f.epose || f.eposs || f.eposm)
97 for (i = 0; i < 12; i++)
98 arr->ep[i] = -1;
99
100 if (f.epose)
101 epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
102 if (f.eposs)
103 epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
104 if (f.eposm)
105 epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
106 if (f.eofb)
107 int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
108 if (f.eorl)
109 int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
110 if (f.eoud)
111 int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
112 if (f.cp)
113 index_to_perm(cube.cp, 8, arr->cp);
114 if (f.coud)
115 int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
116 if (f.corl)
117 int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
118 if (f.cofb)
119 int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
120 if (f.cpos)
121 index_to_perm(cube.cpos, 6, arr->cpos);
122}
123
124void
125epos_to_partial_ep(int epos, int *ep, int *ss)
126{
127 int i, is, eposs[12], eps[4];
128
129 index_to_perm(epos % FACTORIAL4, 4, eps);
130 index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
131
132 for (i = 0; i < 4; i++)
133 swap(&eposs[ss[i]], &eposs[i+8]);
134
135 for (i = 0, is = 0; i < 12; i++)
136 if (eposs[i])
137 ep[i] = ss[eps[is++]];
138}
139
140void
141free_cubearray(CubeArray *arr, PieceFilter f)
142{
143 if (f.epose || f.eposs || f.eposm)
144 free(arr->ep);
145 if (f.eofb)
146 free(arr->eofb);
147 if (f.eorl)
148 free(arr->eorl);
149 if (f.eoud)
150 free(arr->eoud);
151 if (f.cp)
152 free(arr->cp);
153 if (f.coud)
154 free(arr->coud);
155 if (f.corl)
156 free(arr->corl);
157 if (f.cofb)
158 free(arr->cofb);
159 if (f.cpos)
160 free(arr->cpos);
161
162 free(arr);
163}
164
165Cube
166move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
167{
168 CubeArray *arrc = new_cubearray(c, f);
169 Cube ret;
170
171 if (f.epose || f.eposs || f.eposm)
172 apply_permutation(arr->ep, arrc->ep, 12);
173
174 if (f.eofb) {
175 apply_permutation(arr->ep, arrc->eofb, 12);
176 sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
177 }
178
179 if (f.eorl) {
180 apply_permutation(arr->ep, arrc->eorl, 12);
181 sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
182 }
183
184 if (f.eoud) {
185 apply_permutation(arr->ep, arrc->eoud, 12);
186 sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
187 }
188
189 if (f.cp)
190 apply_permutation(arr->cp, arrc->cp, 8);
191
192 if (f.coud) {
193 apply_permutation(arr->cp, arrc->coud, 8);
194 sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
195 }
196
197 if (f.corl) {
198 apply_permutation(arr->cp, arrc->corl, 8);
199 sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
200 }
201
202 if (f.cofb) {
203 apply_permutation(arr->cp, arrc->cofb, 8);
204 sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
205 }
206
207 if (f.cpos)
208 apply_permutation(arr->cpos, arrc->cpos, 6);
209
210 ret = arrays_to_cube(arrc, f);
211 free_cubearray(arrc, f);
212
213 return ret;
214}
215
216CubeArray *
217new_cubearray(Cube cube, PieceFilter f)
218{
219 CubeArray *arr = malloc(sizeof(CubeArray));
220
221 if (f.epose || f.eposs || f.eposm)
222 arr->ep = malloc(12 * sizeof(int));
223 if (f.eofb)
224 arr->eofb = malloc(12 * sizeof(int));
225 if (f.eorl)
226 arr->eorl = malloc(12 * sizeof(int));
227 if (f.eoud)
228 arr->eoud = malloc(12 * sizeof(int));
229 if (f.cp)
230 arr->cp = malloc(8 * sizeof(int));
231 if (f.coud)
232 arr->coud = malloc(8 * sizeof(int));
233 if (f.corl)
234 arr->corl = malloc(8 * sizeof(int));
235 if (f.cofb)
236 arr->cofb = malloc(8 * sizeof(int));
237 if (f.cpos)
238 arr->cpos = malloc(6 * sizeof(int));
239
240 cube_to_arrays(cube, arr, f);
241
242 return arr;
243}
244
245
246/* TODO: consider if this is good here or better in coord.c
247 in any case it is used in transformation init at the moment */
248Cube
249admissible_ep(Cube cube, PieceFilter f)
250{
251 CubeArray *arr = new_cubearray(cube, f);
252 Cube ret;
253 bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
254 int i, j;
255
256 for (i = 0; i < 12; i++)
257 if (arr->ep[i] != -1)
258 used[arr->ep[i]] = true;
259
260 for (i = 0, j = 0; i < 12; i++) {
261 for ( ; j < 11 && used[j]; j++);
262 if (arr->ep[i] == -1)
263 arr->ep[i] = j++;
264 }
265
266 ret = arrays_to_cube(arr, pf_ep);
267 free_cubearray(arr, f);
268
269 return ret;
270}
271
272Cube
273compose(Cube c2, Cube c1)
274{
275 return compose_filtered(c2, c1, pf_all);
276}
277
278int
279edge_slice(Edge e) {
280 if (e < 0 || e > 11)
281 return -1;
282
283 if (e == FR || e == FL || e == BL || e == BR)
284 return 0;
285 if (e == UR || e == UL || e == DR || e == DL)
286 return 1;
287
288 return 2;
289}
290
291bool
292equal(Cube c1, Cube c2)
293{
294 return c1.eofb == c2.eofb &&
295 c1.epose == c2.epose &&
296 c1.eposs == c2.eposs &&
297 c1.eposm == c2.eposm &&
298 c1.coud == c2.coud &&
299 c1.cp == c2.cp &&
300 c1.cpos == c2.cpos;
301}
302
303Cube
304inverse_cube(Cube cube)
305{
306 CubeArray *arr = new_cubearray(cube, pf_all);
307 CubeArray *inv = new_cubearray((Cube){0}, pf_all);
308 Cube ret;
309 int i;
310
311 for (i = 0; i < 12; i++) {
312 inv->ep[arr->ep[i]] = i;
313 inv->eofb[arr->ep[i]] = arr->eofb[i];
314 inv->eorl[arr->ep[i]] = arr->eorl[i];
315 inv->eoud[arr->ep[i]] = arr->eoud[i];
316 }
317
318 for (i = 0; i < 8; i++) {
319 inv->cp[arr->cp[i]] = i;
320 inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
321 inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
322 inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
323 }
324
325 for (int i = 0; i < 6; i++)
326 inv->cpos[arr->cpos[i]] = i;
327
328 ret = arrays_to_cube(inv, pf_all);
329 free_cubearray(arr, pf_all);
330 free_cubearray(inv, pf_all);
331
332 return ret;
333}
334
335bool
336is_admissible(Cube cube)
337{
338 /* TODO: this should check consistency of different orientations */
339 /* TODO: check that centers are opposite and admissible */
340
341 CubeArray *a = new_cubearray(cube, pf_all);
342 int parity;
343 bool perm;
344
345 perm = is_perm(a->ep, 12) &&
346 is_perm(a->cp, 8) &&
347 is_perm(a->cpos, 6);
348 parity = perm_sign(a->ep, 12) +
349 perm_sign(a->cp, 8) +
350 perm_sign(a->cpos, 6);
351
352 return perm && parity % 2 == 0;
353}
354
355bool
356is_solved(Cube cube)
357{
358 /* TODO: move somewhere else, like in solve.c
359 int i;
360 if (reorient) {
361 for (i = 0; i < NROTATIONS; i++)
362 if (is_solved(apply_alg(rotation_algs[i], cube),false))
363 return true;
364 return false;
365 } else {
366 return equal(cube, (Cube){0});
367 }
368 */
369
370 return equal(cube, (Cube){0});
371}
372
373bool
374is_solved_block(Cube cube, Block block)
375{
376 int i;
377
378 for (i = 0; i < 12; i++)
379 if (block.edge[i] && !is_solved_edge(cube, i))
380 return false;
381 for (i = 0; i < 8; i++)
382 if (block.corner[i] && !is_solved_corner(cube, i))
383 return false;
384 for (i = 0; i < 6; i++)
385 if (block.center[i] && !is_solved_center(cube, i))
386 return false;
387
388 return true;
389}
390
391bool
392is_solved_center(Cube cube, Center c)
393{
394 return what_center_at(cube, c) == c;
395}
396
397bool
398is_solved_corner(Cube cube, Corner c)
399{
400 return what_corner_at(cube, c) == c &&
401 what_orientation_corner(cube.coud, c);
402}
403
404bool
405is_solved_edge(Cube cube, Edge e)
406{
407 return what_edge_at(cube, e) == e &&
408 what_orientation_edge(cube.eofb, e);
409}
410
411int
412piece_orientation(Cube cube, int piece, char *orientation)
413{
414 int arr[12], n, b, x;
415
416 if (!strcmp(orientation, "eofb")) {
417 x = cube.eofb;
418 n = 12;
419 b = 2;
420 } else if (!strcmp(orientation, "eorl")) {
421 x = cube.eorl;
422 n = 12;
423 b = 2;
424 } else if (!strcmp(orientation, "eoud")) {
425 x = cube.eoud;
426 n = 12;
427 b = 2;
428 } else if (!strcmp(orientation, "coud")) {
429 x = cube.coud;
430 n = 8;
431 b = 3;
432 } else if (!strcmp(orientation, "corl")) {
433 x = cube.corl;
434 n = 8;
435 b = 3;
436 } else if (!strcmp(orientation, "cofb")) {
437 x = cube.cofb;
438 n = 8;
439 b = 3;
440 } else {
441 return -1;
442 }
443
444 int_to_sum_zero_array(x, b, n, arr);
445 if (piece < n)
446 return arr[piece];
447
448 return -1;
449}
450
451void
452print_cube(Cube cube)
453{
454 static char edge_string[12][7] = {
455 [UF] = "UF", [UL] = "UL", [UB] = "UB", [UR] = "UR",
456 [DF] = "DF", [DL] = "DL", [DB] = "DB", [DR] = "DR",
457 [FR] = "FR", [FL] = "FL", [BL] = "BL", [BR] = "BR"
458 };
459
460 static char corner_string[8][7] = {
461 [UFR] = "UFR", [UFL] = "UFL", [UBL] = "UBL", [UBR] = "UBR",
462 [DFR] = "DFR", [DFL] = "DFL", [DBL] = "DBL", [DBR] = "DBR"
463 };
464
465 static char center_string[6][7] = {
466 [U_center] = "U", [D_center] = "D",
467 [R_center] = "R", [L_center] = "L",
468 [F_center] = "F", [B_center] = "B"
469 };
470
471 for (int i = 0; i < 12; i++)
472 printf(" %s ", edge_string[what_edge_at(cube, i)]);
473 printf("\n");
474
475 for (int i = 0; i < 12; i++)
476 printf(" %d ", what_orientation_edge(cube.eofb, i));
477 printf("\n");
478
479 for (int i = 0; i < 8; i++)
480 printf("%s ", corner_string[what_corner_at(cube, i)]);
481 printf("\n");
482
483 for (int i = 0; i < 8; i++)
484 printf(" %d ", what_orientation_corner(cube.coud, i));
485 printf("\n");
486
487 for (int i = 0; i < 6; i++)
488 printf(" %s ", center_string[what_center_at(cube, i)]);
489 printf("\n");
490}
491
492Cube
493random_cube()
494{
495 CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
496 Cube ret;
497 int ep, cp, eo, co;
498
499 ep = rand() % FACTORIAL12;
500 cp = rand() % FACTORIAL8;
501 eo = rand() % POW2TO11;
502 co = rand() % POW3TO7;
503
504 index_to_perm(ep, 12, arr->ep);
505 index_to_perm(cp, 8, arr->cp);
506 int_to_sum_zero_array(eo, 2, 12, arr->eofb);
507 int_to_sum_zero_array(co, 3, 8, arr->coud);
508
509 if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
510 swap(&(arr->ep[0]), &(arr->ep[1]));
511
512 ret = arrays_to_cube(arr, pf_4val);
513 free_cubearray(arr, pf_4val);
514
515 return ret;
516}
517
518Center
519what_center_at(Cube cube, Center c)
520{
521 static bool initialized = false;
522 static Center aux[FACTORIAL6][6];
523 static int i;
524 static unsigned int ui;
525 static CubeArray *arr;
526
527 if (!initialized) {
528 for (ui = 0; ui < FACTORIAL6; ui++) {
529 arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
530 for (i = 0; i < 6; i++)
531 aux[ui][i] = arr->cpos[i];
532 free_cubearray(arr, pf_cpos);
533 }
534
535 initialized = true;
536 }
537
538 return aux[cube.cpos][c];
539}
540
541Corner
542what_corner_at(Cube cube, Corner c)
543{
544 static bool initialized = false;
545 static Corner aux[FACTORIAL8][8];
546 static int i;
547 static unsigned int ui;
548 static CubeArray *arr;
549
550 if (!initialized) {
551 for (ui = 0; ui < FACTORIAL8; ui++) {
552 arr = new_cubearray((Cube){.cp = ui}, pf_cp);
553 for (i = 0; i < 8; i++)
554 aux[ui][i] = arr->cp[i];
555 free_cubearray(arr, pf_cp);
556 }
557
558 initialized = true;
559 }
560
561 return aux[cube.cp][c];
562}
563
564Edge
565what_edge_at(Cube cube, Edge e)
566{
567 Edge ret;
568 CubeArray *arr = new_cubearray(cube, pf_ep);
569
570 ret = arr->ep[e];
571
572 free_cubearray(arr, pf_ep);
573 return ret;
574}
575
576int
577what_orientation_corner(int co, Corner c)
578{
579 static bool initialized = false;
580 static int auxlast[POW3TO7];
581 static int auxarr[8];
582 static unsigned int ui;
583
584 if (!initialized) {
585 for (ui = 0; ui < POW3TO7; ui++) {
586 int_to_sum_zero_array(ui, 3, 8, auxarr);
587 auxlast[ui] = auxarr[7];
588 }
589
590 initialized = true;
591 }
592
593 if (c < 7)
594 return (co / powint(3, c)) % 3;
595 else
596 return auxlast[co];
597}
598
599int
600what_orientation_edge(int eo, Edge e)
601{
602 static bool initialized = false;
603 static int auxlast[POW2TO11];
604 static int auxarr[12];
605 static unsigned int ui;
606
607 if (!initialized) {
608 for (ui = 0; ui < POW2TO11; ui++) {
609 int_to_sum_zero_array(ui, 2, 12, auxarr);
610 auxlast[ui] = auxarr[11];
611 }
612
613 initialized = true;
614 }
615
616 if (e < 11)
617 return (eo & (1 << e)) ? 1 : 0;
618 else
619 return auxlast[eo];
620}
621
622Center
623where_is_center(Cube cube, Center c)
624{
625 static bool initialized = false;
626 static Center aux[FACTORIAL6][6];
627 static int i;
628 static unsigned int ui;
629 static CubeArray *arr;
630
631 if (!initialized) {
632 for (ui = 0; ui < FACTORIAL6; ui++) {
633 arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
634 for (i = 0; i < 6; i++)
635 aux[ui][arr->cpos[i]] = i;
636 free_cubearray(arr, pf_cpos);
637 }
638
639 initialized = true;
640 }
641
642 return aux[cube.cpos][c];
643}
644
645Corner
646where_is_corner(Cube cube, Corner c)
647{
648 static bool initialized = false;
649 static Corner aux[FACTORIAL8][8];
650 static int i;
651 static unsigned int ui;
652 static CubeArray *arr;
653
654 if (!initialized) {
655 for (ui = 0; ui < FACTORIAL8; ui++) {
656 arr = new_cubearray((Cube){.cp = ui}, pf_cp);
657 for (i = 0; i < 8; i++)
658 aux[ui][arr->cp[i]] = i;
659 free_cubearray(arr, pf_cp);
660 }
661
662 initialized = true;
663 }
664 return aux[cube.cp][c];
665}
666
667Edge
668where_is_edge(Cube cube, Edge e)
669{
670 /* TODO: when I wrote this code I forgot to add the final
671 part, and now I can't remember how it was supposed to
672 work (i.e. how to recover the location of the edge
673 from these tables. I think it is either very easy or
674 wrong, in any case it is not a priority now.
675 Future Seba can deal with it.
676
677 static bool initialized = false;
678 static Edge aux[3][FACTORIAL12/FACTORIAL8][12];
679 static int i;
680 static unsigned int ui;
681 static CubeArray *arr;
682
683 if (!initialized) {
684 for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
685 arr = new_cubearray((Cube){.epose = ui}, pf_e);
686 for (i = 0; i < 12; i++)
687 if (edge_slice(arr->ep[i]) == 0)
688 aux[0][ui][arr->ep[i]] = i;
689 free_cubearray(arr, pf_e);
690
691 arr = new_cubearray((Cube){.eposs = ui}, pf_s);
692 for (i = 0; i < 12; i++)
693 if (edge_slice(arr->ep[i]) == 1)
694 aux[1][ui][arr->ep[i]] = i;
695 free_cubearray(arr, pf_s);
696
697 arr = new_cubearray((Cube){.eposm = ui}, pf_m);
698 for (i = 0; i < 12; i++)
699 if (edge_slice(arr->ep[i]) == 2)
700 aux[2][ui][arr->ep[i]] = i;
701 free_cubearray(arr, pf_m);
702 }
703
704 initialized = true;
705 }
706 */
707
708 int i;
709 CubeArray *arr = new_cubearray(cube, pf_ep);
710
711 for (i = 0; i < 12; i++)
712 if ((Edge)arr->ep[i] == e)
713 return i;
714
715 return -1;
716}

Generated with cgit - Back to sebastiano.tronto.net