aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commands.c34
-rw-r--r--src/cubetypes.h231
-rw-r--r--src/pruning.c10
-rw-r--r--src/solve.c193
-rw-r--r--src/steps.c13
-rw-r--r--src/steps.h2
6 files changed, 333 insertions, 150 deletions
diff --git a/src/commands.c b/src/commands.c
index 10e4eb8..b089a1c 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -28,7 +28,7 @@ Command
28solve_cmd = { 28solve_cmd = {
29 .name = "solve", 29 .name = "solve",
30 .usage = "solve STEP [OPTIONS] SCRAMBLE", 30 .usage = "solve STEP [OPTIONS] SCRAMBLE",
31 .description = "Solve a step", 31 .description = "Solve a step; see command steps for a list of steps",
32 .parse_args = solve_parse_args, 32 .parse_args = solve_parse_args,
33 .exec = solve_exec 33 .exec = solve_exec
34}; 34};
@@ -116,6 +116,7 @@ solve_parse_args(int c, char **v)
116 a->opts->min_moves = 0; 116 a->opts->min_moves = 0;
117 a->opts->max_moves = 20; 117 a->opts->max_moves = 20;
118 a->opts->max_solutions = 1; 118 a->opts->max_solutions = 1;
119 a->opts->nthreads = 1;
119 a->opts->optimal_only = false; 120 a->opts->optimal_only = false;
120 a->opts->can_niss = false; 121 a->opts->can_niss = false;
121 a->opts->verbose = false; 122 a->opts->verbose = false;
@@ -127,7 +128,8 @@ solve_parse_args(int c, char **v)
127 val = strtol(v[++i], NULL, 10); 128 val = strtol(v[++i], NULL, 10);
128 if (val < 0 || val > 100) { 129 if (val < 0 || val > 100) {
129 fprintf(stderr, 130 fprintf(stderr,
130 "Invalid min number of moves.\n"); 131 "Invalid min number of moves"
132 "(0 <= m <= 100).\n");
131 return a; 133 return a;
132 } 134 }
133 a->opts->min_moves = val; 135 a->opts->min_moves = val;
@@ -135,10 +137,20 @@ solve_parse_args(int c, char **v)
135 val = strtol(v[++i], NULL, 10); 137 val = strtol(v[++i], NULL, 10);
136 if (val < 0 || val > 100) { 138 if (val < 0 || val > 100) {
137 fprintf(stderr, 139 fprintf(stderr,
138 "Invalid max number of moves.\n"); 140 "Invalid max number of moves"
141 "(0 <= M <= 100).\n");
139 return a; 142 return a;
140 } 143 }
141 a->opts->max_moves = val; 144 a->opts->max_moves = val;
145 } else if (!strcmp(v[i], "-t")) {
146 val = strtol(v[++i], NULL, 10);
147 if (val < 1 || val > 64) {
148 fprintf(stderr,
149 "Invalid number of threads."
150 "1 <= t <= 64\n");
151 return a;
152 }
153 a->opts->nthreads = val;
142 } else if (!strcmp(v[i], "-s")) { 154 } else if (!strcmp(v[i], "-s")) {
143 val = strtol(v[++i], NULL, 10); 155 val = strtol(v[++i], NULL, 10);
144 if (val < 1 || val > 1000000) { 156 if (val < 1 || val > 1000000) {
@@ -255,11 +267,19 @@ print_exec(CommandArgs *args)
255static void 267static void
256help_exec(CommandArgs *args) 268help_exec(CommandArgs *args)
257{ 269{
258 /* TODO: print full nissy manpage */
259 if (args->command == NULL) { 270 if (args->command == NULL) {
260 printf("Type help COMMAND for information on a "); 271 printf(
261 printf("specific command.\n"); 272 "Use the nissy command \"help COMMAND\" for a short "
262 printf("A more complete manual page is work in progress.\n"); 273 "description of a specific command.\n"
274 "Use the nissy command \"commands\" for a list of "
275 "available commands.\n"
276 "See the manual page for more details. The manual"
277 " page is available with \"man nissy\" on a UNIX"
278 " system (such a Linux or MacOS) or in pdf and html"
279 " format in the docs folder.\n"
280 "Nissy is available for free at "
281 "https://github.com/sebastianotronto/nissy"
282 );
263 } else { 283 } else {
264 printf("Command %s: %s\nusage: %s\n", args->command->name, 284 printf("Command %s: %s\nusage: %s\n", args->command->name,
265 args->command->description, args->command->usage); 285 args->command->description, args->command->usage);
diff --git a/src/cubetypes.h b/src/cubetypes.h
index 334662c..7eb803e 100644
--- a/src/cubetypes.h
+++ b/src/cubetypes.h
@@ -3,6 +3,7 @@
3 3
4#include <stdbool.h> 4#include <stdbool.h>
5#include <inttypes.h> 5#include <inttypes.h>
6#include <pthread.h>
6 7
7#define NMOVES 55 /* Actually 55, but one is NULLMOVE */ 8#define NMOVES 55 /* Actually 55, but one is NULLMOVE */
8#define NTRANS 48 9#define NTRANS 48
@@ -87,6 +88,7 @@ typedef struct prunedata PruneData;
87typedef struct solveoptions SolveOptions; 88typedef struct solveoptions SolveOptions;
88typedef struct step Step; 89typedef struct step Step;
89typedef struct symdata SymData; 90typedef struct symdata SymData;
91typedef struct threaddata ThreadData;
90 92
91typedef Cube (*AntiIndexer) (uint64_t); 93typedef Cube (*AntiIndexer) (uint64_t);
92typedef bool (*Checker) (Cube); 94typedef bool (*Checker) (Cube);
@@ -104,186 +106,205 @@ typedef Trans (*TransDetector) (Cube);
104struct 106struct
105alg 107alg
106{ 108{
107 Move * move; 109 Move * move;
108 bool * inv; 110 bool * inv;
109 int len; 111 int len;
110 int allocated; 112 int allocated;
111}; 113};
112 114
113struct 115struct
114alglist 116alglist
115{ 117{
116 AlgListNode * first; 118 AlgListNode * first;
117 AlgListNode * last; 119 AlgListNode * last;
118 int len; 120 int len;
119}; 121};
120 122
121struct 123struct
122alglistnode 124alglistnode
123{ 125{
124 Alg * alg; 126 Alg * alg;
125 AlgListNode * next; 127 AlgListNode * next;
126}; 128};
127 129
128struct 130struct
129block 131block
130{ 132{
131 bool edge[12]; 133 bool edge[12];
132 bool corner[8]; 134 bool corner[8];
133 bool center[6]; 135 bool center[6];
134}; 136};
135 137
136struct 138struct
137command 139command
138{ 140{
139 char * name; 141 char * name;
140 char * usage; 142 char * usage;
141 char * description; 143 char * description;
142 ArgParser parse_args; 144 ArgParser parse_args;
143 Exec exec; 145 Exec exec;
144}; 146};
145 147
146struct 148struct
147commandargs 149commandargs
148{ 150{
149 bool success; 151 bool success;
150 Alg * scramble; 152 Alg * scramble;
151 SolveOptions * opts; 153 SolveOptions * opts;
152 Step * step; 154 Step * step;
153 Command * command; /* For help */ 155 Command * command; /* For help */
154}; 156};
155 157
156struct 158struct
157coordinate 159coordinate
158{ 160{
159 Indexer index; 161 Indexer index;
160 AntiIndexer cube; 162 AntiIndexer cube;
161 uint64_t max; 163 uint64_t max;
162 int ntrans; 164 int ntrans;
163 Trans * trans; 165 Trans * trans;
164}; 166};
165 167
166struct 168struct
167cube 169cube
168{ 170{
169 int epose; 171 int epose;
170 int eposs; 172 int eposs;
171 int eposm; 173 int eposm;
172 int eofb; 174 int eofb;
173 int eorl; 175 int eorl;
174 int eoud; 176 int eoud;
175 int cp; 177 int cp;
176 int coud; 178 int coud;
177 int cofb; 179 int cofb;
178 int corl; 180 int corl;
179 int cpos; 181 int cpos;
180}; 182};
181 183
182struct 184struct
183cubearray 185cubearray
184{ 186{
185 int * ep; 187 int * ep;
186 int * eofb; 188 int * eofb;
187 int * eorl; 189 int * eorl;
188 int * eoud; 190 int * eoud;
189 int * cp; 191 int * cp;
190 int * coud; 192 int * coud;
191 int * corl; 193 int * corl;
192 int * cofb; 194 int * cofb;
193 int * cpos; 195 int * cpos;
194}; 196};
195 197
196struct 198struct
197cubetarget 199cubetarget
198{ 200{
199 Cube cube; 201 Cube cube;
200 int target; 202 int target;
201}; 203};
202 204
203struct 205struct
204dfsdata 206dfsdata
205{ 207{
206 int d; 208 int d;
207 int m; 209 int m;
208 int lb; 210 int lb;
209 bool niss; 211 bool niss;
210 Move last1; 212 Move last1;
211 Move last2; 213 Move last2;
212 AlgList * sols; 214 AlgList * sols;
213 Alg * current_alg; 215 pthread_mutex_t * sols_mutex;
214 Move sorted_moves[NMOVES]; 216 Alg * current_alg;
215 int move_position[NMOVES]; 217 Move * sorted_moves;
216 uint8_t * visited; 218 int * move_position;
219 uint8_t * visited;
217}; 220};
218 221
219struct 222struct
220piecefilter 223piecefilter
221{ 224{
222 bool epose; 225 bool epose;
223 bool eposs; 226 bool eposs;
224 bool eposm; 227 bool eposm;
225 bool eofb; 228 bool eofb;
226 bool eorl; 229 bool eorl;
227 bool eoud; 230 bool eoud;
228 bool cp; 231 bool cp;
229 bool coud; 232 bool coud;
230 bool cofb; 233 bool cofb;
231 bool corl; 234 bool corl;
232 bool cpos; 235 bool cpos;
233}; 236};
234 237
235struct 238struct
236prunedata 239prunedata
237{ 240{
238 char * filename; 241 char * filename;
239 uint8_t * ptable; 242 uint8_t * ptable;
240 bool generated; 243 bool generated;
241 uint64_t n; 244 uint64_t n;
242 Coordinate * coord; 245 Coordinate * coord;
243 Moveset moveset; 246 Moveset moveset;
244}; 247};
245 248
246struct 249struct
247solveoptions 250solveoptions
248{ 251{
249 int min_moves; 252 int min_moves;
250 int max_moves; 253 int max_moves;
251 int max_solutions; 254 int max_solutions;
252 bool optimal_only; 255 int nthreads;
253 bool can_niss; 256 bool optimal_only;
254 bool verbose; 257 bool can_niss;
255 bool all; 258 bool verbose;
256 bool print_number; 259 bool all;
260 bool print_number;
257}; 261};
258 262
259struct 263struct
260step 264step
261{ 265{
262 char * shortname; 266 char * shortname;
263 char * name; 267 char * name;
264 Estimator estimate; 268 Estimator estimate;
265 Checker ready; 269 Checker ready;
266 char * ready_msg; 270 char * ready_msg;
267 Validator is_valid; 271 Validator is_valid;
268 Moveset moveset; 272 Moveset moveset;
269 Trans pre_trans; 273 Trans pre_trans;
270 TransDetector detect; 274 TransDetector detect;
271 int ntables; 275 int ntables;
272 PruneData * tables[10]; 276 PruneData * tables[10];
273}; 277};
274 278
275struct 279struct
276symdata 280symdata
277{ 281{
278 char * filename; 282 char * filename;
279 bool generated; 283 bool generated;
280 Coordinate * coord; 284 Coordinate * coord;
281 Coordinate * sym_coord; 285 Coordinate * sym_coord;
282 int ntrans; 286 int ntrans;
283 Trans * trans; 287 Trans * trans;
284 uint64_t * class; 288 uint64_t * class;
285 Cube * rep; 289 Cube * rep;
286 Trans * transtorep; 290 Trans * transtorep;
291};
292
293struct
294threaddata
295{
296 int thid;
297 Cube cube;
298 Step * step;
299 int depth;
300 Move * sorted_moves;
301 int * move_position;
302 SolveOptions * opts;
303 AlgList * start;
304 AlgListNode ** node;
305 AlgList * sols;
306 pthread_mutex_t * start_mutex;
307 pthread_mutex_t * sols_mutex;
287}; 308};
288 309
289#endif 310#endif
diff --git a/src/pruning.c b/src/pruning.c
index 1369892..2c6f348 100644
--- a/src/pruning.c
+++ b/src/pruning.c
@@ -95,7 +95,7 @@ pd_khuge_HTM = {
95void 95void
96genptable(PruneData *pd) 96genptable(PruneData *pd)
97{ 97{
98 Move ms[NMOVES]; 98 Move *ms;
99 uint64_t j, oldn; 99 uint64_t j, oldn;
100 DfsData dd; 100 DfsData dd;
101 101
@@ -112,6 +112,7 @@ genptable(PruneData *pd)
112 112
113 fprintf(stderr, "Cannot load %s, generating it\n", pd->filename); 113 fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
114 114
115 ms = malloc(NMOVES * sizeof(Move));
115 moveset_to_list(pd->moveset, ms); 116 moveset_to_list(pd->moveset, ms);
116 117
117 for (j = 0; j < pd->coord->max; j++) 118 for (j = 0; j < pd->coord->max; j++)
@@ -119,6 +120,7 @@ genptable(PruneData *pd)
119 120
120 dd = (DfsData) { .m = 0 }; 121 dd = (DfsData) { .m = 0 };
121 dd.visited = malloc((ptablesize(pd)/4 + 1) * sizeof(uint8_t)); 122 dd.visited = malloc((ptablesize(pd)/4 + 1) * sizeof(uint8_t));
123 dd.sorted_moves = malloc(NMOVES * sizeof(Move));
122 moveset_to_list(pd->moveset, dd.sorted_moves); 124 moveset_to_list(pd->moveset, dd.sorted_moves);
123 oldn = 0; 125 oldn = 0;
124 pd->n = 0; 126 pd->n = 0;
@@ -136,14 +138,16 @@ genptable(PruneData *pd)
136 if (!write_ptable_file(pd)) 138 if (!write_ptable_file(pd))
137 fprintf(stderr, "Error writing ptable file\n"); 139 fprintf(stderr, "Error writing ptable file\n");
138 140
141 free(ms);
139 free(dd.visited); 142 free(dd.visited);
143 free(dd.sorted_moves);
140} 144}
141*/ 145*/
142 146
143void 147void
144genptable(PruneData *pd) 148genptable(PruneData *pd)
145{ 149{
146 Move ms[NMOVES]; 150 Move *ms;
147 int d; 151 int d;
148 uint64_t j, oldn; 152 uint64_t j, oldn;
149 153
@@ -161,6 +165,7 @@ genptable(PruneData *pd)
161 165
162 fprintf(stderr, "Cannot load %s, generating it\n", pd->filename); 166 fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
163 167
168 ms = malloc(NMOVES * sizeof(Move));
164 moveset_to_list(pd->moveset, ms); 169 moveset_to_list(pd->moveset, ms);
165 170
166 /* We use 4 bits per value, so any distance >= 15 is set to 15 */ 171 /* We use 4 bits per value, so any distance >= 15 is set to 15 */
@@ -186,6 +191,7 @@ genptable(PruneData *pd)
186 if (!write_ptable_file(pd)) 191 if (!write_ptable_file(pd))
187 fprintf(stderr, "Error writing ptable file\n"); 192 fprintf(stderr, "Error writing ptable file\n");
188 193
194 free(ms);
189} 195}
190 196
191/* 197/*
diff --git a/src/solve.c b/src/solve.c
index 29f614b..a35a837 100644
--- a/src/solve.c
+++ b/src/solve.c
@@ -8,6 +8,8 @@ static void dfs_branch(Cube c, Step *s, SolveOptions *os, DfsData *dd);
8static bool dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd); 8static bool dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd);
9static void dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd); 9static void dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd);
10static bool dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd); 10static bool dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd);
11static void * instance_thread(void *arg);
12static void multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d);
11 13
12/* Local functions ***********************************************************/ 14/* Local functions ***********************************************************/
13 15
@@ -41,12 +43,24 @@ dfs(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
41static void 43static void
42dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd) 44dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
43{ 45{
44 Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves; 46 bool b = false;
47 int i;
48 Move m, l1, l2;
45 49
46 int i, maxnsol = opts->max_solutions; 50 l1 = dd->last1;
51 l2 = dd->last2;
47 52
48 for (i = 0; moves[i] != NULLMOVE && dd->sols->len < maxnsol; i++) { 53 for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
49 m = moves[i]; 54 /*
55 pthread_mutex_lock(dd->sols_mutex);
56 b = dd->sols->len >= opts->max_solutions;
57 pthread_mutex_unlock(dd->sols_mutex);
58 */
59
60 if (b)
61 break;
62
63 m = dd->sorted_moves[i];
50 if (allowed_next(m, dd)) { 64 if (allowed_next(m, dd)) {
51 dd->last2 = dd->last1; 65 dd->last2 = dd->last1;
52 dd->last1 = m; 66 dd->last1 = m;
@@ -68,8 +82,12 @@ dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd)
68 return false; 82 return false;
69 83
70 if (dd->current_alg->len == dd->d) { 84 if (dd->current_alg->len == dd->d) {
71 if (s->is_valid(dd->current_alg) || opts->all) 85 if (s->is_valid(dd->current_alg) || opts->all) {
72 append_alg(dd->sols, dd->current_alg); 86 pthread_mutex_lock(dd->sols_mutex);
87 if (dd->sols->len < opts->max_solutions)
88 append_alg(dd->sols, dd->current_alg);
89 pthread_mutex_unlock(dd->sols_mutex);
90 }
73 91
74 if (opts->verbose) 92 if (opts->verbose)
75 print_alg(dd->current_alg, false); 93 print_alg(dd->current_alg, false);
@@ -103,14 +121,13 @@ dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
103static bool 121static bool
104dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd) 122dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
105{ 123{
124 bool b = false;
125
106 CubeTarget ct = { 126 CubeTarget ct = {
107 .cube = c, 127 .cube = c,
108 .target = dd->d - dd->current_alg->len 128 .target = dd->d - dd->current_alg->len
109 }; 129 };
110 130
111 if (dd->sols->len >= opts->max_solutions)
112 return true;
113
114 dd->lb = s->estimate(ct); 131 dd->lb = s->estimate(ct);
115 if (opts->can_niss && !dd->niss) 132 if (opts->can_niss && !dd->niss)
116 dd->lb = MIN(1, dd->lb); 133 dd->lb = MIN(1, dd->lb);
@@ -118,7 +135,131 @@ dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
118 if (dd->current_alg->len + dd->lb > dd->d) 135 if (dd->current_alg->len + dd->lb > dd->d)
119 return true; 136 return true;
120 137
121 return false; 138 pthread_mutex_lock(dd->sols_mutex);
139 b = dd->sols->len >= opts->max_solutions;
140 pthread_mutex_unlock(dd->sols_mutex);
141
142 return b;
143}
144
145static void *
146instance_thread(void *arg)
147{
148 bool b;
149 Cube c;
150 ThreadData *td;
151 AlgListNode *node;
152 DfsData dd;
153
154 td = (ThreadData *)arg;
155
156 while (1) {
157 b = false;
158
159 pthread_mutex_lock(td->start_mutex);
160 if ((node = *(td->node)) == NULL)
161 b = true;
162 else
163 *(td->node) = (*(td->node))->next;
164 pthread_mutex_unlock(td->start_mutex);
165
166 if (b)
167 break;
168
169 c = node->alg->inv[0] ?
170 apply_move(node->alg->move[0], inverse_cube(td->cube)) :
171 apply_move(node->alg->move[0], td->cube);
172
173 dd.d = td->depth;
174 dd.m = 1;
175 dd.niss = node->alg->inv[0];
176 dd.lb = -1;
177 dd.last1 = node->alg->move[0];
178 dd.last2 = NULLMOVE;
179 dd.sols = td->sols;
180 dd.sols_mutex = td->sols_mutex;
181 dd.current_alg = new_alg("");
182 append_move(dd.current_alg, node->alg->move[0],
183 node->alg->inv[0]);
184 dd.sorted_moves = td->sorted_moves;
185 dd.move_position = td->move_position;
186
187/*
188 pthread_mutex_lock(td->sols_mutex);
189 printf("Starting thread %d with move: ", td->thid);
190 print_alg(dd.current_alg, false);
191 pthread_mutex_unlock(td->sols_mutex);
192*/
193
194 dfs(c, td->step, td->opts, &dd);
195
196 free_alg(dd.current_alg);
197 }
198
199 return NULL;
200}
201
202static void
203multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d)
204{
205 int i, *move_position;
206 Move *sorted_moves;
207 Alg *alg;
208 AlgList *start;
209 AlgListNode **node;
210 pthread_t t[opts->nthreads];
211 ThreadData td[opts->nthreads];
212 pthread_mutex_t *start_mutex, *sols_mutex;
213
214 move_position = malloc(NMOVES * sizeof(int));
215 sorted_moves = malloc(NMOVES * sizeof(Move));
216 node = malloc(sizeof(AlgListNode *));
217 start_mutex = malloc(sizeof(pthread_mutex_t));
218 sols_mutex = malloc(sizeof(pthread_mutex_t));
219
220 start = new_alglist();
221 pthread_mutex_init(start_mutex, NULL);
222 pthread_mutex_init(sols_mutex, NULL);
223
224 moveset_to_list(s->moveset, sorted_moves);
225 movelist_to_position(sorted_moves, move_position);
226 for (i = 0; sorted_moves[i] != NULLMOVE; i++) {
227 alg = new_alg("");
228 append_move(alg, sorted_moves[i], false);
229 append_alg(start, alg);
230 if (opts->can_niss) {
231 alg->inv[0] = true;
232 append_alg(start, alg);
233 }
234 free_alg(alg);
235 }
236 *node = start->first;
237
238 for (i = 0; i < opts->nthreads; i++) {
239 td[i].thid = i;
240 td[i].cube = c;
241 td[i].step = s;
242 td[i].depth = d;
243 td[i].sorted_moves = sorted_moves;
244 td[i].move_position = move_position;
245 td[i].opts = opts;
246 td[i].start = start;
247 td[i].node = node;
248 td[i].sols = sols;
249 td[i].start_mutex = start_mutex;
250 td[i].sols_mutex = sols_mutex;
251 pthread_create(&t[i], NULL, instance_thread, &td[i]);
252 }
253
254 for (i = 0; i < opts->nthreads; i++)
255 pthread_join(t[i], NULL);
256
257 free_alglist(start);
258 free(node);
259 free(start_mutex);
260 free(sols_mutex);
261 free(move_position);
262 free(sorted_moves);
122} 263}
123 264
124/* Public functions **********************************************************/ 265/* Public functions **********************************************************/
@@ -126,11 +267,12 @@ dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
126AlgList * 267AlgList *
127solve(Cube cube, Step *step, SolveOptions *opts) 268solve(Cube cube, Step *step, SolveOptions *opts)
128{ 269{
270 int d;
271 AlgList *sols = new_alglist();
129 AlgListNode *node; 272 AlgListNode *node;
130 DfsData dd;
131 Cube c; 273 Cube c;
132 274
133 prepare_step(step, &dd); 275 prepare_step(step);
134 276
135 if (step->detect != NULL) 277 if (step->detect != NULL)
136 step->pre_trans = step->detect(cube); 278 step->pre_trans = step->detect(cube);
@@ -139,24 +281,29 @@ solve(Cube cube, Step *step, SolveOptions *opts)
139 if (step->ready != NULL && !step->ready(c)) { 281 if (step->ready != NULL && !step->ready(c)) {
140 fprintf(stderr, "Cube not ready for solving step: "); 282 fprintf(stderr, "Cube not ready for solving step: ");
141 fprintf(stderr, "%s\n", step->ready_msg); 283 fprintf(stderr, "%s\n", step->ready_msg);
142 return dd.sols; 284 return sols;
285 }
286
287 if (step->estimate((CubeTarget){.cube = c, .target = 0}) == 0 &&
288 opts->min_moves == 0) {
289 append_alg(sols, new_alg(""));
290 return sols;
143 } 291 }
144 292
145 for (dd.d = opts->min_moves; 293 for (d = MAX(1, opts->min_moves);
146 dd.d <= opts->max_moves && 294 d <= opts->max_moves &&
147 !(dd.sols->len && opts->optimal_only) && 295 !(sols->len && opts->optimal_only) &&
148 dd.sols->len < opts->max_solutions; 296 sols->len < opts->max_solutions;
149 dd.d++) { 297 d++) {
150 if (opts->verbose) 298 if (opts->verbose)
151 fprintf(stderr, 299 fprintf(stderr,
152 "Found %d solutions, searching depth %d...\n", 300 "Found %d solutions, searching depth %d...\n",
153 dd.sols->len, dd.d); 301 sols->len, d);
154 dfs(c, step, opts, &dd); 302 multidfs(c, step, opts, sols, d);
155 } 303 }
156 304
157 for (node = dd.sols->first; node != NULL; node = node->next) 305 for (node = sols->first; node != NULL; node = node->next)
158 transform_alg(inverse_trans(step->pre_trans), node->alg); 306 transform_alg(inverse_trans(step->pre_trans), node->alg);
159 307
160 free_alg(dd.current_alg); 308 return sols;
161 return dd.sols;
162} 309}
diff --git a/src/steps.c b/src/steps.c
index 012e4cd..34ddcc2 100644
--- a/src/steps.c
+++ b/src/steps.c
@@ -1063,21 +1063,10 @@ detect_pretrans_drud(Cube cube)
1063/* Public functions **********************************************************/ 1063/* Public functions **********************************************************/
1064 1064
1065void 1065void
1066prepare_step(Step *step, DfsData *dd) 1066prepare_step(Step *step)
1067{ 1067{
1068 int i; 1068 int i;
1069 1069
1070 dd->m = 0;
1071 dd->niss = false;
1072 dd->lb = -1;
1073 dd->last1 = NULLMOVE;
1074 dd->last2 = NULLMOVE;
1075 dd->sols = new_alglist();
1076 dd->current_alg = new_alg("");
1077
1078 moveset_to_list(step->moveset, dd->sorted_moves);
1079 movelist_to_position(dd->sorted_moves, dd->move_position);
1080
1081 for (i = 0; i < step->ntables; i++) 1070 for (i = 0; i < step->ntables; i++)
1082 genptable(step->tables[i]); 1071 genptable(step->tables[i]);
1083} 1072}
diff --git a/src/steps.h b/src/steps.h
index 89ab168..4aedcee 100644
--- a/src/steps.h
+++ b/src/steps.h
@@ -7,6 +7,6 @@
7 7
8extern Step * steps[NSTEPS]; 8extern Step * steps[NSTEPS];
9 9
10void prepare_step(Step *step, DfsData *dd); 10void prepare_step(Step *step);
11 11
12#endif 12#endif

Generated with cgit - Back to sebastiano.tronto.net