aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/nissy.c1
-rw-r--r--src/nissy.h7
-rw-r--r--src/solvers/coord/common.h2
-rw-r--r--src/solvers/coord/coord.h1
-rw-r--r--src/solvers/coord/dr.h22
-rw-r--r--src/solvers/coord/dreo.h102
-rw-r--r--src/solvers/coord/eo.h15
-rw-r--r--src/solvers/coord/gendata.h11
-rw-r--r--src/solvers/coord/list.h1
-rw-r--r--src/solvers/coord/solve.h27
-rw-r--r--src/solvers/coord/types_macros.h1
-rw-r--r--src/utils/constants.h4
12 files changed, 178 insertions, 16 deletions
diff --git a/src/nissy.c b/src/nissy.c
index 738d6e1..40e4be7 100644
--- a/src/nissy.c
+++ b/src/nissy.c
@@ -566,6 +566,7 @@ nissy_solve(
566 } 566 }
567 567
568 if (!issolvable(c)) { 568 if (!issolvable(c)) {
569/* TODO: this is step-dependent */
569 LOG("solve: cube is not solvable\n"); 570 LOG("solve: cube is not solvable\n");
570 return NISSY_ERROR_UNSOLVABLE_CUBE; 571 return NISSY_ERROR_UNSOLVABLE_CUBE;
571 } 572 }
diff --git a/src/nissy.h b/src/nissy.h
index 23bcb8b..add88e4 100644
--- a/src/nissy.h
+++ b/src/nissy.h
@@ -363,8 +363,11 @@ different from what specified, or simply ill-formed.
363#define NISSY_ERROR_INVALID_CUBE -10LL 363#define NISSY_ERROR_INVALID_CUBE -10LL
364 364
365/* 365/*
366The value NISSY_ERROR_UNSOLVABLE_CUBE means that the provided cube is 366The value NISSY_ERROR_UNSOLVABLE_CUBE means that the provided cube is in
367in an unsolvable state. 367an unsolvable state for the given solver. This could mean either that the
368cube is not solvable at all (for example in case it has a single twisted
369corner), or that it is not ready for the given step (for example if the
370caller wants to solve a DR finish without the cube being in DR state).
368*/ 371*/
369#define NISSY_ERROR_UNSOLVABLE_CUBE -11LL 372#define NISSY_ERROR_UNSOLVABLE_CUBE -11LL
370 373
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
index 95c0e6c..2eb5ad0 100644
--- a/src/solvers/coord/common.h
+++ b/src/solvers/coord/common.h
@@ -125,7 +125,7 @@ coord_gendata_generic(
125 125
126 writetableinfo(&info, coord_datasize, data); 126 writetableinfo(&info, coord_datasize, data);
127 127
128 DBG_ASSERT(n == coord->sym.classes, 0, 128 DBG_ASSERT(n == coord->sym.classes, SIZE_MAX,
129 "%s coordinate data: computed %" PRIu64 " classes, " 129 "%s coordinate data: computed %" PRIu64 " classes, "
130 "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes); 130 "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes);
131 131
diff --git a/src/solvers/coord/coord.h b/src/solvers/coord/coord.h
index 11d41bc..2f24035 100644
--- a/src/solvers/coord/coord.h
+++ b/src/solvers/coord/coord.h
@@ -2,6 +2,7 @@
2#include "common.h" 2#include "common.h"
3#include "eo.h" 3#include "eo.h"
4#include "dr.h" 4#include "dr.h"
5#include "dreo.h"
5#include "list.h" 6#include "list.h"
6#include "utils.h" 7#include "utils.h"
7#include "gendata.h" 8#include "gendata.h"
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h
index 314d4f1..3bc4c6d 100644
--- a/src/solvers/coord/dr.h
+++ b/src/solvers/coord/dr.h
@@ -1,5 +1,5 @@
1#define DREOESEP_CLASSES UINT64_C(64430) 1#define DREOESEP_CLASSES UINT64_C(64430)
2#define DREOESEP_MAX (POW_2_11 * COMB_12_4) 2#define DREOESEP_MAX (POW_2_11 * COMB_12_4)
3 3
4STATIC uint64_t coord_dreoesep_nosym(cube_t); 4STATIC uint64_t coord_dreoesep_nosym(cube_t);
5STATIC cube_t invcoord_dreoesep_nosym(uint64_t); 5STATIC cube_t invcoord_dreoesep_nosym(uint64_t);
@@ -10,6 +10,8 @@ STATIC cube_t coordinate_dr_cube(uint64_t, const void *);
10STATIC bool coordinate_dr_isnasty(uint64_t, const void *); 10STATIC bool coordinate_dr_isnasty(uint64_t, const void *);
11STATIC size_t coordinate_dr_gendata(void *); 11STATIC size_t coordinate_dr_gendata(void *);
12 12
13STATIC bool is_eoco_solvable(cube_t);
14
13/* TODO: remove the following two when all coordinates are converted to unsigned */ 15/* TODO: remove the following two when all coordinates are converted to unsigned */
14STATIC uint64_t coord_co_u(cube_t c) { return (uint64_t)coord_co(c); } 16STATIC uint64_t coord_co_u(cube_t c) { return (uint64_t)coord_co(c); }
15STATIC cube_t invcoord_co_u(uint64_t i) { return invcoord_co((int64_t)i); } 17STATIC cube_t invcoord_co_u(uint64_t i) { return invcoord_co((int64_t)i); }
@@ -29,6 +31,7 @@ STATIC coord_t coordinate_dr = {
29 [AXIS_FB] = TRANS_FDr, 31 [AXIS_FB] = TRANS_FDr,
30 }, 32 },
31 .is_admissible = &solution_lastqt_cw, 33 .is_admissible = &solution_lastqt_cw,
34 .is_solvable = &is_eoco_solvable,
32 .sym = { 35 .sym = {
33 .classes = DREOESEP_CLASSES, 36 .classes = DREOESEP_CLASSES,
34 .max = DREOESEP_MAX, 37 .max = DREOESEP_MAX,
@@ -100,3 +103,18 @@ coordinate_dr_gendata(void *data)
100{ 103{
101 return coord_gendata_generic(&coordinate_dr, data); 104 return coord_gendata_generic(&coordinate_dr, data);
102} 105}
106
107STATIC bool
108is_eoco_solvable(cube_t cube) {
109 uint8_t c[8], e[12], i, cocount, eocount;
110
111 pieces(&cube, c, e);
112
113 for (i = 0, cocount = 0; i < 8; i++)
114 cocount += (c[i] & COBITS_2) >> COSHIFT;
115
116 for (i = 0, eocount = 0; i < 12; i++)
117 eocount += (e[i] & EOBIT) >> EOSHIFT;
118
119 return cocount % 3 == 0 && eocount % 2 == 0;
120}
diff --git a/src/solvers/coord/dreo.h b/src/solvers/coord/dreo.h
new file mode 100644
index 0000000..37de0d3
--- /dev/null
+++ b/src/solvers/coord/dreo.h
@@ -0,0 +1,102 @@
1#define DRESEP_CLASSES 81
2
3STATIC uint64_t coord_dresep_nosym(cube_t);
4STATIC cube_t invcoord_dresep_nosym(uint64_t);
5STATIC cube_t coordinate_dreo_merge(cube_t, cube_t);
6
7STATIC uint64_t coordinate_dreo_coord(cube_t, const void *);
8STATIC cube_t coordinate_dreo_cube(uint64_t, const void *);
9STATIC bool coordinate_dreo_isnasty(uint64_t, const void *);
10STATIC size_t coordinate_dreo_gendata(void *);
11
12STATIC bool is_dreo_solvable(cube_t);
13
14STATIC coord_t coordinate_dreo = {
15 .name = "DREO",
16 .coord = &coordinate_dreo_coord,
17 .cube = &coordinate_dreo_cube,
18 .isnasty = &coordinate_dreo_isnasty,
19 .gendata = coordinate_dreo_gendata,
20 .max = DRESEP_CLASSES * POW_3_7,
21 .trans_mask = TM_UDRLFIX,
22 .moves_mask = MM_EO,
23 .axistrans = {
24 [AXIS_UD] = TRANS_UFr,
25 [AXIS_RL] = TRANS_RFr,
26 [AXIS_FB] = TRANS_FDr,
27 },
28 .is_admissible = &solution_lastqt_cw,
29 .is_solvable = &is_dreo_solvable,
30 .sym = {
31 .classes = DRESEP_CLASSES,
32 .max = COMB_12_4,
33 .coord = &coord_dresep_nosym,
34 .cube = &invcoord_dresep_nosym,
35 .max2 = POW_3_7,
36 .coord2 = &coord_co_u,
37 .cube2 = &invcoord_co_u,
38 .merge = &coordinate_dreo_merge,
39 },
40};
41
42STATIC uint64_t
43coord_dresep_nosym(cube_t cube)
44{
45 return (uint64_t)coord_esep(cube) / COMB_8_4;
46}
47
48STATIC cube_t
49invcoord_dresep_nosym(uint64_t coord)
50{
51 return invcoord_esep(coord * COMB_8_4);
52}
53
54STATIC cube_t
55coordinate_dreo_merge(cube_t c1, cube_t c2)
56{
57 cube_t merged;
58
59 merged = c1;
60 copy_corners(&merged, c2);
61
62 return merged;
63}
64
65STATIC uint64_t
66coordinate_dreo_coord(cube_t cube, const void *data)
67{
68 return coord_coord_generic(&coordinate_dreo, cube, data);
69}
70
71STATIC cube_t
72coordinate_dreo_cube(uint64_t i, const void *data)
73{
74 return coord_cube_generic(&coordinate_dreo, i, data);
75}
76
77STATIC bool
78coordinate_dreo_isnasty(uint64_t i, const void *data)
79{
80 return coord_isnasty_generic(&coordinate_dreo, i, data);
81}
82
83STATIC size_t
84coordinate_dreo_gendata(void *data)
85{
86 return coord_gendata_generic(&coordinate_dreo, data);
87}
88
89STATIC bool
90is_dreo_solvable(cube_t cube) {
91 uint8_t c[8], e[12], i, cocount;
92
93 if (coord_eo(cube) != 0)
94 return false;
95
96 pieces(&cube, c, e);
97
98 for (i = 0, cocount = 0; i < 8; i++)
99 cocount += (c[i] & COBITS_2) >> COSHIFT;
100
101 return cocount % 3 == 0;
102}
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
index b83be01..a0685c4 100644
--- a/src/solvers/coord/eo.h
+++ b/src/solvers/coord/eo.h
@@ -2,6 +2,7 @@ STATIC uint64_t coordinate_eo_coord(cube_t, const void *);
2STATIC cube_t coordinate_eo_cube(uint64_t, const void *); 2STATIC cube_t coordinate_eo_cube(uint64_t, const void *);
3STATIC bool coordinate_eo_isnasty(uint64_t, const void *); 3STATIC bool coordinate_eo_isnasty(uint64_t, const void *);
4STATIC size_t coordinate_eo_gendata(void *); 4STATIC size_t coordinate_eo_gendata(void *);
5STATIC bool is_eo_even(cube_t);
5 6
6STATIC coord_t coordinate_eo = { 7STATIC coord_t coordinate_eo = {
7 .name = "EO", 8 .name = "EO",
@@ -18,6 +19,7 @@ STATIC coord_t coordinate_eo = {
18 [AXIS_FB] = TRANS_UFr, 19 [AXIS_FB] = TRANS_UFr,
19 }, 20 },
20 .is_admissible = &solution_lastqt_cw, 21 .is_admissible = &solution_lastqt_cw,
22 .is_solvable = &is_eo_even,
21 .sym = {0}, 23 .sym = {0},
22}; 24};
23 25
@@ -46,3 +48,16 @@ coordinate_eo_gendata(void *data)
46{ 48{
47 return 0; 49 return 0;
48} 50}
51
52STATIC bool
53is_eo_even(cube_t cube)
54{
55 uint8_t c[8], e[12], i, count;
56
57 pieces(&cube, c, e);
58
59 for (i = 0, count = 0; i < 12; i++)
60 count += (e[i] & EOBIT) >> EOSHIFT;
61
62 return count % 2 == 0;
63}
diff --git a/src/solvers/coord/gendata.h b/src/solvers/coord/gendata.h
index 423dad1..63e1631 100644
--- a/src/solvers/coord/gendata.h
+++ b/src/solvers/coord/gendata.h
@@ -39,6 +39,9 @@ gendata_coord(const coord_t coord[static 1], void *buf)
39 39
40 coord_data = buf == NULL ? NULL : ((uint8_t *)buf) + INFOSIZE; 40 coord_data = buf == NULL ? NULL : ((uint8_t *)buf) + INFOSIZE;
41 coord_dsize = coord->gendata(coord_data); 41 coord_dsize = coord->gendata(coord_data);
42 if (coord_dsize == SIZE_MAX)
43 goto gendata_coord_error;
44
42 ninfo = coord_dsize == 0 ? 1 : 2; 45 ninfo = coord_dsize == 0 ? 1 : 2;
43 tablesize = DIV_ROUND_UP(coord->max, 2); 46 tablesize = DIV_ROUND_UP(coord->max, 2);
44 47
@@ -77,6 +80,10 @@ gendata_coord(const coord_t coord[static 1], void *buf)
77 80
78gendata_coord_return_size: 81gendata_coord_return_size:
79 return ninfo * INFOSIZE + coord_dsize + tablesize; 82 return ninfo * INFOSIZE + coord_dsize + tablesize;
83
84gendata_coord_error:
85 LOG("An unexpected error occurred when generating the data.\n");
86 return 0;
80} 87}
81 88
82STATIC tableinfo_t 89STATIC tableinfo_t
@@ -167,6 +174,8 @@ genptable_coord_fillneighbors(
167 c = coord->cube(i, data); 174 c = coord->cube(i, data);
168 tot = 0; 175 tot = 0;
169 for (m = 0; m < NMOVES; m++) { 176 for (m = 0; m < NMOVES; m++) {
177 if (!((UINT32_C(1) << (uint32_t)m) & coord->moves_mask))
178 continue;
170 moved = move(c, m); 179 moved = move(c, m);
171 ii = coord->coord(moved, data); 180 ii = coord->coord(moved, data);
172 isnasty = coord->isnasty(ii, data); 181 isnasty = coord->isnasty(ii, data);
@@ -216,6 +225,8 @@ genptable_coord_fillfromnew(
216 for (j = 0, found = false; j < nsim && !found; j++) { 225 for (j = 0, found = false; j < nsim && !found; j++) {
217 c = coord->cube(sim[j], data); 226 c = coord->cube(sim[j], data);
218 for (m = 0; m < NMOVES; m++) { 227 for (m = 0; m < NMOVES; m++) {
228 if (!((UINT32_C(1) << (uint32_t)m) & coord->moves_mask))
229 continue;
219 ii = coord->coord(move(c, m), data); 230 ii = coord->coord(move(c, m), data);
220 if (get_coord_pval(coord, table, ii) < d) { 231 if (get_coord_pval(coord, table, ii) < d) {
221 found = true; 232 found = true;
diff --git a/src/solvers/coord/list.h b/src/solvers/coord/list.h
index 7d43d45..9409bb6 100644
--- a/src/solvers/coord/list.h
+++ b/src/solvers/coord/list.h
@@ -1,5 +1,6 @@
1coord_t *all_coordinates[] = { 1coord_t *all_coordinates[] = {
2 &coordinate_eo, 2 &coordinate_eo,
3 &coordinate_dr, 3 &coordinate_dr,
4 &coordinate_dreo,
4 NULL 5 NULL
5}; 6};
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
index fa4134a..8806d17 100644
--- a/src/solvers/coord/solve.h
+++ b/src/solvers/coord/solve.h
@@ -135,11 +135,10 @@ solve_coord_dfs(dfsarg_solve_coord_t arg[static 1])
135 ret = 0; 135 ret = 0;
136 if (coord_continue_onnormal(arg)) { 136 if (coord_continue_onnormal(arg)) {
137 l = arg->solution_moves->nmoves; 137 l = arg->solution_moves->nmoves;
138 if (l == 0) { 138 mm = arg->coord->moves_mask;
139 mm = MM_ALLMOVES; 139 if (l != 0) {
140 } else {
141 m = arg->solution_moves->moves[l-1]; 140 m = arg->solution_moves->moves[l-1];
142 mm = allowedmask[movebase(m)]; 141 mm &= allowedmask[movebase(m)];
143 } 142 }
144 arg->solution_moves->nmoves++; 143 arg->solution_moves->nmoves++;
145 arg->lastisnormal = true; 144 arg->lastisnormal = true;
@@ -165,11 +164,10 @@ solve_coord_dfs(dfsarg_solve_coord_t arg[static 1])
165 164
166 if (coord_continue_oninverse(arg)) { 165 if (coord_continue_oninverse(arg)) {
167 l = arg->solution_moves->npremoves; 166 l = arg->solution_moves->npremoves;
168 if (l == 0) { 167 mm = arg->coord->moves_mask;
169 mm = MM_ALLMOVES; 168 if (l != 0) {
170 } else {
171 m = arg->solution_moves->premoves[l-1]; 169 m = arg->solution_moves->premoves[l-1];
172 mm = allowedmask[movebase(m)]; 170 mm &= allowedmask[movebase(m)];
173 } 171 }
174 arg->solution_moves->npremoves++; 172 arg->solution_moves->npremoves++;
175 arg->lastisnormal = false; 173 arg->lastisnormal = false;
@@ -264,6 +262,12 @@ solve_coord(
264 solution_settings_t solution_settings; 262 solution_settings_t solution_settings;
265 solution_list_t solution_list; 263 solution_list_t solution_list;
266 264
265 t = coord->axistrans[axis];
266 c = transform(cube, t);
267
268 if (!coord->is_solvable(c))
269 goto solve_coord_error_unsolvable;
270
267 if (!solution_list_init(&solution_list, solutions_size, sols)) 271 if (!solution_list_init(&solution_list, solutions_size, sols))
268 goto solve_coord_error_buffer; 272 goto solve_coord_error_buffer;
269 273
@@ -280,9 +284,6 @@ solve_coord(
280 ptable = (uint8_t *)data + info.next + INFOSIZE; 284 ptable = (uint8_t *)data + info.next + INFOSIZE;
281 } 285 }
282 286
283 t = coord->axistrans[axis];
284 c = transform(cube, t);
285
286 solution_moves_reset(&solution_moves); 287 solution_moves_reset(&solution_moves);
287 288
288 solution_settings = (solution_settings_t) { 289 solution_settings = (solution_settings_t) {
@@ -351,4 +352,8 @@ solve_coord_error_data:
351solve_coord_error_buffer: 352solve_coord_error_buffer:
352 LOG("Could not append solution to buffer: size too small\n"); 353 LOG("Could not append solution to buffer: size too small\n");
353 return NISSY_ERROR_BUFFER_SIZE; 354 return NISSY_ERROR_BUFFER_SIZE;
355
356solve_coord_error_unsolvable:
357 LOG("Cube not ready for solving %s\n", coord->name);
358 return NISSY_ERROR_UNSOLVABLE_CUBE;
354} 359}
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
index a2eaefe..84ed8eb 100644
--- a/src/solvers/coord/types_macros.h
+++ b/src/solvers/coord/types_macros.h
@@ -25,6 +25,7 @@ typedef struct {
25 uint64_t trans_mask; 25 uint64_t trans_mask;
26 uint8_t axistrans[3]; 26 uint8_t axistrans[3];
27 bool (*is_admissible)(const solution_moves_t[static 1]); 27 bool (*is_admissible)(const solution_moves_t[static 1]);
28 bool (*is_solvable)(cube_t);
28 struct { 29 struct {
29 size_t classes; 30 size_t classes;
30 uint64_t max; 31 uint64_t max;
diff --git a/src/utils/constants.h b/src/utils/constants.h
index ba7f4d4..5ccff06 100644
--- a/src/utils/constants.h
+++ b/src/utils/constants.h
@@ -116,6 +116,10 @@ STATIC int64_t binomial[12][12] = {
116 116
117#define TM_ALLTRANS UINT64_C(0xFFFFFFFFFFFF) 117#define TM_ALLTRANS UINT64_C(0xFFFFFFFFFFFF)
118#define TM_SINGLE(t) (UINT64_C(1) << (uint64_t)(t)) 118#define TM_SINGLE(t) (UINT64_C(1) << (uint64_t)(t))
119#define TM_UDRLFIX (\
120 TM_SINGLE(TRANS_UFr) | TM_SINGLE(TRANS_UBr) | TM_SINGLE(TRANS_UFm) | \
121 TM_SINGLE(TRANS_UBm) | TM_SINGLE(TRANS_DFr) | TM_SINGLE(TRANS_DBr) | \
122 TM_SINGLE(TRANS_DFm) | TM_SINGLE(TRANS_DBm))
119#define TM_UDFIX (\ 123#define TM_UDFIX (\
120 TM_SINGLE(TRANS_UFr) | TM_SINGLE(TRANS_UBr) | TM_SINGLE(TRANS_URr) | \ 124 TM_SINGLE(TRANS_UFr) | TM_SINGLE(TRANS_UBr) | TM_SINGLE(TRANS_URr) | \
121 TM_SINGLE(TRANS_ULr) | TM_SINGLE(TRANS_UFm) | TM_SINGLE(TRANS_UBm) | \ 125 TM_SINGLE(TRANS_ULr) | TM_SINGLE(TRANS_UFm) | TM_SINGLE(TRANS_UBm) | \

Generated with cgit - Back to sebastiano.tronto.net