aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--TODO.md13
-rw-r--r--src/cube.c126
-rw-r--r--src/cube.h12
-rw-r--r--src/fst.c75
-rw-r--r--src/fst.h1
-rw-r--r--src/moves.c18
-rw-r--r--src/moves.h3
-rw-r--r--tests/fst_post_init_tests.c114
-rw-r--r--tests/fst_pre_init_tests.c89
-rw-r--r--tests/fst_test_util.c64
-rw-r--r--tests/fst_test_util.h7
-rw-r--r--tests/inc.h1
-rw-r--r--tests/nissy_tests.c12
-rw-r--r--tests/test_all.c10
-rw-r--r--tests/test_fst.c184
16 files changed, 489 insertions, 244 deletions
diff --git a/Makefile b/Makefile
index 43fa678..1b6055b 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,9 @@ nissy: clean
21 ${CC} ${CFLAGS} -o nissy src/*.c 21 ${CC} ${CFLAGS} -o nissy src/*.c
22 22
23test: 23test:
24 ${CC} ${TESTFLAGS} -o test src/*.c tests/*.c 24 ${CC} ${TESTFLAGS} -o nissy-test src/*.c tests/*.c
25 ./nissy-test
26 rm nissy-test
25 27
26nissy.exe: 28nissy.exe:
27 x86_64-w64-mingw32-gcc ${CFLAGS} -static -o nissy.exe src/*.c 29 x86_64-w64-mingw32-gcc ${CFLAGS} -static -o nissy.exe src/*.c
diff --git a/TODO.md b/TODO.md
index a149c2f..6e61e75 100644
--- a/TODO.md
+++ b/TODO.md
@@ -9,8 +9,8 @@ It's more of a personal reminder than anything else.
9 of the files includes + doing more stuff. A static "initiliazed" 9 of the files includes + doing more stuff. A static "initiliazed"
10 variable is probably needed too. 10 variable is probably needed too.
11### testing! 11### testing!
12* test fst: implement fst_consistent 12* generic test util: function taking an array of tests, an array of testnames
13* test fst: init_fst is necessary before testing move and inverse 13 (or maybe tests should be their own type?) and running them
14* separate "commands" for testing different parts (e.g. ./test coord) 14* separate "commands" for testing different parts (e.g. ./test coord)
15* test coordinate (needed anyway to test fst) 15* test coordinate (needed anyway to test fst)
16* other tests (start from bottom: utils.c) 16* other tests (start from bottom: utils.c)
@@ -19,10 +19,15 @@ It's more of a personal reminder than anything else.
19* add Void * extradata to DfsArg and a custom move function 19* add Void * extradata to DfsArg and a custom move function
20* add optional custom pre-process for generating special table (nx) 20* add optional custom pre-process for generating special table (nx)
21* copy_dfsdata should copy extra too! 21* copy_dfsdata should copy extra too!
22### Solving simplification / refactor
23* Split solve in solve_coord, solve_generic, solve_singlethread...
24* Rework choicesteps: simplify, remove one type of rotation...
22### nx.c 25### nx.c
23* implement nxopt with all tables and all tricks 26* implement nxopt with all tables and all tricks
24 (maybe compile time variable for maximum memory to use?) 27 (maybe compile time variable for maximum memory to use?)
25* is_valid should also unniss / cleanup the alg 28* is_valid should also unniss / cleanup the alg
29### Other easy refactor
30* split cubetypes.h into other files
26 31
27## For version 2.1 32## For version 2.1
28### Changes to Step and Solve 33### Changes to Step and Solve
@@ -47,9 +52,11 @@ It's more of a personal reminder than anything else.
47 check if found enough solutions before checking pruning values) 52 check if found enough solutions before checking pruning values)
48### Technical 53### Technical
49* generic option parser 54* generic option parser
55* scan system to get best number of threads
50### Commands 56### Commands
51* Easy: add option -I (inverse) and -L (linear, like inverse + normal) 57* Easy: add option -I (inverse) and -L (linear, like inverse + normal)
52 to do only linear NISS 58 to do only linear NISS
59* message for -N ignored say -n (lowercase)
53 60
54## Commands 61## Commands
55 62
@@ -75,6 +82,8 @@ including e.g. solutions that were not shown because -c)
75* solve should try up to a small bound without loading the large pruning table 82* solve should try up to a small bound without loading the large pruning table
76 (maybe this is not necessary if loading the table is fast enough) 83 (maybe this is not necessary if loading the table is fast enough)
77* silent batch mode without >>> 84* silent batch mode without >>>
85* Optimal solver: when asking for only one solution, scan for upper bound in
86 parallel using a two-phase solver.
78 87
79### New features 88### New features
80* EO analysis (and also DR and HTR analysis): group similar EOs together 89* EO analysis (and also DR and HTR analysis): group similar EOs together
diff --git a/src/cube.c b/src/cube.c
index c2a457c..92c6713 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -5,27 +5,61 @@
5static int where_is_piece(int piece, int *arr, int n); 5static int where_is_piece(int piece, int *arr, int n);
6 6
7void 7void
8compose(Cube *c2, Cube *c1) 8compose_centers(Cube *c2, Cube *c1)
9{ 9{
10 apply_permutation(c2->ep, c1->ep, 12); 10 apply_permutation(c2->xp, c1->xp, 6);
11 apply_permutation(c2->ep, c1->eo, 12); 11}
12 sum_arrays_mod(c2->eo, c1->eo, 12, 2);
13 12
13void
14compose_corners(Cube *c2, Cube *c1)
15{
14 apply_permutation(c2->cp, c1->cp, 8); 16 apply_permutation(c2->cp, c1->cp, 8);
15 apply_permutation(c2->cp, c1->co, 8); 17 apply_permutation(c2->cp, c1->co, 8);
16 sum_arrays_mod(c2->co, c1->co, 8, 3); 18 sum_arrays_mod(c2->co, c1->co, 8, 3);
19}
17 20
18 apply_permutation(c2->xp, c1->xp, 6); 21void
22compose_edges(Cube *c2, Cube *c1)
23{
24 apply_permutation(c2->ep, c1->ep, 12);
25 apply_permutation(c2->ep, c1->eo, 12);
26 sum_arrays_mod(c2->eo, c1->eo, 12, 2);
19} 27}
20 28
21void 29void
22copy_cube(Cube *src, Cube *dst) 30compose(Cube *c2, Cube *c1)
31{
32 compose_centers(c2, c1);
33 compose_corners(c2, c1);
34 compose_edges(c2, c1);
35}
36
37void
38copy_cube_centers(Cube *src, Cube *dst)
39{
40 memcpy(dst->xp, src->xp, 6 * sizeof(int));
41}
42
43void
44copy_cube_corners(Cube *src, Cube *dst)
23{ 45{
24 memcpy(dst->ep, src->ep, 12 * sizeof(int));
25 memcpy(dst->eo, src->eo, 12 * sizeof(int));
26 memcpy(dst->cp, src->cp, 8 * sizeof(int)); 46 memcpy(dst->cp, src->cp, 8 * sizeof(int));
27 memcpy(dst->co, src->co, 8 * sizeof(int)); 47 memcpy(dst->co, src->co, 8 * sizeof(int));
28 memcpy(dst->xp, src->xp, 6 * sizeof(int)); 48}
49
50void
51copy_cube_edges(Cube *src, Cube *dst)
52{
53 memcpy(dst->ep, src->ep, 12 * sizeof(int));
54 memcpy(dst->eo, src->eo, 12 * sizeof(int));
55}
56
57void
58copy_cube(Cube *src, Cube *dst)
59{
60 copy_cube_centers(src, dst);
61 copy_cube_corners(src, dst);
62 copy_cube_edges(src, dst);
29} 63}
30 64
31bool 65bool
@@ -49,25 +83,51 @@ equal(Cube *c1, Cube *c2)
49} 83}
50 84
51void 85void
52invert_cube(Cube *cube) 86invert_cube_centers(Cube *cube)
53{ 87{
54 Cube aux;
55 int i; 88 int i;
89 Cube aux;
56 90
57 copy_cube(cube, &aux); 91 copy_cube_centers(cube, &aux);
58 92
59 for (i = 0; i < 12; i++) { 93 for (i = 0; i < 6; i++)
60 cube->ep[aux.ep[i]] = i; 94 cube->xp[aux.xp[i]] = i;
61 cube->eo[aux.ep[i]] = aux.eo[i]; 95}
62 } 96
97void
98invert_cube_corners(Cube *cube)
99{
100 int i;
101 Cube aux;
102
103 copy_cube_corners(cube, &aux);
63 104
64 for (i = 0; i < 8; i++) { 105 for (i = 0; i < 8; i++) {
65 cube->cp[aux.cp[i]] = i; 106 cube->cp[aux.cp[i]] = i;
66 cube->co[aux.cp[i]] = (3 - aux.co[i]) % 3; 107 cube->co[aux.cp[i]] = (3 - aux.co[i]) % 3;
67 } 108 }
109}
68 110
69 for (i = 0; i < 6; i++) 111void
70 cube->xp[aux.xp[i]] = i; 112invert_cube_edges(Cube *cube)
113{
114 int i;
115 Cube aux;
116
117 copy_cube_edges(cube, &aux);
118
119 for (i = 0; i < 12; i++) {
120 cube->ep[aux.ep[i]] = i;
121 cube->eo[aux.ep[i]] = aux.eo[i];
122 }
123}
124
125void
126invert_cube(Cube *cube)
127{
128 invert_cube_centers(cube);
129 invert_cube_corners(cube);
130 invert_cube_edges(cube);
71} 131}
72 132
73bool 133bool
@@ -105,15 +165,37 @@ is_solved(Cube *cube)
105} 165}
106 166
107void 167void
108make_solved(Cube *cube) 168make_solved_centers(Cube *cube)
169{
170 static int sorted[6] = {0, 1, 2, 3, 4, 5};
171
172 memcpy(cube->xp, sorted, 6 * sizeof(int));
173}
174
175void
176make_solved_corners(Cube *cube)
177{
178 static int sorted[8] = {0, 1, 2, 3, 4, 5, 6, 7};
179
180 memcpy(cube->cp, sorted, 8 * sizeof(int));
181 memset(cube->co, 0, 8 * sizeof(int));
182}
183
184void
185make_solved_edges(Cube *cube)
109{ 186{
110 static int sorted[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 187 static int sorted[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
111 188
112 memcpy(cube->ep, sorted, 12 * sizeof(int)); 189 memcpy(cube->ep, sorted, 12 * sizeof(int));
113 memset(cube->eo, 0, 12 * sizeof(int)); 190 memset(cube->eo, 0, 12 * sizeof(int));
114 memcpy(cube->cp, sorted, 8 * sizeof(int)); 191}
115 memset(cube->co, 0, 8 * sizeof(int)); 192
116 memcpy(cube->xp, sorted, 6 * sizeof(int)); 193void
194make_solved(Cube *cube)
195{
196 make_solved_centers(cube);
197 make_solved_corners(cube);
198 make_solved_edges(cube);
117} 199}
118 200
119void 201void
diff --git a/src/cube.h b/src/cube.h
index 789bb2e..f182b27 100644
--- a/src/cube.h
+++ b/src/cube.h
@@ -8,12 +8,24 @@
8#include "utils.h" 8#include "utils.h"
9 9
10void compose(Cube *c2, Cube *c1); /* Use c2 as an alg on c1 */ 10void compose(Cube *c2, Cube *c1); /* Use c2 as an alg on c1 */
11void compose_centers(Cube *c2, Cube *c1);
12void compose_corners(Cube *c2, Cube *c1);
13void compose_edges(Cube *c2, Cube *c1);
11void copy_cube(Cube *src, Cube *dst); 14void copy_cube(Cube *src, Cube *dst);
15void copy_cube_centers(Cube *src, Cube *dst);
16void copy_cube_corners(Cube *src, Cube *dst);
17void copy_cube_edges(Cube *src, Cube *dst);
12bool equal(Cube *c1, Cube *c2); 18bool equal(Cube *c1, Cube *c2);
13void invert_cube(Cube *cube); 19void invert_cube(Cube *cube);
20void invert_cube_centers(Cube *cube);
21void invert_cube_corners(Cube *cube);
22void invert_cube_edges(Cube *cube);
14bool is_admissible(Cube *cube); 23bool is_admissible(Cube *cube);
15bool is_solved(Cube *cube); 24bool is_solved(Cube *cube);
16void make_solved(Cube *cube); 25void make_solved(Cube *cube);
26void make_solved_centers(Cube *cube);
27void make_solved_corners(Cube *cube);
28void make_solved_edges(Cube *cube);
17void print_cube(Cube *cube); 29void print_cube(Cube *cube);
18int where_is_center(Center x, Cube *c); 30int where_is_center(Center x, Cube *c);
19int where_is_corner(Corner k, Cube *c); 31int where_is_corner(Corner k, Cube *c);
diff --git a/src/fst.c b/src/fst.c
index aa9e41e..df5b81f 100644
--- a/src/fst.c
+++ b/src/fst.c
@@ -3,7 +3,6 @@
3#include "fst.h" 3#include "fst.h"
4 4
5static FstCube ep_to_fst_epos(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); 6static void transform_ep_only(Trans t, int *ep, Cube *dst);
8static void init_fst_corner_invtables(); 7static void init_fst_corner_invtables();
9static void init_fst_eo_invtables(); 8static void init_fst_eo_invtables();
@@ -55,7 +54,10 @@ cube_to_fst(Cube *cube)
55static FstCube 54static FstCube
56ep_to_fst_epos(int *ep) 55ep_to_fst_epos(int *ep)
57{ 56{
58 /* TODO: maybe optimize? */ 57 /* TODO: maybe optimize */
58
59/* TODO: this version if faster, but broken
60 probably need to fix transform_ep_only()
59 61
60 FstCube ret; 62 FstCube ret;
61 Cube c; 63 Cube c;
@@ -68,6 +70,24 @@ ep_to_fst_epos(int *ep)
68 70
69 transform_ep_only(rd, ep, &c); 71 transform_ep_only(rd, ep, &c);
70 ret.rd_eposepe = coord_eposepe.i[0]->index(&c); 72 ret.rd_eposepe = coord_eposepe.i[0]->index(&c);
73*/
74
75 FstCube ret;
76 Cube c, d;
77
78 make_solved(&c);
79 memcpy(c.ep, ep, 12 * sizeof(int));
80
81 copy_cube(&c, &d);
82 ret.uf_eposepe = coord_eposepe.i[0]->index(&d);
83
84 copy_cube(&c, &d);
85 apply_trans(fr, &d);
86 ret.fr_eposepe = coord_eposepe.i[0]->index(&d);
87
88 copy_cube(&c, &d);
89 apply_trans(rd, &d);
90 ret.rd_eposepe = coord_eposepe.i[0]->index(&d);
71 91
72 return ret; 92 return ret;
73} 93}
@@ -155,7 +175,7 @@ fst_to_cube(FstCube fst, Cube *cube)
155 cube->xp[i] = i; 175 cube->xp[i] = i;
156} 176}
157 177
158static int 178int
159fst_where_is_edge(int e, FstCube fst) 179fst_where_is_edge(int e, FstCube fst)
160{ 180{
161 switch (edge_slice[e]) { 181 switch (edge_slice[e]) {
@@ -183,6 +203,10 @@ void
183init_fst() 203init_fst()
184{ 204{
185 init_trans(); 205 init_trans();
206 gen_coord(&coord_eofb);
207 gen_coord(&coord_eposepe);
208 gen_coord(&coord_coud);
209 gen_coord(&coord_cp);
186 210
187 init_fst_corner_invtables(); 211 init_fst_corner_invtables();
188 init_fst_eo_invtables(); 212 init_fst_eo_invtables();
@@ -193,32 +217,29 @@ init_fst()
193static void 217static void
194init_fst_corner_invtables() 218init_fst_corner_invtables()
195{ 219{
196/* TODO: this can be optimized by transforming and copying only corners */
197/* A factor of about 4 would be saved in the innermost loop */
198
199 Cube c, d; 220 Cube c, d;
200 uint64_t cp, coud; 221 uint64_t cp, coud;
201 222
202 for (cp = 0; cp < FACTORIAL8; cp++) { 223 for (cp = 0; cp < FACTORIAL8; cp++) {
203 make_solved(&c); 224 make_solved_corners(&c);
204 coord_cp.i[0]->to_cube(cp, &c); 225 coord_cp.i[0]->to_cube(cp, &c);
205 226
206 copy_cube(&c, &d); 227 copy_cube_corners(&c, &d);
207 invert_cube(&d); 228 invert_cube_corners(&d);
208 inv_cp[cp] = coord_coud.i[0]->index(&d); 229 inv_cp[cp] = coord_cp.i[0]->index(&d);
209 230
210 for (coud = 0; coud < POW3TO7; coud++) { 231 for (coud = 0; coud < POW3TO7; coud++) {
211 copy_cube(&c, &d); 232 copy_cube_corners(&c, &d);
212 coord_coud.i[0]->to_cube(coud, &d); 233 coord_coud.i[0]->to_cube(coud, &d);
213 invert_cube(&d); 234 invert_cube_corners(&d);
214 inv_coud[cp][coud] = coord_coud.i[0]->index(&d); 235 inv_coud[cp][coud] = coord_coud.i[0]->index(&d);
215 } 236 }
216 237
217 copy_cube(&c, &d); 238 copy_cube_corners(&c, &d);
218 apply_trans(fr, &d); 239 apply_trans(fr, &d);
219 uf_cp_to_fr_cp[cp] = coord_cp.i[0]->index(&d); 240 uf_cp_to_fr_cp[cp] = coord_cp.i[0]->index(&d);
220 241
221 copy_cube(&c, &d); 242 copy_cube_corners(&c, &d);
222 apply_trans(rd, &d); 243 apply_trans(rd, &d);
223 uf_cp_to_rd_cp[cp] = coord_cp.i[0]->index(&d); 244 uf_cp_to_rd_cp[cp] = coord_cp.i[0]->index(&d);
224 } 245 }
@@ -234,13 +255,17 @@ init_fst_eo_invtables()
234 make_solved(&c); 255 make_solved(&c);
235 coord_eposepe.i[0]->to_cube(ep, &c); 256 coord_eposepe.i[0]->to_cube(ep, &c);
236 for (eo = 0; eo < POW2TO11; eo++) { 257 for (eo = 0; eo < POW2TO11; eo++) {
237 coord_eofb.i[0]->to_cube(eo, &c); 258 copy_cube_edges(&c, &d);
238 copy_cube(&c, &d); 259 coord_eofb.i[0]->to_cube(eo, &d);
239 init_fst_eo_update(eo, ep, 0, &d); 260 init_fst_eo_update(eo, ep, 0, &d);
261
240 apply_trans(inverse_trans(fr), &d); 262 apply_trans(inverse_trans(fr), &d);
263 coord_eofb.i[0]->to_cube(eo, &d);
241 init_fst_eo_update(eo, ep, 1, &d); 264 init_fst_eo_update(eo, ep, 1, &d);
242 copy_cube(&c, &d); 265
266 copy_cube_edges(&c, &d);
243 apply_trans(inverse_trans(rd), &d); 267 apply_trans(inverse_trans(rd), &d);
268 coord_eofb.i[0]->to_cube(eo, &d);
244 init_fst_eo_update(eo, ep, 2, &d); 269 init_fst_eo_update(eo, ep, 2, &d);
245 } 270 }
246 } 271 }
@@ -251,9 +276,11 @@ init_fst_eo_update(uint64_t eo, uint64_t ep, int s, Cube *d)
251{ 276{
252 int i; 277 int i;
253 278
254 for (i = 0; i < 12; i++) 279 for (i = 0; i < 12; i++) {
255 if (d->eo[i]) 280 if (edge_slice[d->ep[i]] == s && d->eo[i] && d->ep[i] != 11)
256 eo_invtable[s][eo][ep] |= ((uint16_t)1) << d->ep[i]; 281 eo_invtable[s][eo][ep] |=
282 ((uint16_t)1) << ((uint16_t)d->ep[i]);
283 }
257} 284}
258 285
259static void 286static void
@@ -270,7 +297,7 @@ init_fst_transalg()
270 apply_alg(alg, &c); 297 apply_alg(alg, &c);
271 for (i = 0; i < 12; i++) 298 for (i = 0; i < 12; i++)
272 trans_ep_alg[t][i] = c.ep[i]; 299 trans_ep_alg[t][i] = c.ep[i];
273 invert_cube(&c); 300 invert_cube_edges(&c);
274 for (i = 0; i < 12; i++) 301 for (i = 0; i < 12; i++)
275 trans_ep_inv[t][i] = c.ep[i]; 302 trans_ep_inv[t][i] = c.ep[i];
276 } 303 }
@@ -286,20 +313,20 @@ init_fst_where_is_edge()
286 for (e = 0; e < BINOM12ON4 * FACTORIAL4; e++) { 313 for (e = 0; e < BINOM12ON4 * FACTORIAL4; e++) {
287 coord_eposepe.i[0]->to_cube(e, &c); 314 coord_eposepe.i[0]->to_cube(e, &c);
288 315
289 copy_cube(&c, &d); 316 copy_cube_edges(&c, &d);
290 fst_where_is_edge_arr[0][FR][e] = where_is_edge(FR, &d); 317 fst_where_is_edge_arr[0][FR][e] = where_is_edge(FR, &d);
291 fst_where_is_edge_arr[0][FL][e] = where_is_edge(FL, &d); 318 fst_where_is_edge_arr[0][FL][e] = where_is_edge(FL, &d);
292 fst_where_is_edge_arr[0][BL][e] = where_is_edge(BL, &d); 319 fst_where_is_edge_arr[0][BL][e] = where_is_edge(BL, &d);
293 fst_where_is_edge_arr[0][BR][e] = where_is_edge(BR, &d); 320 fst_where_is_edge_arr[0][BR][e] = where_is_edge(BR, &d);
294 321
295 copy_cube(&c, &d); 322 copy_cube_edges(&c, &d);
296 apply_trans(inverse_trans(fr), &d); 323 apply_trans(inverse_trans(fr), &d);
297 fst_where_is_edge_arr[1][UL][e] = where_is_edge(UL, &d); 324 fst_where_is_edge_arr[1][UL][e] = where_is_edge(UL, &d);
298 fst_where_is_edge_arr[1][UR][e] = where_is_edge(UR, &d); 325 fst_where_is_edge_arr[1][UR][e] = where_is_edge(UR, &d);
299 fst_where_is_edge_arr[1][DL][e] = where_is_edge(DL, &d); 326 fst_where_is_edge_arr[1][DL][e] = where_is_edge(DL, &d);
300 fst_where_is_edge_arr[1][DR][e] = where_is_edge(DR, &d); 327 fst_where_is_edge_arr[1][DR][e] = where_is_edge(DR, &d);
301 328
302 copy_cube(&c, &d); 329 copy_cube_edges(&c, &d);
303 apply_trans(inverse_trans(rd), &d); 330 apply_trans(inverse_trans(rd), &d);
304 fst_where_is_edge_arr[2][UF][e] = where_is_edge(UF, &d); 331 fst_where_is_edge_arr[2][UF][e] = where_is_edge(UF, &d);
305 fst_where_is_edge_arr[2][UB][e] = where_is_edge(UB, &d); 332 fst_where_is_edge_arr[2][UB][e] = where_is_edge(UB, &d);
diff --git a/src/fst.h b/src/fst.h
index c3b226c..be5e99b 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);
10int fst_where_is_edge(int e, FstCube fst);
10void init_fst(); 11void init_fst();
11 12
12#endif 13#endif
diff --git a/src/moves.c b/src/moves.c
index 51012db..a9dfdc0 100644
--- a/src/moves.c
+++ b/src/moves.c
@@ -106,6 +106,24 @@ apply_move(Move m, Cube *cube)
106 compose(&move_array[m], cube); 106 compose(&move_array[m], cube);
107} 107}
108 108
109void
110apply_move_centers(Move m, Cube *cube)
111{
112 compose_centers(&move_array[m], cube);
113}
114
115void
116apply_move_corners(Move m, Cube *cube)
117{
118 compose_corners(&move_array[m], cube);
119}
120
121void
122apply_move_edges(Move m, Cube *cube)
123{
124 compose_edges(&move_array[m], cube);
125}
126
109Alg * 127Alg *
110cleanup(Alg *alg) 128cleanup(Alg *alg)
111{ 129{
diff --git a/src/moves.h b/src/moves.h
index 4afe8fb..4e8be7f 100644
--- a/src/moves.h
+++ b/src/moves.h
@@ -7,6 +7,9 @@
7 7
8void apply_alg(Alg *alg, Cube *cube); 8void apply_alg(Alg *alg, Cube *cube);
9void apply_move(Move m, Cube *cube); 9void apply_move(Move m, Cube *cube);
10void apply_move_centers(Move m, Cube *cube);
11void apply_move_corners(Move m, Cube *cube);
12void apply_move_edges(Move m, Cube *cube);
10Alg * cleanup(Alg *alg); 13Alg * cleanup(Alg *alg);
11 14
12void init_moves(); 15void init_moves();
diff --git a/tests/fst_post_init_tests.c b/tests/fst_post_init_tests.c
new file mode 100644
index 0000000..653e379
--- /dev/null
+++ b/tests/fst_post_init_tests.c
@@ -0,0 +1,114 @@
1#include "fst_test_util.h"
2
3static bool fst_move_testcase(Cube *c, Alg *a);
4static bool fst_inverse_testcase(Cube *c, Alg *a);
5
6static bool fst_move_test();
7static bool fst_where_is_edge_test();
8static bool fst_inverse_test();
9
10static Tester test[] = {
11 fst_move_test,
12 fst_where_is_edge_test,
13 fst_inverse_test,
14 NULL
15};
16
17static char *name[] = {
18 "FST move",
19 "FST where is edge",
20 "FST inverse",
21};
22
23static bool
24fst_move_testcase(Cube *c, Alg *a)
25{
26 int i;
27 Cube d;
28 FstCube fst;
29
30 make_solved(&d);
31 fst = cube_to_fst(&d);
32
33 for (i = 0; i < a->len; i++) {
34 if (a->inv[i] || a->move[i] > B3) {
35 printf("Cannot apply the following alg to FST: ");
36 print_alg(a, false);
37 return false;
38 }
39 fst = fst_move(a->move[i], fst);
40 }
41
42 fst_to_cube(fst, &d);
43
44 return equal_and_log(c, &d);
45}
46
47static bool
48fst_inverse_testcase(Cube *c, Alg *a)
49{
50 Cube d;
51
52 fst_to_cube(fst_inverse(cube_to_fst(c)), &d);
53 invert_cube(c);
54
55 return equal_and_log(c, &d);
56}
57
58static bool
59fst_move_test()
60{
61 return try_all_str(fst_move_testcase, "FST move incorrect");
62}
63
64static bool
65fst_where_is_edge_test()
66{
67 int i;
68 Alg *scr;
69 Cube c, d;
70 FstCube fst;
71
72 /* Testing on a single scramble is fine for now */
73 scr = new_alg("RUFDL2B2FRD");
74 make_solved(&c);
75 apply_alg(scr, &c);
76 fst = cube_to_fst(&c);
77
78 for (i = 0; i < 12; i++) {
79 if (fst_where_is_edge(c.ep[i], fst) != i) {
80 fst_to_cube(fst, &d);
81 printf("Alg: ");
82 print_alg(scr, false);
83 printf("Expected:\n");
84 print_cube(&c);
85 printf("But got:\n");
86 print_cube(&d);
87 return false;
88 }
89 }
90
91 return true;
92}
93
94static bool
95fst_inverse_test()
96{
97 return try_all_str(fst_inverse_testcase, "FST test incorrect");
98}
99
100void fst_post_init_testall() {
101 int i;
102
103 init_fst();
104
105 for (i = 0; test[i] != NULL; i++) {
106 printf("Test: %s\n", name[i]);
107 if (!test[i]()) {
108 printf("Failed!\n");
109 exit(1);
110 }
111 printf("Passed.\n\n");
112 }
113 printf("All FST post-init tests passed.\n\n");
114}
diff --git a/tests/fst_pre_init_tests.c b/tests/fst_pre_init_tests.c
new file mode 100644
index 0000000..6b7a440
--- /dev/null
+++ b/tests/fst_pre_init_tests.c
@@ -0,0 +1,89 @@
1#include "fst_test_util.h"
2
3static bool cube_to_fst_to_cube_testcase(Cube *c, Alg *a);
4static bool fst_is_consistent_testcase(Cube *c, Alg *a);
5
6static bool fst_is_consistent_test();
7static bool cube_to_fst_to_cube_test();
8
9static Tester test[] = {
10 fst_is_consistent_test,
11 cube_to_fst_to_cube_test,
12 NULL
13};
14
15static char *name[] = {
16 "Consistency of FST (converted from cube)",
17 "Cube to FST to cube",
18};
19
20static bool
21fst_is_consistent_testcase(Cube *c, Alg *a)
22{
23 FstCube fst_uf, fst_fr, fst_rd;
24 Cube c_fr, c_rd;
25 bool consistent_fr, consistent_rd;
26
27 copy_cube(c, &c_fr);
28 apply_trans(fr, &c_fr);
29
30 copy_cube(c, &c_rd);
31 apply_trans(rd, &c_rd);
32
33 fst_uf = cube_to_fst(c);
34 fst_fr = cube_to_fst(&c_fr);
35 fst_rd = cube_to_fst(&c_rd);
36
37 consistent_fr = fst_uf.fr_eofb == fst_fr.uf_eofb &&
38 fst_uf.fr_eposepe == fst_fr.uf_eposepe &&
39 fst_uf.fr_coud == fst_fr.uf_coud;
40
41 consistent_rd = fst_uf.rd_eofb == fst_rd.uf_eofb &&
42 fst_uf.rd_eposepe == fst_rd.uf_eposepe &&
43 fst_uf.rd_coud == fst_rd.uf_coud;
44
45 return consistent_fr && consistent_rd;
46}
47
48static bool
49cube_to_fst_to_cube_testcase(Cube *c, Alg *a)
50{
51 Cube d;
52 FstCube fst;
53
54 fst = cube_to_fst(c);
55 fst_to_cube(fst, &d);
56
57 return equal_and_log(c, &d);;
58}
59
60static bool
61cube_to_fst_to_cube_test()
62{
63 return try_all_str(
64 cube_to_fst_to_cube_testcase, "Cube to FST to cube failed");
65}
66
67static bool
68fst_is_consistent_test()
69{
70 return try_all_str(
71 fst_is_consistent_testcase, "FST from cube not consistent");
72}
73
74void fst_pre_init_testall() {
75 int i;
76
77 init_env();
78 init_trans();
79
80 for (i = 0; test[i] != NULL; i++) {
81 printf("Test: %s\n", name[i]);
82 if (!test[i]()) {
83 printf("Failed!\n");
84 exit(1);
85 }
86 printf("Passed.\n\n");
87 }
88 printf("All FST pre-init tests passed.\n\n");
89}
diff --git a/tests/fst_test_util.c b/tests/fst_test_util.c
new file mode 100644
index 0000000..35c1e9f
--- /dev/null
+++ b/tests/fst_test_util.c
@@ -0,0 +1,64 @@
1#include "fst_test_util.h"
2
3char *algs[] = {
4 "",
5 "U", "U2", "U'", "D", "D2", "D'", "R", "R2", "R'",
6 "L", "L2", "L'", "F", "F2", "F'", "B", "B2", "B'",
7 "U2 R2 U2 R2 U2",
8 "U2 F2 R2 B2 U2 D2 F2 L2 B2",
9 "RUR'URU2R'",
10 "L2 D R U2 B2 L",
11 "R'U'F",
12 "F2 U' R2 D' B2 D2 R2 D2 R2 U' F L' U' R B F2 R B' D2",
13 "D L2 F2 R2 D R2 U L2 U' B2 D L' F2 U2 B' L D' U' R' B2 F2",
14 "F' L2 F' D' R F2 L U L' D2 R2 F2 D2 R2 B' L2 B2 U2 F D2 B",
15 NULL,
16};
17
18bool
19equal_and_log(Cube *c, Cube *d)
20{
21 bool ret = equal(c, d);
22
23 if (!ret) {
24 printf("These cubes should be equal, but are not:\n\n");
25 print_cube(c);
26 printf("\n");
27 print_cube(d);
28 printf("\n");
29 }
30
31 return ret;
32}
33
34bool
35try_str(CubeTester f, char *algstr, char *msg)
36{
37 bool b;
38 Alg *a;
39 Cube c;
40
41 a = new_alg(algstr);
42 make_solved(&c);
43 apply_alg(a, &c);
44
45 if (!(b = f(&c, a)))
46 printf("%s with alg %s\n", msg, algstr);
47
48 free_alg(a);
49
50 return b;
51}
52
53bool
54try_all_str(CubeTester f, char *msg)
55{
56 bool b;
57 int i;
58
59 b = true;
60 for (i = 0; algs[i] != NULL; i++)
61 b = b && try_str(f, algs[i], msg);
62
63 return b;
64}
diff --git a/tests/fst_test_util.h b/tests/fst_test_util.h
new file mode 100644
index 0000000..b67b945
--- /dev/null
+++ b/tests/fst_test_util.h
@@ -0,0 +1,7 @@
1#include "../src/fst.h"
2
3extern char *algs[];
4
5bool equal_and_log(Cube *c, Cube *d);
6bool try_str(CubeTester f, char *algstr, char *msg);
7bool try_all_str(CubeTester f, char *msg);
diff --git a/tests/inc.h b/tests/inc.h
deleted file mode 100644
index 53c5fdf..0000000
--- a/tests/inc.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <stdio.h>
diff --git a/tests/nissy_tests.c b/tests/nissy_tests.c
new file mode 100644
index 0000000..d959423
--- /dev/null
+++ b/tests/nissy_tests.c
@@ -0,0 +1,12 @@
1#include <stdio.h>
2
3void fst_pre_init_testall();
4void fst_post_init_testall();
5
6int main() {
7 fst_pre_init_testall();
8 fst_post_init_testall();
9
10 printf("All tests passed.\n");
11 return 0;
12}
diff --git a/tests/test_all.c b/tests/test_all.c
deleted file mode 100644
index 4daeec0..0000000
--- a/tests/test_all.c
+++ /dev/null
@@ -1,10 +0,0 @@
1#include "inc.h"
2
3void test_fst_all();
4
5int main() {
6 test_fst_all();
7
8 printf("All tests passed.\n");
9 return 0;
10}
diff --git a/tests/test_fst.c b/tests/test_fst.c
deleted file mode 100644
index ad1caba..0000000
--- a/tests/test_fst.c
+++ /dev/null
@@ -1,184 +0,0 @@
1#include "inc.h"
2#include "../src/fst.h"
3
4static bool cube_to_fst_to_cube(Cube *c, Alg *a);
5static bool fst_consistent(Cube *c, Alg *a);
6static bool fst_move_test(Cube *c, Alg *a);
7static bool fst_inverse_test(Cube *c, Alg *a);
8static bool try_str(CubeTester f, char *algstr, char *msg);
9static bool try_all_str(CubeTester f, char *msg);
10
11static bool test_fst_consistent_algs();
12static bool test_cube_to_fst_to_cube_algs();
13static bool test_fst_move_algs();
14static bool test_fst_inverse_algs();
15
16static Tester test[] = {
17 test_fst_consistent_algs,
18 test_cube_to_fst_to_cube_algs,
19 test_fst_move_algs,
20 test_fst_inverse_algs,
21 NULL
22};
23
24static char *name[] = {
25 "Consistency of FST (converted from cube)",
26 "Cube to FST to cube",
27 "FST move",
28 "FST inverse",
29};
30
31static char *algs[] = {
32 "",
33 "U", "U2", "U'", "D", "D2", "D'", "R", "R2", "R'",
34 "L", "L2", "L'", "F", "F2", "F'", "B", "B2", "B'",
35 "U2 R2 U2 R2 U2",
36 "U2 F2 R2 B2 U2 D2 F2 L2 B2",
37 "RUR'URU2R'",
38 "L2 D R U2 B2 L",
39 "R'U'F",
40 "F2 U' R2 D' B2 D2 R2 D2 R2 U' F L' U' R B F2 R B' D2",
41 "D L2 F2 R2 D R2 U L2 U' B2 D L' F2 U2 B' L D' U' R' B2 F2",
42 "F' L2 F' D' R F2 L U L' D2 R2 F2 D2 R2 B' L2 B2 U2 F D2 B",
43 NULL,
44};
45
46static bool
47fst_consistent(Cube *c, Alg *a)
48{
49 FstCube fst;
50
51 fst = cube_to_fst(c);
52
53 /* TODO: check consistency of fr_* and rd_* with uf_* */
54
55 return true;
56}
57
58static bool
59cube_to_fst_to_cube(Cube *c, Alg *a)
60{
61 Cube d;
62 FstCube fst;
63
64 fst = cube_to_fst(c);
65 fst_to_cube(fst, &d);
66
67 if (!equal(c, &d)) {
68 printf("Cubes are different:\n\n");
69 printf("Cube 1:\n");
70 print_cube(c);
71 printf("\nCube 2:\n");
72 print_cube(&d);
73 printf("\n");
74 return false;
75 }
76
77 return true;
78}
79
80static bool
81fst_move_test(Cube *c, Alg *a)
82{
83 int i;
84 Cube d;
85 FstCube fst;
86
87 fst = cube_to_fst(c);
88
89 for (i = 0; i < a->len; i++) {
90 if (a->inv[i] || a->move[i] > B3) {
91 printf("Cannot apply the following alg to FST: ");
92 print_alg(a, false);
93 return false;
94 }
95 fst = fst_move(a->move[i], fst);
96 }
97
98 fst_to_cube(fst, &d);
99
100 return equal(c, &d);
101}
102
103static bool
104fst_inverse_test(Cube *c, Alg *a)
105{
106 Cube d;
107
108 fst_to_cube(fst_inverse(cube_to_fst(c)), &d);
109 invert_cube(c);
110
111 return equal(c, &d);
112}
113
114static bool
115try_str(CubeTester f, char *algstr, char *msg)
116{
117 bool b;
118 Alg *a;
119 Cube c;
120
121 a = new_alg(algstr);
122 make_solved(&c);
123 apply_alg(a, &c);
124
125 if (!(b = f(&c, a)))
126 printf("%s with alg %s\n", msg, algstr);
127
128 free_alg(a);
129
130 return b;
131}
132
133static bool
134try_all_str(CubeTester f, char *msg)
135{
136 bool b;
137 int i;
138
139 b = true;
140 for (i = 0; algs[i] != NULL; i++)
141 b = b && try_str(f, algs[i], msg);
142
143 return b;
144}
145
146static bool
147test_cube_to_fst_to_cube_algs()
148{
149 return try_all_str(cube_to_fst_to_cube, "Cube to FST to cube failed");
150}
151
152static bool
153test_fst_consistent_algs()
154{
155 return try_all_str(fst_consistent, "FST from cube not consistent");
156}
157
158static bool
159test_fst_move_algs()
160{
161 return try_all_str(fst_move_test, "FST move incorrect");
162}
163
164static bool
165test_fst_inverse_algs()
166{
167 return try_all_str(fst_inverse_test, "FST test incorrect");
168}
169
170void test_fst_all() {
171 int i;
172
173 init_trans();
174
175 for (i = 0; test[i] != NULL; i++) {
176 printf("Test: %s\n", name[i]);
177 if (!test[i]()) {
178 printf("Failed!\n");
179 exit(1);
180 }
181 printf("Passed.\n\n");
182 }
183 printf("All FST tests passed.\n\n");
184}

Generated with cgit - Back to sebastiano.tronto.net