diff options
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | docs/co.txt | 39 | ||||
| -rwxr-xr-x | nissy | bin | 302560 -> 319784 bytes | |||
| -rw-r--r-- | src/helppages.h | 46 | ||||
| -rw-r--r-- | src/main.c | 211 | ||||
| -rw-r--r-- | src/solver.c | 96 | ||||
| -rw-r--r-- | src/solver.h | 2 |
7 files changed, 323 insertions, 73 deletions
| @@ -26,7 +26,7 @@ example, on a Linux system with GCC installed: | |||
| 26 | 26 | ||
| 27 | ``` | 27 | ``` |
| 28 | cd path/to/nissy | 28 | cd path/to/nissy |
| 29 | gcc -O3 -std=c99 -o nissy ./src/*.c | 29 | gcc -O2 -std=c99 -o nissy ./src/*.c |
| 30 | ./nissy | 30 | ./nissy |
| 31 | ``` | 31 | ``` |
| 32 | 32 | ||
diff --git a/docs/co.txt b/docs/co.txt new file mode 100644 index 0000000..27c0b43 --- /dev/null +++ b/docs/co.txt | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | |||
| 2 | HELP PAGE FOR COMMAND co | ||
| 3 | |||
| 4 | SYNTAX | ||
| 5 | co [OPTIONS] [MOVES|$ID|@ID] | ||
| 6 | |||
| 7 | DESCRIPTION | ||
| 8 | Solves CO for a given scramble. A scramble can be given as last argument of the | ||
| 9 | command, or an ID of a saved scramble can be provided. If none of the two is | ||
| 10 | given, a prompt will ask the user to input a new scramble. | ||
| 11 | |||
| 12 | OPTIONS | ||
| 13 | axis={fb,rl,ud} Specify the axis for the CO. One to three axes can be given, | ||
| 14 | comma separated, no spaces. | ||
| 15 | Default: CO on any of the three axis (omitting the option is | ||
| 16 | the same as specifying axis=fb,rl,ud). | ||
| 17 | b=N Specify a bound for the number of moves. N must be a number. | ||
| 18 | Default value: 20. | ||
| 19 | h Show hidden COs. | ||
| 20 | Default, if an CO ending in e.g. F is shown, the equivalent | ||
| 21 | one ending in F' is hidden. | ||
| 22 | i Ignore centers. By default the CO is aligned with centers. | ||
| 23 | niss Use NISS. | ||
| 24 | Default: does not use NISS. | ||
| 25 | n=N Specify a maximum number of COs to be output. N must be a | ||
| 26 | number. | ||
| 27 | Default value: 1. | ||
| 28 | |||
| 29 | EXAMPLES | ||
| 30 | co axis=fb $1 | ||
| 31 | Finds one optimal CO on fb for the first saved scramble. | ||
| 32 | |||
| 33 | co n=5 b=4 U R F | ||
| 34 | Finds up to 5 COs of length at most 4 for scramble U R F. | ||
| 35 | |||
| 36 | co n=100 b=5 niss axis=fb,ud h R' U' F L R'U'F | ||
| 37 | Finds up to 100 COs of lenth at most 4, possibly using NISS, including | ||
| 38 | "hidden" COs, excluding the rl axis. | ||
| 39 | |||
| Binary files differ | |||
diff --git a/src/helppages.h b/src/helppages.h index 5ee0e4a..178de37 100644 --- a/src/helppages.h +++ b/src/helppages.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* To generate this help page, use the script makedoc.sh */ | 1 | /* To generate this help page, use the script makedoc.sh */ |
| 2 | 2 | ||
| 3 | int Npages = 21; | 3 | int Npages = 22; |
| 4 | 4 | ||
| 5 | char *helppages[][10] = { | 5 | char *helppages[][10] = { |
| 6 | 6 | ||
| @@ -67,6 +67,50 @@ Resets all saved scrambles and output sequences.\n\ | |||
| 67 | " | 67 | " |
| 68 | }, | 68 | }, |
| 69 | 69 | ||
| 70 | { "co", | ||
| 71 | "\ | ||
| 72 | \n\ | ||
| 73 | HELP PAGE FOR COMMAND co\n\ | ||
| 74 | \n\ | ||
| 75 | SYNTAX\n\ | ||
| 76 | co [OPTIONS] [MOVES|$ID|@ID]\n\ | ||
| 77 | \n\ | ||
| 78 | DESCRIPTION\n\ | ||
| 79 | Solves CO for a given scramble. A scramble can be given as last argument of the\n\ | ||
| 80 | command, or an ID of a saved scramble can be provided. If none of the two is\n\ | ||
| 81 | given, a prompt will ask the user to input a new scramble.\n\ | ||
| 82 | \n\ | ||
| 83 | OPTIONS\n\ | ||
| 84 | axis={fb,rl,ud} Specify the axis for the CO. One to three axes can be given,\n\ | ||
| 85 | comma separated, no spaces.\n\ | ||
| 86 | Default: CO on any of the three axis (omitting the option is\n\ | ||
| 87 | the same as specifying axis=fb,rl,ud).\n\ | ||
| 88 | b=N Specify a bound for the number of moves. N must be a number.\n\ | ||
| 89 | Default value: 20.\n\ | ||
| 90 | h Show hidden COs.\n\ | ||
| 91 | Default, if an CO ending in e.g. F is shown, the equivalent\n\ | ||
| 92 | one ending in F' is hidden.\n\ | ||
| 93 | i Ignore centers. By default the CO is aligned with centers.\n\ | ||
| 94 | niss Use NISS.\n\ | ||
| 95 | Default: does not use NISS.\n\ | ||
| 96 | n=N Specify a maximum number of COs to be output. N must be a\n\ | ||
| 97 | number.\n\ | ||
| 98 | Default value: 1.\n\ | ||
| 99 | \n\ | ||
| 100 | EXAMPLES\n\ | ||
| 101 | co axis=fb $1\n\ | ||
| 102 | Finds one optimal CO on fb for the first saved scramble.\n\ | ||
| 103 | \n\ | ||
| 104 | co n=5 b=4 U R F \n\ | ||
| 105 | Finds up to 5 COs of length at most 4 for scramble U R F.\n\ | ||
| 106 | \n\ | ||
| 107 | co n=100 b=5 niss axis=fb,ud h R' U' F L R'U'F\n\ | ||
| 108 | Finds up to 100 COs of lenth at most 4, possibly using NISS, including\n\ | ||
| 109 | \"hidden\" COs, excluding the rl axis.\n\ | ||
| 110 | \n\ | ||
| 111 | " | ||
| 112 | }, | ||
| 113 | |||
| 70 | { "dr", | 114 | { "dr", |
| 71 | "\ | 115 | "\ |
| 72 | \n\ | 116 | \n\ |
| @@ -8,51 +8,6 @@ | |||
| 8 | #include "solver.h" | 8 | #include "solver.h" |
| 9 | #include "string.h" | 9 | #include "string.h" |
| 10 | #include "helppages.h" | 10 | #include "helppages.h" |
| 11 | |||
| 12 | char *commands[][10] = { | ||
| 13 | {"help", "[COMMAND]", | ||
| 14 | "Print this help, or a help page for COMMAND."}, | ||
| 15 | {"scramble", "[OPTIONS]", | ||
| 16 | "Prints a random-state scramble."}, | ||
| 17 | {"save", "[MOVES|@ID|$ID]", | ||
| 18 | "Save or copy a scramble."}, | ||
| 19 | {"change", "$ID1 [MOVES|$ID2|@ID2]", | ||
| 20 | "Change a memorized scramble."}, | ||
| 21 | {"print", "[$ID|@ID]", | ||
| 22 | "Print memorized sequences."}, | ||
| 23 | {"add", "[MOVES|$ID1|@ID1] $ID2", | ||
| 24 | "Add moves at the end of a memorized scramble."}, | ||
| 25 | {"invert", "[MOVES|$ID|@ID]", | ||
| 26 | "Inverts the given sequence of moves."}, | ||
| 27 | {"unniss", "[MOVES|$ID|@ID]}", | ||
| 28 | "Removes NISS: A (B) -> B\' A."}, | ||
| 29 | {"pic", "[MOVES|$ID|@ID]", | ||
| 30 | "Show a text description of the scrambled cube."}, | ||
| 31 | {"solve", "[MOVES|$ID|@ID]", | ||
| 32 | "Solves a scramble."}, | ||
| 33 | {"replace", "[MOVES|$ID|@ID]", | ||
| 34 | "Find non-optimal subsequences."}, | ||
| 35 | {"clear", "", | ||
| 36 | "Delete saved scrambles and output sequences."}, | ||
| 37 | {"eo", "[MOVES|$ID|@ID]", | ||
| 38 | "Solves EO."}, | ||
| 39 | {"dr", "[MOVES|$ID|@ID]", | ||
| 40 | "Solves DR, either directly or from eo."}, | ||
| 41 | {"htr", "[MOVES|$ID|@ID]", | ||
| 42 | "Solves HTR from DR."}, | ||
| 43 | {"drfinish", "[MOVES|$ID|@ID]", | ||
| 44 | "Solves the cube after DR."}, | ||
| 45 | {"htrfinish", "[MOVES|$ID|@ID]", | ||
| 46 | "Solves the cube using only half turns."}, | ||
| 47 | {"drcorners", "[MOVES|$ID|@ID]", | ||
| 48 | "Solves corners after DR."}, | ||
| 49 | {"exit", "", | ||
| 50 | "Exit nissy."}, | ||
| 51 | {"quit", "", | ||
| 52 | "Exit nissy."}, | ||
| 53 | {"", "", ""} | ||
| 54 | }; | ||
| 55 | |||
| 56 | /* Saved sequences of moves */ | 11 | /* Saved sequences of moves */ |
| 57 | int scr_count=1, tmp_count=1, max_tmp=999; | 12 | int scr_count=1, tmp_count=1, max_tmp=999; |
| 58 | int scrambles[255][255], tmp[1000][255]; | 13 | int scrambles[255][255], tmp[1000][255]; |
| @@ -122,28 +77,6 @@ int parsecmd(char *cmd, char cmdtok[][100]) { | |||
| 122 | return n; | 77 | return n; |
| 123 | } | 78 | } |
| 124 | 79 | ||
| 125 | void help_cmd(int n, char cmdtok[][100]) { | ||
| 126 | if (n == 1) { | ||
| 127 | printf("\n"); | ||
| 128 | for (int i = 0; commands[i][0][0]; i++) | ||
| 129 | printf("%-10s%-25s%s\n", commands[i][0], commands[i][1], commands[i][2]); | ||
| 130 | printf("\n"); | ||
| 131 | printf("Type \'help\' followed by a command for a detailed help page.\n"); | ||
| 132 | printf("Type \'help nissy\' for a general user guide.\n"); | ||
| 133 | } else if (n == 2) { | ||
| 134 | for (int i = 0; i < Npages; i++) { | ||
| 135 | if (!strcmp(helppages[i][0], cmdtok[1])) { | ||
| 136 | printf("%s", helppages[i][1]); | ||
| 137 | return; | ||
| 138 | } | ||
| 139 | } | ||
| 140 | printf("No help page for %s.\n", cmdtok[1]); | ||
| 141 | return; | ||
| 142 | } else { | ||
| 143 | printf("help: wrong syntax.\n"); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | void scramble_cmd(int n, char cmdtok[][100]) { | 80 | void scramble_cmd(int n, char cmdtok[][100]) { |
| 148 | int c = 0, e = 0, dr = 0; | 81 | int c = 0, e = 0, dr = 0; |
| 149 | 82 | ||
| @@ -528,6 +461,69 @@ void eo_cmd(int n, char cmdtok[][100]) { | |||
| 528 | print_results(neo, eo_list); | 461 | print_results(neo, eo_list); |
| 529 | } | 462 | } |
| 530 | 463 | ||
| 464 | void co_cmd(int n, char cmdtok[][100]) { | ||
| 465 | |||
| 466 | /* Default values */ | ||
| 467 | int m = 1, b = 20, ignore = 0; | ||
| 468 | int niss = 0, hide = 1; | ||
| 469 | int fb = 1, rl = 1, ud = 1; | ||
| 470 | int scram[255] = {[0] = 0}; | ||
| 471 | int scram_unnissed[255]; | ||
| 472 | |||
| 473 | /* Parse options */ | ||
| 474 | for (int i = 1; i < n && scram[0] == 0; i++) { | ||
| 475 | if (!strcmp(cmdtok[i], "h")) { | ||
| 476 | hide = 0; | ||
| 477 | } else if (!strcmp(cmdtok[i], "niss")) { | ||
| 478 | niss = 1; | ||
| 479 | } else if (!strcmp(cmdtok[i], "i")) { | ||
| 480 | ignore = 1; | ||
| 481 | } else if (!strncmp(cmdtok[i], "axis=", 5)) { | ||
| 482 | fb = rl = ud = 0; | ||
| 483 | if (strstr(cmdtok[i], "fb") != NULL) | ||
| 484 | fb = 1; | ||
| 485 | if (strstr(cmdtok[i], "rl") != NULL) | ||
| 486 | rl = 1; | ||
| 487 | if (strstr(cmdtok[i], "ud") != NULL) | ||
| 488 | ud = 1; | ||
| 489 | if (fb + rl + ud == 0) { | ||
| 490 | printf("co: bad axis option.\n"); | ||
| 491 | return; | ||
| 492 | } | ||
| 493 | } else if (!strncmp(cmdtok[i], "n=", 2)) { | ||
| 494 | m = atoi(cmdtok[i]+2); | ||
| 495 | if (m <= 0) { | ||
| 496 | printf("co: bad option n.\n"); | ||
| 497 | return; | ||
| 498 | } | ||
| 499 | } else if (!strncmp(cmdtok[i], "b=", 2)) { | ||
| 500 | b = atoi(cmdtok[i]+2); | ||
| 501 | if (b <= 0) { | ||
| 502 | printf("co: bad option b.\n"); | ||
| 503 | return; | ||
| 504 | } | ||
| 505 | } else if (read_moves_from_argument(n-i, cmdtok+i, scram) == -1) { | ||
| 506 | printf("co: error reading moves or ID.\n"); | ||
| 507 | return; | ||
| 508 | } | ||
| 509 | } | ||
| 510 | |||
| 511 | if (scram[0] == 0) { | ||
| 512 | if (read_moves_from_prompt(scram) == -1) { | ||
| 513 | printf("co: error reading moves.\n"); | ||
| 514 | return; | ||
| 515 | } | ||
| 516 | } | ||
| 517 | |||
| 518 | unniss(scram, scram_unnissed); | ||
| 519 | |||
| 520 | /* Call solver and print results */ | ||
| 521 | int co_list[m+5][30]; | ||
| 522 | int nco = co_scram_spam(scram_unnissed, co_list, fb, rl, ud, m, b, niss, | ||
| 523 | hide, ignore); | ||
| 524 | print_results(nco, co_list); | ||
| 525 | } | ||
| 526 | |||
| 531 | void dr_cmd(int n, char cmdtok[][100]) { | 527 | void dr_cmd(int n, char cmdtok[][100]) { |
| 532 | 528 | ||
| 533 | /* Default values */ | 529 | /* Default values */ |
| @@ -763,7 +759,7 @@ void htrfinish_cmd(int n, char cmdtok[][100]) { | |||
| 763 | 759 | ||
| 764 | void drcorners_cmd(int n, char cmdtok[][100]) { | 760 | void drcorners_cmd(int n, char cmdtok[][100]) { |
| 765 | /* Default values */ | 761 | /* Default values */ |
| 766 | int m = 1, b = 20, ignore=0; | 762 | int m = 1, b = 20, ignore = 0; |
| 767 | int from = 0; /* 0: unspecified; {1,2,3}: from {ud,fb,rl} */ | 763 | int from = 0; /* 0: unspecified; {1,2,3}: from {ud,fb,rl} */ |
| 768 | int scram[255] = {[0] = 0}; | 764 | int scram[255] = {[0] = 0}; |
| 769 | int scram_unnissed[255]; | 765 | int scram_unnissed[255]; |
| @@ -823,15 +819,89 @@ void exit_quit_cmd(int n, char cmdtok[][100]) { | |||
| 823 | printf("%s: wrong synstax.\n", cmdtok[0]); | 819 | printf("%s: wrong synstax.\n", cmdtok[0]); |
| 824 | } | 820 | } |
| 825 | 821 | ||
| 822 | /***************************************************************/ | ||
| 823 | /* List of all commands */ | ||
| 824 | /* Important: they must be in the same order in the two arrays */ | ||
| 825 | /***************************************************************/ | ||
| 826 | |||
| 827 | char *commands[][10] = { | ||
| 828 | {"help", "[COMMAND]", | ||
| 829 | "Print this help, or a help page for COMMAND."}, | ||
| 830 | {"scramble", "[OPTIONS]", | ||
| 831 | "Prints a random-state scramble."}, | ||
| 832 | {"save", "[MOVES|@ID|$ID]", | ||
| 833 | "Save or copy a scramble."}, | ||
| 834 | {"change", "$ID1 [MOVES|$ID2|@ID2]", | ||
| 835 | "Change a memorized scramble."}, | ||
| 836 | {"print", "[$ID|@ID]", | ||
| 837 | "Print memorized sequences."}, | ||
| 838 | {"add", "[MOVES|$ID1|@ID1] $ID2", | ||
| 839 | "Add moves at the end of a memorized scramble."}, | ||
| 840 | {"invert", "[MOVES|$ID|@ID]", | ||
| 841 | "Inverts the given sequence of moves."}, | ||
| 842 | {"unniss", "[MOVES|$ID|@ID]}", | ||
| 843 | "Removes NISS: A (B) -> B\' A."}, | ||
| 844 | {"pic", "[MOVES|$ID|@ID]", | ||
| 845 | "Show a text description of the scrambled cube."}, | ||
| 846 | {"solve", "[MOVES|$ID|@ID]", | ||
| 847 | "Solves a scramble."}, | ||
| 848 | {"replace", "[MOVES|$ID|@ID]", | ||
| 849 | "Find non-optimal subsequences."}, | ||
| 850 | {"clear", "", | ||
| 851 | "Delete saved scrambles and output sequences."}, | ||
| 852 | {"eo", "[MOVES|$ID|@ID]", | ||
| 853 | "Solves EO."}, | ||
| 854 | {"co", "[MOVES|$ID|@ID]", | ||
| 855 | "Solves CO."}, | ||
| 856 | {"dr", "[MOVES|$ID|@ID]", | ||
| 857 | "Solves DR, either directly or from eo."}, | ||
| 858 | {"htr", "[MOVES|$ID|@ID]", | ||
| 859 | "Solves HTR from DR."}, | ||
| 860 | {"drfinish", "[MOVES|$ID|@ID]", | ||
| 861 | "Solves the cube after DR."}, | ||
| 862 | {"htrfinish", "[MOVES|$ID|@ID]", | ||
| 863 | "Solves the cube using only half turns."}, | ||
| 864 | {"drcorners", "[MOVES|$ID|@ID]", | ||
| 865 | "Solves corners after DR."}, | ||
| 866 | {"exit", "", | ||
| 867 | "Exit nissy."}, | ||
| 868 | {"quit", "", | ||
| 869 | "Exit nissy."}, | ||
| 870 | {"", "", ""} | ||
| 871 | }; | ||
| 872 | |||
| 873 | void help_cmd(int n, char cmdtok[][100]) { | ||
| 874 | if (n == 1) { | ||
| 875 | printf("\n"); | ||
| 876 | for (int i = 0; commands[i][0][0]; i++) | ||
| 877 | printf("%-10s%-25s%s\n", commands[i][0], commands[i][1], commands[i][2]); | ||
| 878 | printf("\n"); | ||
| 879 | printf("Type \'help\' followed by a command for a detailed help page.\n"); | ||
| 880 | printf("Type \'help nissy\' for a general user guide.\n"); | ||
| 881 | } else if (n == 2) { | ||
| 882 | for (int i = 0; i < Npages; i++) { | ||
| 883 | if (!strcmp(helppages[i][0], cmdtok[1])) { | ||
| 884 | printf("%s", helppages[i][1]); | ||
| 885 | return; | ||
| 886 | } | ||
| 887 | } | ||
| 888 | printf("No help page for %s.\n", cmdtok[1]); | ||
| 889 | return; | ||
| 890 | } else { | ||
| 891 | printf("help: wrong syntax.\n"); | ||
| 892 | } | ||
| 893 | } | ||
| 894 | |||
| 826 | void (*cmd_list[])(int n, char cmdtok[][100]) = { | 895 | void (*cmd_list[])(int n, char cmdtok[][100]) = { |
| 827 | help_cmd, scramble_cmd, save_cmd, change_cmd, print_cmd, | 896 | help_cmd, scramble_cmd, save_cmd, change_cmd, print_cmd, |
| 828 | add_cmd, invert_cmd, unniss_cmd, pic_cmd, | 897 | add_cmd, invert_cmd, unniss_cmd, pic_cmd, |
| 829 | solve_cmd, replace_cmd, clear_cmd, | 898 | solve_cmd, replace_cmd, clear_cmd, |
| 830 | eo_cmd, dr_cmd, htr_cmd, | 899 | eo_cmd, co_cmd, dr_cmd, htr_cmd, |
| 831 | drfinish_cmd, htrfinish_cmd, drcorners_cmd, | 900 | drfinish_cmd, htrfinish_cmd, drcorners_cmd, |
| 832 | exit_quit_cmd, exit_quit_cmd, NULL | 901 | exit_quit_cmd, exit_quit_cmd, NULL |
| 833 | }; | 902 | }; |
| 834 | 903 | ||
| 904 | |||
| 835 | void execcmd(int n, char cmdtok[][100]) { | 905 | void execcmd(int n, char cmdtok[][100]) { |
| 836 | int i = 0; | 906 | int i = 0; |
| 837 | while (strcmp(commands[i][0], cmdtok[0]) && strcmp(commands[i][0], "")) | 907 | while (strcmp(commands[i][0], cmdtok[0]) && strcmp(commands[i][0], "")) |
| @@ -842,6 +912,9 @@ void execcmd(int n, char cmdtok[][100]) { | |||
| 842 | printf("%s: not a command.\n", cmdtok[0]); | 912 | printf("%s: not a command.\n", cmdtok[0]); |
| 843 | } | 913 | } |
| 844 | 914 | ||
| 915 | |||
| 916 | /* Main loop */ | ||
| 917 | |||
| 845 | int main() { | 918 | int main() { |
| 846 | init_transition_table(); | 919 | init_transition_table(); |
| 847 | init_possible_next(); | 920 | init_possible_next(); |
diff --git a/src/solver.c b/src/solver.c index 82abd85..48e845f 100644 --- a/src/solver.c +++ b/src/solver.c | |||
| @@ -107,6 +107,88 @@ int eo_scram_spam(int scram[], int eo_list[][30], int fb, int rl, int ud, | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | 109 | ||
| 110 | /******/ | ||
| 111 | /* CO */ | ||
| 112 | /******/ | ||
| 113 | void niss_co_dfs(int co, int scramble[], int co_list[][30], int *co_count, | ||
| 114 | int t_table[pow3to7][19], int p_table[pow3to7], | ||
| 115 | int last1, int last2, int moves, int m, int d, int niss, | ||
| 116 | int can_use_niss, int hide, int ignore) { | ||
| 117 | |||
| 118 | |||
| 119 | if (*co_count >= m || moves > d || | ||
| 120 | ((!can_use_niss || niss) && ((!ignore && moves + p_table[co] > d) || | ||
| 121 | ( ignore && moves + p_table[co] - 2 > d)))) | ||
| 122 | return; | ||
| 123 | |||
| 124 | co_list[*co_count][moves] = 0; | ||
| 125 | |||
| 126 | if (co == 0 || (ignore && ( t_table[t_table[co][F]][B] == 0 || | ||
| 127 | t_table[t_table[co][R]][L] == 0 || | ||
| 128 | t_table[t_table[co][U]][D] == 0 ))) { | ||
| 129 | /* If an early CO is found, or if "case F2 B", or if hide is on. */ | ||
| 130 | if (moves != d || (parallel(last1, last2) && last2 % 3 == 2) || | ||
| 131 | (hide && moves > 0 && | ||
| 132 | (last1 % 3 == 0 || (parallel(last1, last2) && last2 % 3 == 0)))) | ||
| 133 | return; | ||
| 134 | /* Copy moves for the next solution */ | ||
| 135 | if (*co_count < m - 1) | ||
| 136 | copy_moves(co_list[*co_count], co_list[(*co_count)+1]); | ||
| 137 | (*co_count)++; | ||
| 138 | return; | ||
| 139 | } | ||
| 140 | |||
| 141 | for (int i = 1; i < 19; i++) { | ||
| 142 | if (possible_next[last1][last2] & (1 << i)) { | ||
| 143 | co_list[*co_count][moves] = niss ? -i : i; | ||
| 144 | niss_co_dfs(t_table[co][i], scramble, co_list, co_count, t_table, | ||
| 145 | p_table, i, last1, moves+1, m, d, niss, | ||
| 146 | can_use_niss, hide, ignore); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | if (*co_count >= m) | ||
| 151 | return; | ||
| 152 | co_list[*co_count][moves] = 0; | ||
| 153 | |||
| 154 | /* If not nissing already and we either have not done any move yet or | ||
| 155 | * the last move was F/F' etc, and if I am allowed to niss, try niss! */ | ||
| 156 | if (!niss && (last1 == 0 || t_table[0][last1] != 0) && can_use_niss && | ||
| 157 | !(hide && moves > 0 && | ||
| 158 | (last1 % 3 == 0 || (parallel(last1, last2) && last2 % 3 == 0)))) { | ||
| 159 | int aux[] = {0,0}; | ||
| 160 | niss_co_dfs(premoves_inverse(co_list[*co_count], scramble, aux, t_table), | ||
| 161 | scramble, co_list, co_count, t_table, p_table, | ||
| 162 | 0, 0, moves, m, d, 1, can_use_niss, hide, ignore); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | int co_scram_spam(int scram[], int co_list[][30], int fb, int rl, int ud, | ||
| 167 | int m, int b, int niss, int h, int ignore) { | ||
| 168 | |||
| 169 | init_small_pruning_tables(); | ||
| 170 | |||
| 171 | int n = 0, cofb = 0, corl = 0, coud = 0; | ||
| 172 | for (int i = 0; scram[i]; i++) { | ||
| 173 | cofb = cofb_transition_table[cofb][scram[i]]; | ||
| 174 | corl = corl_transition_table[corl][scram[i]]; | ||
| 175 | coud = coud_transition_table[coud][scram[i]]; | ||
| 176 | } | ||
| 177 | for (int i = 0; i <= b; i++) { | ||
| 178 | if (fb) | ||
| 179 | niss_co_dfs(cofb, scram, co_list, &n, cofb_transition_table, | ||
| 180 | cofb_pruning_table, 0, 0, 0, m, i, 0, niss, h, ignore); | ||
| 181 | if (rl) | ||
| 182 | niss_co_dfs(corl, scram, co_list, &n, corl_transition_table, | ||
| 183 | corl_pruning_table, 0, 0, 0, m, i, 0, niss, h, ignore); | ||
| 184 | if (ud) | ||
| 185 | niss_co_dfs(coud, scram, co_list, &n, coud_transition_table, | ||
| 186 | coud_pruning_table, 0, 0, 0, m, i, 0, niss, h, ignore); | ||
| 187 | } | ||
| 188 | return n; | ||
| 189 | } | ||
| 190 | |||
| 191 | |||
| 110 | /**************/ | 192 | /**************/ |
| 111 | /* DR from EO */ | 193 | /* DR from EO */ |
| 112 | /**************/ | 194 | /**************/ |
| @@ -600,10 +682,20 @@ void dr_corners_dfs(int cp, int sol[][30], int *sol_count, | |||
| 600 | 682 | ||
| 601 | sol[*sol_count][moves] = 0; | 683 | sol[*sol_count][moves] = 0; |
| 602 | 684 | ||
| 603 | if (cp == 0 || (ignore && | 685 | if (cp == 0 || |
| 686 | (ignore && mask == move_mask_drud && | ||
| 604 | (cp_transition_table[cp_transition_table[cp][U]][D3] == 0 || | 687 | (cp_transition_table[cp_transition_table[cp][U]][D3] == 0 || |
| 605 | cp_transition_table[cp_transition_table[cp][U2]][D2] == 0 || | 688 | cp_transition_table[cp_transition_table[cp][U2]][D2] == 0 || |
| 606 | cp_transition_table[cp_transition_table[cp][U3]][D] == 0 ))) { | 689 | cp_transition_table[cp_transition_table[cp][U3]][D] == 0 )) || |
| 690 | (ignore && mask == move_mask_drfb && | ||
| 691 | (cp_transition_table[cp_transition_table[cp][F]][B3] == 0 || | ||
| 692 | cp_transition_table[cp_transition_table[cp][F2]][B2] == 0 || | ||
| 693 | cp_transition_table[cp_transition_table[cp][F3]][B] == 0 )) || | ||
| 694 | (ignore && mask == move_mask_drrl && | ||
| 695 | (cp_transition_table[cp_transition_table[cp][R]][L3] == 0 || | ||
| 696 | cp_transition_table[cp_transition_table[cp][R2]][L2] == 0 || | ||
| 697 | cp_transition_table[cp_transition_table[cp][R3]][L] == 0 )) | ||
| 698 | ) { | ||
| 607 | if (moves != d) | 699 | if (moves != d) |
| 608 | return; | 700 | return; |
| 609 | /* Copy moves for the next solution */ | 701 | /* Copy moves for the next solution */ |
diff --git a/src/solver.h b/src/solver.h index d154c8f..abb55d3 100644 --- a/src/solver.h +++ b/src/solver.h | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | int eo_scram_spam(int scram[], int eo_list[][30], int fb, int rl, int ud, | 1 | int eo_scram_spam(int scram[], int eo_list[][30], int fb, int rl, int ud, |
| 2 | int m, int b, int niss, int h); | 2 | int m, int b, int niss, int h); |
| 3 | int co_scram_spam(int scram[], int co_list[][30], int fb, int rl, int ud, | ||
| 4 | int m, int b, int niss, int h, int i); | ||
| 3 | int dr_scram_spam(int scram[], int dr_list[][30], int fb, int rl, int ud, | 5 | int dr_scram_spam(int scram[], int dr_list[][30], int fb, int rl, int ud, |
| 4 | int m, int b, int h); | 6 | int m, int b, int h); |
| 5 | int drfrom_scram_spam(int scram[], int dr_list[][30], int from, int fb, | 7 | int drfrom_scram_spam(int scram[], int dr_list[][30], int from, int fb, |
