aboutsummaryrefslogtreecommitdiff
path: root/src/commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands.c')
-rw-r--r--src/commands.c322
1 files changed, 61 insertions, 261 deletions
diff --git a/src/commands.c b/src/commands.c
index a91fb4f..7f58ef5 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -1,187 +1,11 @@
1#include "commands.h" 1#define COMMANDS_C
2
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 2
14static void gen_exec(CommandArgs *args); 3#include "commands.h"
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 4
31static bool read_step(CommandArgs *args, char *str); 5static bool read_step(CommandArgs *args, char *str);
32static bool read_scrtype(CommandArgs *args, char *str); 6static bool read_scrtype(CommandArgs *args, char *str);
33static bool read_scramble(int c, char **v, CommandArgs *args); 7static bool read_scramble(int c, char **v, CommandArgs *args);
34 8
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
185/* Arg parsing functions implementation **************************************/ 9/* Arg parsing functions implementation **************************************/
186 10
187CommandArgs * 11CommandArgs *
@@ -386,17 +210,15 @@ parse_no_arg(int c, char **v)
386 210
387/* Exec functions implementation *********************************************/ 211/* Exec functions implementation *********************************************/
388 212
389static void 213void
390solve_exec(CommandArgs *args) 214solve_exec(CommandArgs *args)
391{ 215{
392 Cube c; 216 Cube c;
393 AlgList *sols; 217 AlgList *sols;
394 218
395 init_all_movesets(); 219 make_solved(&c);
396 init_symcoord(); 220 apply_alg(args->scramble, &c);
397 221 sols = solve(&c, args->step, args->opts);
398 c = apply_alg(args->scramble, (Cube){0});
399 sols = solve(c, args->step, args->opts);
400 222
401 if (args->opts->count_only) 223 if (args->opts->count_only)
402 printf("%d\n", sols->len); 224 printf("%d\n", sols->len);
@@ -406,85 +228,64 @@ solve_exec(CommandArgs *args)
406 free_alglist(sols); 228 free_alglist(sols);
407} 229}
408 230
409static void 231void
410scramble_exec(CommandArgs *args) 232scramble_exec(CommandArgs *args)
411{ 233{
412 Cube cube; 234 Cube cube;
413 CubeArray *arr;
414 Alg *scr, *ruf, *aux; 235 Alg *scr, *ruf, *aux;
415 int i, j, eo, ep, co, cp, a[12]; 236 int i, j, eo, ep, co, cp;
416 int eparr[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 };
417 uint64_t ui, uj, uk; 237 uint64_t ui, uj, uk;
418 238
419 init_all_movesets();
420 init_symcoord();
421
422 srand(time(NULL)); 239 srand(time(NULL));
423 240
424 for (i = 0; i < args->n; i++) { 241 for (i = 0; i < args->n; i++) {
425 242
426 if (!strcmp(args->scrtype, "dr")) { 243 if (!strcmp(args->scrtype, "dr")) {
427 /* Warning: cube is inconsistent because of side CO * 244 ui = rand() % FACTORIAL8;
428 * and EO on U/D. But solve_2phase only solves drfin * 245 uj = rand() % FACTORIAL8;
429 * in this case, so it should be ok. * 246 uk = rand() % FACTORIAL4;
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, 12, a);
439 arr = malloc(sizeof(CubeArray));
440 arr->ep = eparr;
441 cube = arrays_to_cube(arr, pf_ep);
442 free(arr);
443 247
444 cube.cp = uj; 248 make_solved(&cube);
445 cube.epose += uk; 249 index_to_perm(ui, 8, cube.cp);
446 } while (!is_admissible(cube)); 250 index_to_perm(uj, 8, cube.ep);
251 index_to_perm(uk, 4, cube.ep + 8);
252 for (j = 8; j < 12; j++)
253 cube.ep[j] += 8;
447 } else if (!strcmp(args->scrtype, "htr")) { 254 } else if (!strcmp(args->scrtype, "htr")) {
448 /* antindex_htrfin() returns a consistent * 255 make_solved(&cube);
449 * cube, except possibly for parity */ 256 /* TODO */
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));
458 } else { 257 } else {
459 eo = rand() % POW2TO11;
460 ep = rand() % FACTORIAL12; 258 ep = rand() % FACTORIAL12;
461 co = rand() % POW3TO7;
462 cp = rand() % FACTORIAL8; 259 cp = rand() % FACTORIAL8;
260 eo = rand() % POW2TO11;
261 co = rand() % POW3TO7;
463 262
464 if (!strcmp(args->scrtype, "eo")) { 263 if (!strcmp(args->scrtype, "eo")) {
465 eo = 0; 264 eo = 0;
466 } else if (!strcmp(args->scrtype, "corners")) { 265 } else if (!strcmp(args->scrtype, "corners")) {
467 eo = 0; 266 eo = 0;
468 ep = 0; 267 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 }
474 } else if (!strcmp(args->scrtype, "edges")) { 268 } else if (!strcmp(args->scrtype, "edges")) {
475 co = 0; 269 co = 0;
476 cp = 0; 270 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 }
482 } 271 }
483 cube = fourval_to_cube(eo, ep, co, cp); 272
273 make_solved(&cube);
274 index_to_perm(ep, 12, cube.ep);
275 index_to_perm(cp, 8, cube.cp);
276 int_to_sum_zero_array(eo, 2, 12, cube.eo);
277 int_to_sum_zero_array(co, 3, 8, cube.co);
278 }
279
280 if (!is_admissible(&cube)) {
281 if (!strcmp(args->scrtype, "corners"))
282 swap(&cube.cp[UFR], &cube.cp[UFL]);
283 else
284 swap(&cube.ep[UF], &cube.ep[UB]);
484 } 285 }
485 286
486 /* TODO: can be optimized for htr and dr using htrfin, drfin */ 287 /* TODO: can be optimized for htr and dr using htrfin, drfin */
487 scr = solve_2phase(cube, 1); 288 scr = solve_2phase(&cube, 1);
488 289
489 if (!strcmp(args->scrtype, "fmc")) { 290 if (!strcmp(args->scrtype, "fmc")) {
490 aux = new_alg(""); 291 aux = new_alg("");
@@ -513,23 +314,22 @@ scramble_exec(CommandArgs *args)
513 } 314 }
514} 315}
515 316
516static void 317void
517gen_exec(CommandArgs *args) 318gen_exec(CommandArgs *args)
518{ 319{
320/* TODO:
519 int i; 321 int i;
520 322
521 fprintf(stderr, "Generating coordinates...\n"); 323 fprintf(stderr, "Generating coordinates...\n");
522 init_all_movesets();
523 init_symcoord();
524
525 fprintf(stderr, "Generating pruning tables...\n"); 324 fprintf(stderr, "Generating pruning tables...\n");
526 for (i = 0; all_pd[i] != NULL; i++) 325 for (i = 0; all_pd[i] != NULL; i++)
527 genptable(all_pd[i], args->opts->nthreads); 326 genptable(all_pd[i], args->opts->nthreads);
327*/
528 328
529 fprintf(stderr, "Done!\n"); 329 fprintf(stderr, "Done!\n");
530} 330}
531 331
532static void 332void
533invert_exec(CommandArgs *args) 333invert_exec(CommandArgs *args)
534{ 334{
535 Alg *inv; 335 Alg *inv;
@@ -540,7 +340,7 @@ invert_exec(CommandArgs *args)
540 free_alg(inv); 340 free_alg(inv);
541} 341}
542 342
543static void 343void
544steps_exec(CommandArgs *args) 344steps_exec(CommandArgs *args)
545{ 345{
546 int i; 346 int i;
@@ -549,7 +349,7 @@ steps_exec(CommandArgs *args)
549 printf("%-15s %s\n", steps[i]->shortname, steps[i]->name); 349 printf("%-15s %s\n", steps[i]->shortname, steps[i]->name);
550} 350}
551 351
552static void 352void
553commands_exec(CommandArgs *args) 353commands_exec(CommandArgs *args)
554{ 354{
555 int i; 355 int i;
@@ -559,9 +359,10 @@ commands_exec(CommandArgs *args)
559 359
560} 360}
561 361
562static void 362void
563freemem_exec(CommandArgs *args) 363freemem_exec(CommandArgs *args)
564{ 364{
365/* TODO:
565 int i; 366 int i;
566 367
567 for (i = 0; all_pd[i] != NULL; i++) 368 for (i = 0; all_pd[i] != NULL; i++)
@@ -569,35 +370,34 @@ freemem_exec(CommandArgs *args)
569 370
570 for (i = 0; all_sd[i] != NULL; i++) 371 for (i = 0; all_sd[i] != NULL; i++)
571 free_sd(all_sd[i]); 372 free_sd(all_sd[i]);
572 373*/
573 /* TODO: invtables are also large, but for now they are *
574 * statically allocated. Consider releasing those too. */
575} 374}
576 375
577static void 376void
578print_exec(CommandArgs *args) 377print_exec(CommandArgs *args)
579{ 378{
580 init_moves(); 379 Cube c;
581 print_cube(apply_alg(args->scramble, (Cube){0})); 380
381 make_solved(&c);
382 apply_alg(args->scramble, &c);
383 print_cube(&c);
582} 384}
583 385
584static void 386void
585twophase_exec(CommandArgs *args) 387twophase_exec(CommandArgs *args)
586{ 388{
587 Cube c; 389 Cube c;
588 Alg *sol; 390 Alg *sol;
589 391
590 init_all_movesets(); 392 make_solved(&c);
591 init_symcoord(); 393 apply_alg(args->scramble, &c);
592 394 sol = solve_2phase(&c, 1);
593 c = apply_alg(args->scramble, (Cube){0});
594 sol = solve_2phase(c, 1);
595 395
596 print_alg(sol, false); 396 print_alg(sol, false);
597 free_alg(sol); 397 free_alg(sol);
598} 398}
599 399
600static void 400void
601help_exec(CommandArgs *args) 401help_exec(CommandArgs *args)
602{ 402{
603 if (args->command == NULL) { 403 if (args->command == NULL) {
@@ -619,26 +419,24 @@ help_exec(CommandArgs *args)
619 } 419 }
620} 420}
621 421
622static void 422void
623quit_exec(CommandArgs *args) 423quit_exec(CommandArgs *args)
624{ 424{
625 exit(0); 425 exit(0);
626} 426}
627 427
628static void 428void
629cleanup_exec(CommandArgs *args) 429cleanup_exec(CommandArgs *args)
630{ 430{
631 Alg *alg; 431 Alg *alg;
632 432
633 init_moves();
634
635 alg = cleanup(args->scramble); 433 alg = cleanup(args->scramble);
636 print_alg(alg, false); 434 print_alg(alg, false);
637 435
638 free_alg(alg); 436 free_alg(alg);
639} 437}
640 438
641static void 439void
642unniss_exec(CommandArgs *args) 440unniss_exec(CommandArgs *args)
643{ 441{
644 Alg *aux; 442 Alg *aux;
@@ -648,7 +446,7 @@ unniss_exec(CommandArgs *args)
648 free(aux); 446 free(aux);
649} 447}
650 448
651static void 449void
652version_exec(CommandArgs *args) 450version_exec(CommandArgs *args)
653{ 451{
654 printf(VERSION"\n"); 452 printf(VERSION"\n");
@@ -691,6 +489,8 @@ static bool
691read_scrtype(CommandArgs *args, char *str) 489read_scrtype(CommandArgs *args, char *str)
692{ 490{
693 int i; 491 int i;
492 static char *scrtypes[20] =
493 { "eo", "corners", "edges", "fmc", "dr", "htr", NULL };
694 494
695 for (i = 0; scrtypes[i] != NULL; i++) { 495 for (i = 0; scrtypes[i] != NULL; i++) {
696 if (!strcmp(scrtypes[i], str)) { 496 if (!strcmp(scrtypes[i], str)) {

Generated with cgit - Back to sebastiano.tronto.net