aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cube.c32
-rw-r--r--src/cube.h3
-rw-r--r--src/cubetypes.h3
-rw-r--r--src/fst.c291
-rw-r--r--src/fst.h1
-rw-r--r--src/shell.c2
-rw-r--r--src/trans.c2
7 files changed, 310 insertions, 24 deletions
diff --git a/src/cube.c b/src/cube.c
index 0ccffa4..c2a457c 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -2,6 +2,8 @@
2 2
3#include "cube.h" 3#include "cube.h"
4 4
5static int where_is_piece(int piece, int *arr, int n);
6
5void 7void
6compose(Cube *c2, Cube *c1) 8compose(Cube *c2, Cube *c1)
7{ 9{
@@ -154,3 +156,33 @@ print_cube(Cube *cube)
154 printf(" %s ", center_string[cube->xp[i]]); 156 printf(" %s ", center_string[cube->xp[i]]);
155 printf("\n"); 157 printf("\n");
156} 158}
159
160int
161where_is_center(Center x, Cube *c)
162{
163 return where_is_piece(x, c->xp, 6);
164}
165
166int
167where_is_corner(Corner k, Cube *c)
168{
169 return where_is_piece(k, c->cp, 8);
170}
171
172int
173where_is_edge(Edge e, Cube *c)
174{
175 return where_is_piece(e, c->ep, 12);
176}
177
178static int
179where_is_piece(int piece, int *arr, int n)
180{
181 int i;
182
183 for (i = 0; i < n; i++)
184 if (arr[i] == piece)
185 return i;
186
187 return -1;
188}
diff --git a/src/cube.h b/src/cube.h
index 9f8b23d..789bb2e 100644
--- a/src/cube.h
+++ b/src/cube.h
@@ -15,6 +15,9 @@ bool is_admissible(Cube *cube);
15bool is_solved(Cube *cube); 15bool is_solved(Cube *cube);
16void make_solved(Cube *cube); 16void make_solved(Cube *cube);
17void print_cube(Cube *cube); 17void print_cube(Cube *cube);
18int where_is_center(Center x, Cube *c);
19int where_is_corner(Corner k, Cube *c);
20int where_is_edge(Edge e, Cube *c);
18 21
19#endif 22#endif
20 23
diff --git a/src/cubetypes.h b/src/cubetypes.h
index bb1ad10..d4fa241 100644
--- a/src/cubetypes.h
+++ b/src/cubetypes.h
@@ -108,6 +108,7 @@ typedef void (*DfsExtraCopier) (void *, void *);
108typedef bool (*Validator) (Alg *); 108typedef bool (*Validator) (Alg *);
109typedef void (*Exec) (CommandArgs *); 109typedef void (*Exec) (CommandArgs *);
110typedef CommandArgs * (*ArgParser) (int, char **); 110typedef CommandArgs * (*ArgParser) (int, char **);
111typedef bool (*Tester) (void);
111typedef int (*TransFinder) (uint64_t, Trans *); 112typedef int (*TransFinder) (uint64_t, Trans *);
112 113
113 114
@@ -239,7 +240,7 @@ fstcube
239 uint16_t rd_eofb; 240 uint16_t rd_eofb;
240 uint16_t rd_eposepe; 241 uint16_t rd_eposepe;
241 uint16_t rd_coud; 242 uint16_t rd_coud;
242} 243};
243 244
244struct 245struct
245indexer 246indexer
diff --git a/src/fst.c b/src/fst.c
index 91c022a..ebd3333 100644
--- a/src/fst.c
+++ b/src/fst.c
@@ -2,7 +2,30 @@
2 2
3#include "fst.h" 3#include "fst.h"
4 4
5static void fst_to_ep(FstCube fst, int *ep); 5static FstCube ep_to_fst_epos(int *ep);
6static int fst_where_is_edge(int e, FstCube fst);
7static void transform_ep_only(Trans t, int *ep, Cube *dst);
8static void init_fst_corner_invtables();
9static void init_fst_eo_invtables();
10static void init_fst_eo_update(uint64_t, uint64_t, int, Cube *);
11static void init_fst_transalg();
12static void init_fst_where_is_edge();
13
14static int edge_slice[12] = {[FR] = 0, [FL] = 0, [BL] = 0, [BR] = 0,
15 [UL] = 1, [UR] = 1, [DR] = 1, [DL] = 1,
16 [UF] = 2, [UB] = 2, [DF] = 2, [DB] = 2};
17
18static uint16_t inv_coud[FACTORIAL8][POW3TO7];
19static uint16_t inv_cp[FACTORIAL8];
20static uint16_t uf_cp_to_fr_cp[FACTORIAL8];
21static uint16_t uf_cp_to_rd_cp[FACTORIAL8];
22
23static int16_t eo_invtable[3][POW2TO11][BINOM12ON4*FACTORIAL4];
24
25static int trans_ep_alg[NROTATIONS][12];
26static int trans_ep_inv[NROTATIONS][12];
27
28static uint16_t fst_where_is_edge_arr[3][12][BINOM12ON4*FACTORIAL4];
6 29
7FstCube 30FstCube
8cube_to_fst(Cube *cube) 31cube_to_fst(Cube *cube)
@@ -11,19 +34,39 @@ cube_to_fst(Cube *cube)
11 FstCube ret; 34 FstCube ret;
12 35
13 copy_cube(cube, &c); 36 copy_cube(cube, &c);
14 ret.uf_eofb = index_eofb(&c); 37 ret.uf_eofb = coord_eofb.i[0]->index(&c);
15 ret.uf_eposepe = index_eposepe(&c); 38 ret.uf_eposepe = coord_eposepe.i[0]->index(&c);
16 ret.uf_coud = index_coud(&c); 39 ret.uf_coud = coord_coud.i[0]->index(&c);
17 ret.uf_cp = index_cp(&c); 40 ret.uf_cp = coord_cp.i[0]->index(&c);
18 copy_cube(cube, &c); 41 copy_cube(cube, &c);
19 transform_cube(fr, &c); 42 apply_trans(fr, &c);
20 ret.fr_eofb = index_eofb(&c); 43 ret.fr_eofb = coord_eofb.i[0]->index(&c);
21 ret.fr_eposepe = index_eposepe(&c); 44 ret.fr_eposepe = coord_eposepe.i[0]->index(&c);
22 ret.fr_coud = index_coud(&c); 45 ret.fr_coud = coord_coud.i[0]->index(&c);
23 transform_cube(rd, &c); 46 apply_trans(rd, &c);
24 ret.rd_eofb = index_eofb(&c); 47 ret.rd_eofb = coord_eofb.i[0]->index(&c);
25 ret.rd_eposepe = index_eposepe(&c); 48 ret.rd_eposepe = coord_eposepe.i[0]->index(&c);
26 ret.rd_coud = index_coud(&c); 49 ret.rd_coud = coord_coud.i[0]->index(&c);
50
51 return ret;
52}
53
54static FstCube
55ep_to_fst_epos(int *ep)
56{
57 /* TODO: maybe optimize? */
58
59 FstCube ret;
60 Cube c;
61
62 memcpy(c.ep, ep, 12 * sizeof(int));
63 ret.uf_eposepe = coord_eposepe.i[0]->index(&c);
64
65 transform_ep_only(fr, ep, &c);
66 ret.fr_eposepe = coord_eposepe.i[0]->index(&c);
67
68 transform_ep_only(rd, ep, &c);
69 ret.rd_eposepe = coord_eposepe.i[0]->index(&c);
27 70
28 return ret; 71 return ret;
29} 72}
@@ -31,28 +74,232 @@ cube_to_fst(Cube *cube)
31FstCube 74FstCube
32fst_inverse(FstCube fst) 75fst_inverse(FstCube fst)
33{ 76{
34 /* TODO */ 77 FstCube ret;
78 int i, ep_inv[12];
79
80 for (i = 0; i < 12; i++)
81 ep_inv[i] = fst_where_is_edge(i, fst);
82 ret = ep_to_fst_epos(ep_inv);
83
84 ret.uf_eofb = ((uint16_t)eo_invtable[0][fst.uf_eofb][fst.uf_eposepe]) |
85 ((uint16_t)eo_invtable[1][fst.uf_eofb][fst.fr_eposepe]) |
86 ((uint16_t)eo_invtable[2][fst.uf_eofb][fst.rd_eposepe]);
87 ret.fr_eofb = ((uint16_t)eo_invtable[0][fst.fr_eofb][fst.uf_eposepe]) |
88 ((uint16_t)eo_invtable[1][fst.fr_eofb][fst.fr_eposepe]) |
89 ((uint16_t)eo_invtable[2][fst.fr_eofb][fst.rd_eposepe]);
90 ret.rd_eofb = ((uint16_t)eo_invtable[0][fst.rd_eofb][fst.uf_eposepe]) |
91 ((uint16_t)eo_invtable[1][fst.rd_eofb][fst.fr_eposepe]) |
92 ((uint16_t)eo_invtable[2][fst.rd_eofb][fst.rd_eposepe]);
93
94 ret.uf_cp = inv_cp[fst.uf_cp];
95
96 ret.uf_coud = inv_coud[fst.uf_cp][fst.uf_coud];
97 ret.fr_coud = inv_coud[uf_cp_to_fr_cp[fst.uf_cp]][fst.fr_coud];
98 ret.rd_coud = inv_coud[uf_cp_to_rd_cp[fst.uf_cp]][fst.rd_coud];
99
100 return ret;
35} 101}
36 102
37FstCube 103FstCube
38fst_move(Move m, FstCube fst) 104fst_move(Move m, FstCube fst)
39{ 105{
40 /* TODO */ 106 FstCube ret;
107 Move m_fr, m_rd;
108
109 m_fr = transform_move(fr, m);
110 m_rd = transform_move(rd, m);
111
112 ret.uf_eofb = coord_eofb.mtable[m][fst.uf_eofb];
113 ret.uf_eposepe = coord_eposepe.mtable[m][fst.uf_eposepe];
114 ret.uf_coud = coord_coud.mtable[m][fst.uf_coud];
115 ret.uf_cp = coord_cp.mtable[m][fst.uf_cp];
116
117 ret.fr_eofb = coord_eofb.mtable[m_fr][fst.fr_eofb];
118 ret.fr_eposepe = coord_eposepe.mtable[m_fr][fst.fr_eposepe];
119 ret.fr_coud = coord_coud.mtable[m_fr][fst.fr_coud];
120
121 ret.rd_eofb = coord_eofb.mtable[m_rd][fst.rd_eofb];
122 ret.rd_eposepe = coord_eposepe.mtable[m_rd][fst.rd_eposepe];
123 ret.rd_coud = coord_coud.mtable[m_rd][fst.rd_coud];
124
125 return ret;
41} 126}
42 127
43void 128void
44fst_to_cube(FstCube fst, Cube *cube) 129fst_to_cube(FstCube fst, Cube *cube)
45{ 130{
46 invindex_eofb((uint64_t)fst.uf_eofb, cube); 131 Cube e, s, m;
47 fst_to_ep(fst, cube->ep); 132 int i;
48 invindex_coud((uint64_t)fst.uf_coud, cube); 133
49 invindex_cp((uint64_t)fst.uf_cp, cube); 134 coord_eposepe.i[0]->to_cube(fst.uf_eposepe, &e);
135 coord_eposepe.i[0]->to_cube(fst.fr_eposepe, &s);
136 apply_trans(inverse_trans(fr), &s);
137 coord_eposepe.i[0]->to_cube(fst.rd_eposepe, &m);
138 apply_trans(inverse_trans(rd), &m);
139
140 for (i = 0; i < 12; i++) {
141 if (edge_slice[e.ep[i]] == 0)
142 cube->ep[i] = e.ep[i];
143 if (edge_slice[s.ep[i]] == 1)
144 cube->ep[i] = s.ep[i];
145 if (edge_slice[m.ep[i]] == 2)
146 cube->ep[i] = m.ep[i];
147 }
148
149 coord_eofb.i[0]->to_cube((uint64_t)fst.uf_eofb, cube);
150 coord_coud.i[0]->to_cube((uint64_t)fst.uf_coud, cube);
151 coord_cp.i[0]->to_cube((uint64_t)fst.uf_cp, cube);
152}
153
154static int
155fst_where_is_edge(int e, FstCube fst)
156{
157 switch (edge_slice[e]) {
158 case 0:
159 return fst_where_is_edge_arr[0][e][fst.uf_eposepe];
160 case 1:
161 return fst_where_is_edge_arr[1][e][fst.fr_eposepe];
162 default:
163 return fst_where_is_edge_arr[2][e][fst.rd_eposepe];
164 }
165
166 return -1;
167}
168
169static void
170transform_ep_only(Trans t, int *ep, Cube *dst)
171{
172 int i;
173
174 for (i = 0; i < 12; i++)
175 dst->ep[i] = trans_ep_alg[t][ep[trans_ep_inv[t][i]]];
176}
177
178void
179init_fst()
180{
181 init_fst_corner_invtables();
182 init_fst_eo_invtables();
183 init_fst_transalg();
184 init_fst_where_is_edge();
185}
186
187static void
188init_fst_corner_invtables()
189{
190/* TODO: this can be optimized by transforming and copying only corners */
191/* A factor of about 4 would be saved in the innermost loop */
192
193 Cube c, d;
194 uint64_t cp, coud;
195
196 for (cp = 0; cp < FACTORIAL8; cp++) {
197 make_solved(&c);
198 coord_cp.i[0]->to_cube(cp, &c);
199
200 copy_cube(&c, &d);
201 invert_cube(&d);
202 inv_cp[cp] = coord_coud.i[0]->index(&d);
203
204 for (coud = 0; coud < POW3TO7; coud++) {
205 copy_cube(&c, &d);
206 coord_coud.i[0]->to_cube(coud, &d);
207 invert_cube(&d);
208 inv_coud[cp][coud] = coord_coud.i[0]->index(&d);
209 }
210
211 copy_cube(&c, &d);
212 apply_trans(fr, &d);
213 uf_cp_to_fr_cp[cp] = coord_cp.i[0]->index(&d);
214
215 copy_cube(&c, &d);
216 apply_trans(rd, &d);
217 uf_cp_to_rd_cp[cp] = coord_cp.i[0]->index(&d);
218 }
219}
220
221static void
222init_fst_eo_invtables()
223{
224 uint64_t ep, eo;
225 Cube c, d;
226
227 for (ep = 0; ep < BINOM12ON4 * FACTORIAL4; ep++) {
228 make_solved(&c);
229 coord_eposepe.i[0]->to_cube(ep, &c);
230 for (eo = 0; eo < POW2TO11; eo++) {
231 coord_eofb.i[0]->to_cube(eo, &c);
232 copy_cube(&c, &d);
233 init_fst_eo_update(eo, ep, 0, &d);
234 apply_trans(inverse_trans(fr), &d);
235 init_fst_eo_update(eo, ep, 1, &d);
236 copy_cube(&c, &d);
237 apply_trans(inverse_trans(rd), &d);
238 init_fst_eo_update(eo, ep, 2, &d);
239 }
240 }
50} 241}
51 242
52static void 243static void
53fst_to_ep(FstCube fst, int *ep) 244init_fst_eo_update(uint64_t eo, uint64_t ep, int s, Cube *d)
54{ 245{
55 /* TODO */ 246 int i;
247
248 for (i = 0; i < 12; i++)
249 if (d->eo[i])
250 eo_invtable[s][eo][ep] |= ((uint16_t)1) << d->ep[i];
56} 251}
57 252
58#endif 253static void
254init_fst_transalg()
255{
256 Trans t;
257 Alg *alg;
258 Cube c;
259 int i;
260
261 for (t = uf; t < NROTATIONS; t++) {
262 make_solved(&c);
263 alg = rotation_alg(t);
264 apply_alg(alg, &c);
265 for (i = 0; i < 12; i++)
266 trans_ep_alg[t][i] = c.ep[i];
267 invert_cube(&c);
268 for (i = 0; i < 12; i++)
269 trans_ep_inv[t][i] = c.ep[i];
270 }
271}
272
273static void
274init_fst_where_is_edge()
275{
276 Cube c, d;
277 uint64_t e;
278
279 init_trans();
280
281 make_solved(&c);
282 for (e = 0; e < BINOM12ON4 * FACTORIAL4; e++) {
283 coord_eposepe.i[0]->to_cube(e, &c);
284
285 copy_cube(&c, &d);
286 fst_where_is_edge_arr[0][FR][e] = where_is_edge(FR, &d);
287 fst_where_is_edge_arr[0][FL][e] = where_is_edge(FL, &d);
288 fst_where_is_edge_arr[0][BL][e] = where_is_edge(BL, &d);
289 fst_where_is_edge_arr[0][BR][e] = where_is_edge(BR, &d);
290
291 copy_cube(&c, &d);
292 apply_trans(inverse_trans(fr), &d);
293 fst_where_is_edge_arr[1][UL][e] = where_is_edge(UL, &d);
294 fst_where_is_edge_arr[1][UR][e] = where_is_edge(UR, &d);
295 fst_where_is_edge_arr[1][DL][e] = where_is_edge(DL, &d);
296 fst_where_is_edge_arr[1][DR][e] = where_is_edge(DR, &d);
297
298 copy_cube(&c, &d);
299 apply_trans(inverse_trans(rd), &d);
300 fst_where_is_edge_arr[2][UF][e] = where_is_edge(UF, &d);
301 fst_where_is_edge_arr[2][UB][e] = where_is_edge(UB, &d);
302 fst_where_is_edge_arr[2][DF][e] = where_is_edge(DF, &d);
303 fst_where_is_edge_arr[2][DB][e] = where_is_edge(DB, &d);
304 }
305}
diff --git a/src/fst.h b/src/fst.h
index 94f6c30..c3b226c 100644
--- a/src/fst.h
+++ b/src/fst.h
@@ -7,6 +7,7 @@ FstCube cube_to_fst(Cube *cube);
7FstCube fst_inverse(FstCube fst); 7FstCube fst_inverse(FstCube fst);
8FstCube fst_move(Move m, FstCube fst); 8FstCube fst_move(Move m, FstCube fst);
9void fst_to_cube(FstCube fst, Cube *cube); 9void fst_to_cube(FstCube fst, Cube *cube);
10void init_fst();
10 11
11#endif 12#endif
12 13
diff --git a/src/shell.c b/src/shell.c
index 44665a8..c25b399 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -142,6 +142,7 @@ launch(bool batchmode)
142 free(shell_argv); 142 free(shell_argv);
143} 143}
144 144
145#ifndef TEST
145int 146int
146main(int argc, char *argv[]) 147main(int argc, char *argv[])
147{ 148{
@@ -187,3 +188,4 @@ main(int argc, char *argv[])
187 188
188 return 0; 189 return 0;
189} 190}
191#endif
diff --git a/src/trans.c b/src/trans.c
index da2dca3..898c2be 100644
--- a/src/trans.c
+++ b/src/trans.c
@@ -26,7 +26,7 @@ static char rotation_alg_string[100][NROTATIONS] = {
26 [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3", 26 [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3",
27}; 27};
28 28
29static Alg *rotation_alg_arr[NROTATIONS]; 29Alg *rotation_alg_arr[NROTATIONS];
30Move moves_ttable[NTRANS][NMOVES]; 30Move moves_ttable[NTRANS][NMOVES];
31Trans trans_ttable[NTRANS][NTRANS]; 31Trans trans_ttable[NTRANS][NTRANS];
32Trans trans_itable[NTRANS]; 32Trans trans_itable[NTRANS];

Generated with cgit - Back to sebastiano.tronto.net