aboutsummaryrefslogtreecommitdiff
path: root/src/commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands.c')
-rw-r--r--src/commands.c356
1 files changed, 270 insertions, 86 deletions
diff --git a/src/commands.c b/src/commands.c
index a9e8fc9..4d3ad50 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -1,11 +1,187 @@
1#define COMMANDS_C
2
3#include "commands.h" 1#include "commands.h"
4 2
5static bool read_cs(CommandArgs *args, char *str); 3/* Arg parsing functions *****************************************************/
4
5CommandArgs * gen_parse_args(int c, char **v);
6CommandArgs * help_parse_args(int c, char **v);
7CommandArgs * parse_only_scramble(int c, char **v);
8CommandArgs * parse_no_arg(int c, char **v);
9CommandArgs * solve_parse_args(int c, char **v);
10CommandArgs * scramble_parse_args(int c, char **v);
11
12/* Exec functions ************************************************************/
13
14static void gen_exec(CommandArgs *args);
15static void cleanup_exec(CommandArgs *args);
16static void invert_exec(CommandArgs *args);
17static void solve_exec(CommandArgs *args);
18static void scramble_exec(CommandArgs *args);
19static void steps_exec(CommandArgs *args);
20static void commands_exec(CommandArgs *args);
21static void freemem_exec(CommandArgs *args);
22static void print_exec(CommandArgs *args);
23static void twophase_exec(CommandArgs *args);
24static void help_exec(CommandArgs *args);
25static void quit_exec(CommandArgs *args);
26static void unniss_exec(CommandArgs *args);
27static void version_exec(CommandArgs *args);
28
29/* Local functions ***********************************************************/
30
31static bool read_step(CommandArgs *args, char *str);
6static bool read_scrtype(CommandArgs *args, char *str); 32static bool read_scrtype(CommandArgs *args, char *str);
7static bool read_scramble(int c, char **v, CommandArgs *args); 33static bool read_scramble(int c, char **v, CommandArgs *args);
8 34
35/* Commands ******************************************************************/
36
37Command
38solve_cmd = {
39 .name = "solve",
40 .usage = "solve STEP [OPTIONS] SCRAMBLE",
41 .description = "Solve a step; see command steps for a list of steps",
42 .parse_args = solve_parse_args,
43 .exec = solve_exec
44};
45
46Command
47scramble_cmd = {
48 .name = "scramble",
49 .usage = "scramble [TYPE] [-n N]",
50 .description = "Get a random-position scramble",
51 .parse_args = scramble_parse_args,
52 .exec = scramble_exec,
53};
54
55Command
56gen_cmd = {
57 .name = "gen",
58 .usage = "gen [-t N]",
59 .description = "Generate all tables [using N threads]",
60 .parse_args = gen_parse_args,
61 .exec = gen_exec
62};
63
64Command
65invert_cmd = {
66 .name = "invert",
67 .usage = "invert SCRAMBLE]",
68 .description = "Invert a scramble",
69 .parse_args = parse_only_scramble,
70 .exec = invert_exec,
71};
72
73Command
74steps_cmd = {
75 .name = "steps",
76 .usage = "steps",
77 .description = "List available steps",
78 .parse_args = parse_no_arg,
79 .exec = steps_exec
80};
81
82Command
83commands_cmd = {
84 .name = "commands",
85 .usage = "commands",
86 .description = "List available commands",
87 .parse_args = parse_no_arg,
88 .exec = commands_exec
89};
90
91Command
92freemem_cmd = {
93 .name = "freemem",
94 .usage = "freemem",
95 .description = "free large tables from RAM",
96 .parse_args = parse_no_arg,
97 .exec = freemem_exec,
98};
99
100Command
101print_cmd = {
102 .name = "print",
103 .usage = "print SCRAMBLE",
104 .description = "Print written description of the cube",
105 .parse_args = parse_only_scramble,
106 .exec = print_exec,
107};
108
109Command
110help_cmd = {
111 .name = "help",
112 .usage = "help [COMMAND]",
113 .description = "Display nissy manual page or help on specific command",
114 .parse_args = help_parse_args,
115 .exec = help_exec,
116};
117
118Command
119twophase_cmd = {
120 .name = "twophase",
121 .usage = "twophase",
122 .description = "Find a solution quickly using a 2-phase method",
123 .parse_args = parse_only_scramble,
124 .exec = twophase_exec,
125};
126
127Command
128quit_cmd = {
129 .name = "quit",
130 .usage = "quit",
131 .description = "Quit nissy",
132 .parse_args = parse_no_arg,
133 .exec = quit_exec,
134};
135
136Command
137cleanup_cmd = {
138 .name = "cleanup",
139 .usage = "cleanup SCRAMBLE",
140 .description = "Rewrite a scramble using only standard moves (HTM)",
141 .parse_args = parse_only_scramble,
142 .exec = cleanup_exec,
143};
144
145Command
146unniss_cmd = {
147 .name = "unniss",
148 .usage = "unniss SCRAMBLE",
149 .description = "Rewrite a scramble without NISS",
150 .parse_args = parse_only_scramble,
151 .exec = unniss_exec,
152};
153
154Command
155version_cmd = {
156 .name = "version",
157 .usage = "version",
158 .description = "print nissy version",
159 .parse_args = parse_no_arg,
160 .exec = version_exec,
161};
162
163Command *commands[] = {
164 &commands_cmd,
165 &freemem_cmd,
166 &gen_cmd,
167 &help_cmd,
168 &invert_cmd,
169 &print_cmd,
170 &quit_cmd,
171 &solve_cmd,
172 &scramble_cmd,
173 &steps_cmd,
174 &twophase_cmd,
175 &cleanup_cmd,
176 &unniss_cmd,
177 &version_cmd,
178 NULL
179};
180
181/* Other constants ***********************************************************/
182
183char *scrtypes[20] = { "eo", "corners", "edges", "fmc", "dr", "htr", NULL };
184
9/* Arg parsing functions implementation **************************************/ 185/* Arg parsing functions implementation **************************************/
10 186
11CommandArgs * 187CommandArgs *
@@ -95,7 +271,7 @@ solve_parse_args(int c, char **v)
95 a->opts->print_number = false; 271 a->opts->print_number = false;
96 } else if (!strcmp(v[i], "-c")) { 272 } else if (!strcmp(v[i], "-c")) {
97 a->opts->count_only = true; 273 a->opts->count_only = true;
98 } else if (!read_cs(a, v[i])) { 274 } else if (!read_step(a, v[i])) {
99 break; 275 break;
100 } 276 }
101 } 277 }
@@ -210,26 +386,17 @@ parse_no_arg(int c, char **v)
210 386
211/* Exec functions implementation *********************************************/ 387/* Exec functions implementation *********************************************/
212 388
213void 389static void
214solve_exec(CommandArgs *args) 390solve_exec(CommandArgs *args)
215{ 391{
216 Cube c; 392 Cube c;
217 AlgList *sols; 393 AlgList *sols;
218 Solver *solver[99];
219 Threader *threader;
220 394
221 make_solved(&c); 395 init_all_movesets();
222 apply_alg(args->scramble, &c); 396 init_symcoord();
223/* TODO: adjust */
224/* threader = &threader_single;*/
225 threader = &threader_eager;
226 397
227/* TODO: adjust */ 398 c = apply_alg(args->scramble, (Cube){0});
228 int i; 399 sols = solve(c, args->step, args->opts);
229 for (i = 0; args->cs->step[i] != NULL; i++)
230 solver[i] = new_stepsolver_lazy(args->cs->step[i]);
231 solver[i] = NULL;
232 sols = solve(&c, args->opts, solver, threader);
233 400
234 if (args->opts->count_only) 401 if (args->opts->count_only)
235 printf("%d\n", sols->len); 402 printf("%d\n", sols->len);
@@ -239,67 +406,85 @@ solve_exec(CommandArgs *args)
239 free_alglist(sols); 406 free_alglist(sols);
240} 407}
241 408
242void 409static void
243scramble_exec(CommandArgs *args) 410scramble_exec(CommandArgs *args)
244{ 411{
245 Cube cube; 412 Cube cube;
413 CubeArray *arr;
246 Alg *scr, *ruf, *aux; 414 Alg *scr, *ruf, *aux;
247 int i, j, eo, ep, co, cp; 415 int i, j, eo, ep, co, cp, a[12];
416 int eparr[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 };
248 uint64_t ui, uj, uk; 417 uint64_t ui, uj, uk;
249 418
419 init_all_movesets();
420 init_symcoord();
421
250 srand(time(NULL)); 422 srand(time(NULL));
251 423
252 for (i = 0; i < args->n; i++) { 424 for (i = 0; i < args->n; i++) {
253 425
254 if (!strcmp(args->scrtype, "dr")) { 426 if (!strcmp(args->scrtype, "dr")) {
255 ui = rand() % FACTORIAL8; 427 /* Warning: cube is inconsistent because of side CO *
256 uj = rand() % FACTORIAL8; 428 * and EO on U/D. But solve_2phase only solves drfin *
257 uk = rand() % FACTORIAL4; 429 * in this case, so it should be ok. *
430 * TODO: check this properly *
431 * Moreover we again need to fix parity after *
432 * generating epose manually */
433 do {
434 ui = rand() % FACTORIAL8;
435 uj = rand() % FACTORIAL8;
436 uk = rand() % FACTORIAL4;
437
438 index_to_perm(ui, 8, eparr);
439 arr = malloc(sizeof(CubeArray));
440 arr->ep = eparr;
441 cube = arrays_to_cube(arr, pf_ep);
442 free(arr);
258 443
259 make_solved(&cube); 444 cube.cp = uj;
260 index_to_perm(ui, 8, cube.cp); 445 cube.epose = uk;
261 index_to_perm(uj, 8, cube.ep); 446 } while (!is_admissible(cube));
262 index_to_perm(uk, 4, cube.ep + 8);
263 for (j = 8; j < 12; j++)
264 cube.ep[j] += 8;
265 } else if (!strcmp(args->scrtype, "htr")) { 447 } else if (!strcmp(args->scrtype, "htr")) {
266 make_solved(&cube); 448 /* antindex_htrfin() returns a consistent *
267 /* TODO */ 449 * cube, except possibly for parity */
450 do {
451 ui = rand() % (24*24/6);
452 cube = (Cube){0};
453 cube.cp = cornershtrfin_ant[ui];
454 cube.epose = rand() % 24;
455 cube.eposs = rand() % 24;
456 cube.eposm = rand() % 24;
457 } while (!is_admissible(cube));
268 } else { 458 } else {
269 ep = rand() % FACTORIAL12;
270 cp = rand() % FACTORIAL8;
271 eo = rand() % POW2TO11; 459 eo = rand() % POW2TO11;
460 ep = rand() % FACTORIAL12;
272 co = rand() % POW3TO7; 461 co = rand() % POW3TO7;
462 cp = rand() % FACTORIAL8;
273 463
274 if (!strcmp(args->scrtype, "eo")) { 464 if (!strcmp(args->scrtype, "eo")) {
275 eo = 0; 465 eo = 0;
276 } else if (!strcmp(args->scrtype, "corners")) { 466 } else if (!strcmp(args->scrtype, "corners")) {
277 eo = 0; 467 eo = 0;
278 ep = 0; 468 ep = 0;
469 index_to_perm(cp, 8, a);
470 if (perm_sign(a, 8) == 1) {
471 swap(&a[0], &a[1]);
472 cp = perm_to_index(a, 8);
473 }
279 } else if (!strcmp(args->scrtype, "edges")) { 474 } else if (!strcmp(args->scrtype, "edges")) {
280 co = 0; 475 co = 0;
281 cp = 0; 476 cp = 0;
477 index_to_perm(ep, 12, a);
478 if (perm_sign(a, 12) == 1) {
479 swap(&a[0], &a[1]);
480 ep = perm_to_index(a, 12);
481 }
282 } 482 }
283 483 cube = fourval_to_cube(eo, ep, co, cp);
284 make_solved(&cube);
285 index_to_perm(ep, 12, cube.ep);
286 index_to_perm(cp, 8, cube.cp);
287 int_to_sum_zero_array(eo, 2, 12, cube.eo);
288 int_to_sum_zero_array(co, 3, 8, cube.co);
289 }
290
291 if (!is_admissible(&cube)) {
292 if (!strcmp(args->scrtype, "corners"))
293 swap(&cube.cp[UFR], &cube.cp[UFL]);
294 else
295 swap(&cube.ep[UF], &cube.ep[UB]);
296 } 484 }
297 485
298 /* TODO: can be optimized for htr and dr using htrfin, drfin */ 486 /* TODO: can be optimized for htr and dr using htrfin, drfin */
299 /* 487 scr = solve_2phase(cube, 1);
300 TODO: solve_2phase was removed
301 scr = solve_2phase(&cube, 1);
302 */
303 488
304 if (!strcmp(args->scrtype, "fmc")) { 489 if (!strcmp(args->scrtype, "fmc")) {
305 aux = new_alg(""); 490 aux = new_alg("");
@@ -328,22 +513,23 @@ scramble_exec(CommandArgs *args)
328 } 513 }
329} 514}
330 515
331void 516static void
332gen_exec(CommandArgs *args) 517gen_exec(CommandArgs *args)
333{ 518{
334/* TODO:
335 int i; 519 int i;
336 520
337 fprintf(stderr, "Generating coordinates...\n"); 521 fprintf(stderr, "Generating coordinates...\n");
522 init_all_movesets();
523 init_symcoord();
524
338 fprintf(stderr, "Generating pruning tables...\n"); 525 fprintf(stderr, "Generating pruning tables...\n");
339 for (i = 0; all_pd[i] != NULL; i++) 526 for (i = 0; all_pd[i] != NULL; i++)
340 genptable(all_pd[i], args->opts->nthreads); 527 genptable(all_pd[i], args->opts->nthreads);
341*/
342 528
343 fprintf(stderr, "Done!\n"); 529 fprintf(stderr, "Done!\n");
344} 530}
345 531
346void 532static void
347invert_exec(CommandArgs *args) 533invert_exec(CommandArgs *args)
348{ 534{
349 Alg *inv; 535 Alg *inv;
@@ -354,16 +540,16 @@ invert_exec(CommandArgs *args)
354 free_alg(inv); 540 free_alg(inv);
355} 541}
356 542
357void 543static void
358steps_exec(CommandArgs *args) 544steps_exec(CommandArgs *args)
359{ 545{
360 int i; 546 int i;
361 547
362 for (i = 0; csteps[i] != NULL; i++) 548 for (i = 0; steps[i] != NULL; i++)
363 printf("%-15s %s\n", csteps[i]->shortname, csteps[i]->name); 549 printf("%-15s %s\n", steps[i]->shortname, steps[i]->name);
364} 550}
365 551
366void 552static void
367commands_exec(CommandArgs *args) 553commands_exec(CommandArgs *args)
368{ 554{
369 int i; 555 int i;
@@ -373,10 +559,9 @@ commands_exec(CommandArgs *args)
373 559
374} 560}
375 561
376void 562static void
377freemem_exec(CommandArgs *args) 563freemem_exec(CommandArgs *args)
378{ 564{
379/* TODO:
380 int i; 565 int i;
381 566
382 for (i = 0; all_pd[i] != NULL; i++) 567 for (i = 0; all_pd[i] != NULL; i++)
@@ -384,36 +569,35 @@ freemem_exec(CommandArgs *args)
384 569
385 for (i = 0; all_sd[i] != NULL; i++) 570 for (i = 0; all_sd[i] != NULL; i++)
386 free_sd(all_sd[i]); 571 free_sd(all_sd[i]);
387*/ 572
573 /* TODO: invtables are also large, but for now they are *
574 * statically allocated. Consider releasing those too. */
388} 575}
389 576
390void 577static void
391print_exec(CommandArgs *args) 578print_exec(CommandArgs *args)
392{ 579{
393 Cube c; 580 init_moves();
394 581 print_cube(apply_alg(args->scramble, (Cube){0}));
395 make_solved(&c);
396 apply_alg(args->scramble, &c);
397 print_cube(&c);
398} 582}
399 583
400/* 584static void
401void
402twophase_exec(CommandArgs *args) 585twophase_exec(CommandArgs *args)
403{ 586{
404 Cube c; 587 Cube c;
405 Alg *sol; 588 Alg *sol;
406 589
407 make_solved(&c); 590 init_all_movesets();
408 apply_alg(args->scramble, &c); 591 init_symcoord();
409 sol = solve_2phase(&c, 1); 592
593 c = apply_alg(args->scramble, (Cube){0});
594 sol = solve_2phase(c, 1);
410 595
411 print_alg(sol, false); 596 print_alg(sol, false);
412 free_alg(sol); 597 free_alg(sol);
413} 598}
414*/
415 599
416void 600static void
417help_exec(CommandArgs *args) 601help_exec(CommandArgs *args)
418{ 602{
419 if (args->command == NULL) { 603 if (args->command == NULL) {
@@ -427,7 +611,7 @@ help_exec(CommandArgs *args)
427 " system (such as Linux or MacOS) or in pdf and html" 611 " system (such as Linux or MacOS) or in pdf and html"
428 " format in the docs folder.\n" 612 " format in the docs folder.\n"
429 "Nissy is available for free at " 613 "Nissy is available for free at "
430 "https://nissy.tronto.net\n" 614 "https://github.com/sebastianotronto/nissy\n"
431 ); 615 );
432 } else { 616 } else {
433 printf("Command %s: %s\nusage: %s\n", args->command->name, 617 printf("Command %s: %s\nusage: %s\n", args->command->name,
@@ -435,24 +619,26 @@ help_exec(CommandArgs *args)
435 } 619 }
436} 620}
437 621
438void 622static void
439quit_exec(CommandArgs *args) 623quit_exec(CommandArgs *args)
440{ 624{
441 exit(0); 625 exit(0);
442} 626}
443 627
444void 628static void
445cleanup_exec(CommandArgs *args) 629cleanup_exec(CommandArgs *args)
446{ 630{
447 Alg *alg; 631 Alg *alg;
448 632
633 init_moves();
634
449 alg = cleanup(args->scramble); 635 alg = cleanup(args->scramble);
450 print_alg(alg, false); 636 print_alg(alg, false);
451 637
452 free_alg(alg); 638 free_alg(alg);
453} 639}
454 640
455void 641static void
456unniss_exec(CommandArgs *args) 642unniss_exec(CommandArgs *args)
457{ 643{
458 Alg *aux; 644 Alg *aux;
@@ -462,7 +648,7 @@ unniss_exec(CommandArgs *args)
462 free(aux); 648 free(aux);
463} 649}
464 650
465void 651static void
466version_exec(CommandArgs *args) 652version_exec(CommandArgs *args)
467{ 653{
468 printf(VERSION"\n"); 654 printf(VERSION"\n");
@@ -505,8 +691,6 @@ static bool
505read_scrtype(CommandArgs *args, char *str) 691read_scrtype(CommandArgs *args, char *str)
506{ 692{
507 int i; 693 int i;
508 static char *scrtypes[20] =
509 { "eo", "corners", "edges", "fmc", "dr", "htr", NULL };
510 694
511 for (i = 0; scrtypes[i] != NULL; i++) { 695 for (i = 0; scrtypes[i] != NULL; i++) {
512 if (!strcmp(scrtypes[i], str)) { 696 if (!strcmp(scrtypes[i], str)) {
@@ -519,13 +703,13 @@ read_scrtype(CommandArgs *args, char *str)
519} 703}
520 704
521static bool 705static bool
522read_cs(CommandArgs *args, char *str) 706read_step(CommandArgs *args, char *str)
523{ 707{
524 int i; 708 int i;
525 709
526 for (i = 0; csteps[i] != NULL; i++) { 710 for (i = 0; steps[i] != NULL; i++) {
527 if (!strcmp(csteps[i]->shortname, str)) { 711 if (!strcmp(steps[i]->shortname, str)) {
528 args->cs = csteps[i]; 712 args->step = steps[i];
529 return true; 713 return true;
530 } 714 }
531 } 715 }
@@ -562,7 +746,7 @@ new_args()
562 args->opts = malloc(sizeof(SolveOptions)); 746 args->opts = malloc(sizeof(SolveOptions));
563 747
564 /* step and command are static */ 748 /* step and command are static */
565 args->cs = csteps[0]; /* default: first step in list */ 749 args->step = steps[0]; /* default: first step in list */
566 args->command = NULL; 750 args->command = NULL;
567 751
568 return args; 752 return args;

Generated with cgit - Back to sebastiano.tronto.net