aboutsummaryrefslogtreecommitdiff
path: root/src/alg.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/alg.c295
1 files changed, 180 insertions, 115 deletions
diff --git a/src/alg.c b/src/alg.c
index d806178..52bebc0 100644
--- a/src/alg.c
+++ b/src/alg.c
@@ -1,11 +1,112 @@
1#define ALG_C
2
3#include "alg.h" 1#include "alg.h"
4 2
3/* Local functions ***********************************************************/
4
5static bool allowed_HTM(Move m);
6static bool allowed_URF(Move m);
7static bool allowed_eofb(Move m);
8static bool allowed_drud(Move m);
9static bool allowed_htr(Move m);
10static bool allowed_next_HTM(Move l2, Move l1, Move m);
5static int axis(Move m); 11static int axis(Move m);
12
6static void free_alglistnode(AlgListNode *aln); 13static void free_alglistnode(AlgListNode *aln);
7static void realloc_alg(Alg *alg, int n); 14static void realloc_alg(Alg *alg, int n);
8 15
16/* Movesets ******************************************************************/
17
18Moveset
19moveset_HTM = {
20 .allowed = allowed_HTM,
21 .allowed_next = allowed_next_HTM,
22};
23
24Moveset
25moveset_URF = {
26 .allowed = allowed_URF,
27 .allowed_next = allowed_next_HTM,
28};
29
30Moveset
31moveset_eofb = {
32 .allowed = allowed_eofb,
33 .allowed_next = allowed_next_HTM,
34};
35
36Moveset
37moveset_drud = {
38 .allowed = allowed_drud,
39 .allowed_next = allowed_next_HTM,
40};
41
42Moveset
43moveset_htr = {
44 .allowed = allowed_htr,
45 .allowed_next = allowed_next_HTM,
46};
47
48static int nmoveset = 5;
49static Moveset * all_ms[] = {
50 &moveset_HTM,
51 &moveset_URF,
52 &moveset_eofb,
53 &moveset_drud,
54 &moveset_htr,
55};
56
57/* Functions *****************************************************************/
58
59static bool
60allowed_HTM(Move m)
61{
62 return m >= U && m <= B3;
63}
64
65static bool
66allowed_URF(Move m)
67{
68 Move b = base_move(m);
69
70 return b == U || b == R || b == F;
71}
72
73static bool
74allowed_eofb(Move m)
75{
76 Move b = base_move(m);
77
78 return b == U || b == D || b == R || b == L ||
79 ((b == F || b == B) && m == b+1);
80}
81
82static bool
83allowed_drud(Move m)
84{
85 Move b = base_move(m);
86
87 return b == U || b == D ||
88 ((b == R || b == L || b == F || b == B) && m == b + 1);
89}
90
91static bool
92allowed_htr(Move m)
93{
94 Move b = base_move(m);
95
96 return moveset_HTM.allowed(m) && m == b + 1;
97}
98
99static bool
100allowed_next_HTM(Move l2, Move l1, Move m)
101{
102 bool p, q;
103
104 p = l1 != NULLMOVE && base_move(l1) == base_move(m);
105 q = l2 != NULLMOVE && base_move(l2) == base_move(m);
106
107 return !(p || (commute(l1, l2) && q));
108}
109
9void 110void
10append_alg(AlgList *l, Alg *alg) 111append_alg(AlgList *l, Alg *alg)
11{ 112{
@@ -33,42 +134,30 @@ append_move(Alg *alg, Move m, bool inverse)
33 alg->move[alg->len] = m; 134 alg->move[alg->len] = m;
34 alg->inv [alg->len] = inverse; 135 alg->inv [alg->len] = inverse;
35 alg->len++; 136 alg->len++;
36
37 if (inverse)
38 alg->move_inverse[alg->len_inverse++] = m;
39 else
40 alg->move_normal[alg->len_normal++] = m;
41} 137}
42 138
43static int 139static int
44axis(Move m) 140axis(Move m)
45{ 141{
46 static int aux[] = { 142 if (m == NULLMOVE)
47 [NULLMOVE] = 0, 143 return 0;
48 144
49 [U] = 1, [U2] = 1, [U3] = 1, 145 if (m >= U && m <= B3)
50 [D] = 1, [D2] = 1, [D3] = 1, 146 return (m-1)/6 + 1;
51 [Uw] = 1, [Uw2] = 1, [Uw3] = 1, 147
52 [Dw] = 1, [Dw2] = 1, [Dw3] = 1, 148 if (m >= Uw && m <= Bw3)
53 [E] = 1, [E2] = 1, [E3] = 1, 149 return (m-1)/6 - 2;
54 [y] = 1, [y2] = 1, [y3] = 1,
55 150
56 [R] = 2, [R2] = 2, [R3] = 2, 151 if (base_move(m) == E || base_move(m) == y)
57 [L] = 2, [L2] = 2, [L3] = 2, 152 return 1;
58 [Rw] = 2, [Rw2] = 2, [Rw3] = 2,
59 [Lw] = 2, [Lw2] = 2, [Lw3] = 2,
60 [M] = 2, [M2] = 2, [M3] = 2,
61 [x] = 2, [x2] = 2, [x3] = 2,
62 153
63 [F] = 3, [F2] = 3, [F3] = 3, 154 if (base_move(m) == M || base_move(m) == x)
64 [B] = 3, [B2] = 3, [B3] = 3, 155 return 2;
65 [Fw] = 3, [Fw2] = 3, [Fw3] = 3, 156
66 [Bw] = 3, [Bw2] = 3, [Bw3] = 3, 157 if (base_move(m) == S || base_move(m) == z)
67 [S] = 3, [S2] = 3, [S3] = 3, 158 return 3;
68 [z] = 3, [z2] = 3, [z3] = 3,
69 };
70 159
71 return aux[m]; 160 return -1;
72} 161}
73 162
74Move 163Move
@@ -86,32 +175,6 @@ commute(Move m1, Move m2)
86 return axis(m1) == axis(m2); 175 return axis(m1) == axis(m2);
87} 176}
88 177
89int
90compare(Move m1, Move m2)
91{
92 if (!commute(m1, m2))
93 return 0;
94
95 return m1 < m2 ? 1 : -1;
96}
97
98int
99compare_last(Alg *alg, Move m, bool inverse)
100{
101 Move last;
102 int n;
103
104 if (inverse) {
105 n = alg->len_inverse;
106 last = n > 0 ? alg->move_inverse[n-1] : NULLMOVE;
107 } else {
108 n = alg->len_normal;
109 last = n > 0 ? alg->move_normal[n-1] : NULLMOVE;
110 }
111
112 return compare(last, m);
113}
114
115void 178void
116compose_alg(Alg *alg1, Alg *alg2) 179compose_alg(Alg *alg1, Alg *alg2)
117{ 180{
@@ -124,7 +187,7 @@ compose_alg(Alg *alg1, Alg *alg2)
124void 187void
125copy_alg(Alg *src, Alg *dst) 188copy_alg(Alg *src, Alg *dst)
126{ 189{
127 dst->len = dst->len_normal = dst->len_inverse = 0; 190 dst->len = 0; /* Overwrites */
128 compose_alg(dst, src); 191 compose_alg(dst, src);
129} 192}
130 193
@@ -156,6 +219,16 @@ free_alglistnode(AlgListNode *aln)
156 free(aln); 219 free(aln);
157} 220}
158 221
222void
223inplace(Alg * (*f)(Alg *), Alg *alg)
224{
225 Alg *aux;
226
227 aux = f(alg);
228 copy_alg(aux, alg);
229 free(aux);
230}
231
159Alg * 232Alg *
160inverse_alg(Alg *alg) 233inverse_alg(Alg *alg)
161{ 234{
@@ -211,14 +284,10 @@ new_alg(char *str)
211 Move j, m; 284 Move j, m;
212 285
213 alg = malloc(sizeof(Alg)); 286 alg = malloc(sizeof(Alg));
214 alg->allocated = 30; 287 alg->move = malloc(30 * sizeof(Move));
215 alg->move = malloc(alg->allocated * sizeof(Move)); 288 alg->inv = malloc(30 * sizeof(bool));
216 alg->inv = malloc(alg->allocated * sizeof(bool)); 289 alg->allocated = 30;
217 alg->move_normal = malloc(alg->allocated * sizeof(Move)); 290 alg->len = 0;
218 alg->move_inverse = malloc(alg->allocated * sizeof(Move));
219 alg->len = 0;
220 alg->len_normal = 0;
221 alg->len_inverse = 0;
222 291
223 niss = false; 292 niss = false;
224 for (i = 0; str[i]; i++) { 293 for (i = 0; str[i]; i++) {
@@ -227,13 +296,13 @@ new_alg(char *str)
227 296
228 if (str[i] == '(' && niss) { 297 if (str[i] == '(' && niss) {
229 fprintf(stderr, "Error reading moves: nested ( )\n"); 298 fprintf(stderr, "Error reading moves: nested ( )\n");
230 alg->len = alg->len_normal = alg->len_inverse = 0; 299 alg->len = 0;
231 return alg; 300 return alg;
232 } 301 }
233 302
234 if (str[i] == ')' && !niss) { 303 if (str[i] == ')' && !niss) {
235 fprintf(stderr, "Error reading moves: unmatched )\n"); 304 fprintf(stderr, "Error reading moves: unmatched )\n");
236 alg->len = alg->len_normal = alg->len_inverse = 0; 305 alg->len = 0;
237 return alg; 306 return alg;
238 } 307 }
239 308
@@ -300,7 +369,7 @@ new_alg(char *str)
300 369
301 if (niss) { 370 if (niss) {
302 fprintf(stderr, "Error reading moves: unmatched (\n"); 371 fprintf(stderr, "Error reading moves: unmatched (\n");
303 alg->len = alg->len_normal = alg->len_inverse = 0; 372 alg->len = 0;
304 } 373 }
305 374
306 return alg; 375 return alg;
@@ -385,25 +454,12 @@ realloc_alg(Alg *alg, int n)
385 fprintf(stderr, "something might go wrong.\n"); 454 fprintf(stderr, "something might go wrong.\n");
386 } 455 }
387 456
388 alg->move = realloc(alg->move, n * sizeof(int)); 457 alg->move = realloc(alg->move, n * sizeof(int));
389 alg->inv = realloc(alg->inv, n * sizeof(int)); 458 alg->inv = realloc(alg->inv, n * sizeof(int));
390 alg->move_normal = realloc(alg->move_normal, n * sizeof(int));
391 alg->move_inverse = realloc(alg->move_inverse, n * sizeof(int));
392 alg->allocated = n; 459 alg->allocated = n;
393} 460}
394 461
395void 462void
396remove_last_move(Alg *a)
397{
398 a->len--;
399
400 if (a->inv[a->len])
401 a->len_inverse--;
402 else
403 a->len_normal--;
404}
405
406void
407swapmove(Move *m1, Move *m2) 463swapmove(Move *m1, Move *m2)
408{ 464{
409 Move aux; 465 Move aux;
@@ -413,34 +469,6 @@ swapmove(Move *m1, Move *m2)
413 *m2 = aux; 469 *m2 = aux;
414} 470}
415 471
416char *
417trans_string(Trans t)
418{
419 static char trans_string_aux[NTRANS][20] = {
420 [uf] = "uf", [ur] = "ur", [ub] = "ub", [ul] = "ul",
421 [df] = "df", [dr] = "dr", [db] = "db", [dl] = "dl",
422 [rf] = "rf", [rd] = "rd", [rb] = "rb", [ru] = "ru",
423 [lf] = "lf", [ld] = "ld", [lb] = "lb", [lu] = "lu",
424 [fu] = "fu", [fr] = "fr", [fd] = "fd", [fl] = "fl",
425 [bu] = "bu", [br] = "br", [bd] = "bd", [bl] = "bl",
426
427 [uf_mirror] = "uf*", [ur_mirror] = "ur*",
428 [ub_mirror] = "ub*", [ul_mirror] = "ul*",
429 [df_mirror] = "df*", [dr_mirror] = "dr*",
430 [db_mirror] = "db*", [dl_mirror] = "dl*",
431 [rf_mirror] = "rf*", [rd_mirror] = "rd*",
432 [rb_mirror] = "rb*", [ru_mirror] = "ru*",
433 [lf_mirror] = "lf*", [ld_mirror] = "ld*",
434 [lb_mirror] = "lb*", [lu_mirror] = "lu*",
435 [fu_mirror] = "fu*", [fr_mirror] = "fr*",
436 [fd_mirror] = "fd*", [fl_mirror] = "fl*",
437 [bu_mirror] = "bu*", [br_mirror] = "br*",
438 [bd_mirror] = "bd*", [bl_mirror] = "bl*",
439 };
440
441 return trans_string_aux[t];
442}
443
444Alg * 472Alg *
445unniss(Alg *alg) 473unniss(Alg *alg)
446{ 474{
@@ -449,11 +477,48 @@ unniss(Alg *alg)
449 477
450 ret = new_alg(""); 478 ret = new_alg("");
451 479
452 for (i = 0; i < alg->len_normal; i++) 480 for (i = 0; i < alg->len; i++)
453 append_move(ret, alg->move_normal[i], false); 481 if (!alg->inv[i])
482 append_move(ret, alg->move[i], false);
483
484 for (i = alg->len-1; i >= 0; i--)
485 if (alg->inv[i])
486 append_move(ret, inverse_move(alg->move[i]), false);
487
488 return ret;
489}
454 490
455 for (i = 0; i < alg->len_inverse; i++) 491void
456 append_move(ret, inverse_move(alg->move_inverse[i]), false); 492init_moveset(Moveset *ms)
493{
494 int j;
495 uint64_t l, one;
496 Move m, l2, l1;
457 497
458 return ret; 498 one = 1;
499
500 for (j = 0, m = U; m < NMOVES; m++)
501 if (ms->allowed(m))
502 ms->sorted_moves[j++] = m;
503 ms->sorted_moves[j] = NULLMOVE;
504
505 for (l1 = 0; l1 < NMOVES; l1++) {
506 for (l2 = 0; l2 < NMOVES; l2++) {
507 ms->mask[l2][l1] = 0;
508 for (l=0; ms->sorted_moves[l]!=NULLMOVE; l++) {
509 m = ms->sorted_moves[l];
510 if (ms->allowed_next(l2, l1, m))
511 ms->mask[l2][l1] |= (one<<m);
512 }
513 }
514 }
515}
516
517void
518init_all_movesets()
519{
520 int i;
521
522 for (i = 0; i < nmoveset; i++)
523 init_moveset(all_ms[i]);
459} 524}

Generated with cgit - Back to sebastiano.tronto.net