diff options
| author | Sebastiano Tronto <sebastiano.tronto@gmail.com> | 2021-11-11 21:37:34 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano.tronto@gmail.com> | 2021-11-11 21:37:34 +0100 |
| commit | 3568412f8f230774d0d11d7ed1c897424f95d3ef (patch) | |
| tree | 77223792d8c925a9b1fc32b3f4341e943b5f8209 /old/2021-02-28-transformcube-works/src/moves.c | |
| parent | 67e1b5e6e6a2c917a2fe58a37a1382c982b1e5c5 (diff) | |
| download | nissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.tar.gz nissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.zip | |
Rewritten from scratch. Welocme nissy 2.0!
Diffstat (limited to 'old/2021-02-28-transformcube-works/src/moves.c')
| -rw-r--r-- | old/2021-02-28-transformcube-works/src/moves.c | 489 |
1 files changed, 489 insertions, 0 deletions
diff --git a/old/2021-02-28-transformcube-works/src/moves.c b/old/2021-02-28-transformcube-works/src/moves.c new file mode 100644 index 0000000..4b0eee1 --- /dev/null +++ b/old/2021-02-28-transformcube-works/src/moves.c | |||
| @@ -0,0 +1,489 @@ | |||
| 1 | #include "moves.h" | ||
| 2 | |||
| 3 | Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f); | ||
| 4 | /* void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front); */ | ||
| 5 | bool read_ttables_file(); | ||
| 6 | bool write_ttables_file(); | ||
| 7 | |||
| 8 | /* Transition tables */ | ||
| 9 | uint16_t epose_ttable[NMOVES][factorial12/factorial8]; | ||
| 10 | uint16_t eposs_ttable[NMOVES][factorial12/factorial8]; | ||
| 11 | uint16_t eposm_ttable[NMOVES][factorial12/factorial8]; | ||
| 12 | uint16_t eofb_ttable[NMOVES][pow2to11]; | ||
| 13 | uint16_t eorl_ttable[NMOVES][pow2to11]; | ||
| 14 | uint16_t eoud_ttable[NMOVES][pow2to11]; | ||
| 15 | uint16_t cp_ttable[NMOVES][factorial8]; | ||
| 16 | uint16_t coud_ttable[NMOVES][pow3to7]; | ||
| 17 | uint16_t cofb_ttable[NMOVES][pow3to7]; | ||
| 18 | uint16_t corl_ttable[NMOVES][pow3to7]; | ||
| 19 | uint16_t cpos_ttable[NMOVES][factorial6]; | ||
| 20 | |||
| 21 | bool commute[NMOVES][NMOVES]; | ||
| 22 | bool possible_next[NMOVES][NMOVES][NMOVES]; | ||
| 23 | Move inverse[NMOVES]; | ||
| 24 | NissMove rotation_algs[24][3] = { | ||
| 25 | { { .m = NULLMOVE }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 26 | { { .m = y }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 27 | { { .m = y2 }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 28 | { { .m = y3 }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 29 | { { .m = z2 }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 30 | { { .m = y }, { .m = z2 }, { .m = NULLMOVE } }, | ||
| 31 | { { .m = x2 }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 32 | { { .m = y3 }, { .m = z2 }, { .m = NULLMOVE } }, | ||
| 33 | { { .m = z3 }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 34 | { { .m = z3 }, { .m = y }, { .m = NULLMOVE } }, | ||
| 35 | { { .m = z3 }, { .m = y2 }, { .m = NULLMOVE } }, | ||
| 36 | { { .m = z3 }, { .m = y3 }, { .m = NULLMOVE } }, | ||
| 37 | { { .m = z }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 38 | { { .m = z }, { .m = y3 }, { .m = NULLMOVE } }, | ||
| 39 | { { .m = z }, { .m = y2 }, { .m = NULLMOVE } }, | ||
| 40 | { { .m = z }, { .m = y }, { .m = NULLMOVE } }, | ||
| 41 | { { .m = x }, { .m = y2 }, { .m = NULLMOVE } }, | ||
| 42 | { { .m = x }, { .m = y }, { .m = NULLMOVE } }, | ||
| 43 | { { .m = x }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 44 | { { .m = x }, { .m = y3 }, { .m = NULLMOVE } }, | ||
| 45 | { { .m = x3 }, { .m = NULLMOVE }, { .m = NULLMOVE } }, | ||
| 46 | { { .m = x3 }, { .m = y }, { .m = NULLMOVE } }, | ||
| 47 | { { .m = x3 }, { .m = y2 }, { .m = NULLMOVE } }, | ||
| 48 | { { .m = x3 }, { .m = y3 }, { .m = NULLMOVE } }, | ||
| 49 | }; | ||
| 50 | |||
| 51 | char move_string[NMOVES][5] = | ||
| 52 | { "-", | ||
| 53 | "U", "U2", "U\'", "D", "D2", "D\'", "R", "R2", "R\'", | ||
| 54 | "L", "L2", "L\'", "F", "F2", "F\'", "B", "B2", "B\'", | ||
| 55 | "Uw", "Uw2", "Uw\'", "Dw", "Dw2", "Dw\'", "Rw", "Rw2", "Rw\'", | ||
| 56 | "Lw", "Lw2", "Lw\'", "Fw", "Fw2", "Fw\'", "Bw", "Bw2", "Bw\'", | ||
| 57 | "M", "M2", "M\'", "S", "S2", "S\'", "E", "E2", "E\'", | ||
| 58 | "x", "x2", "x\'", "y", "y2", "y\'", "z", "z2", "z\'" }; | ||
| 59 | |||
| 60 | /* For each type of pieces only the effects of U, x and y are described */ | ||
| 61 | int edge_cycle[NMOVES][12] = | ||
| 62 | { [U] = {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR}, | ||
| 63 | [x] = {DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR}, | ||
| 64 | [y] = {UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL} }; | ||
| 65 | int eofb_flipped[NMOVES][12] = | ||
| 66 | { [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 }, | ||
| 67 | [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } }; | ||
| 68 | int eorl_flipped[NMOVES][12] = | ||
| 69 | { [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | ||
| 70 | [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } }; | ||
| 71 | int eoud_flipped[NMOVES][12] = | ||
| 72 | { [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 }, | ||
| 73 | [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 }, | ||
| 74 | [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; | ||
| 75 | int corner_cycle[NMOVES][8] = | ||
| 76 | { [U] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR}, | ||
| 77 | [x] = {DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR}, | ||
| 78 | [y] = {UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL} }; | ||
| 79 | int coud_flipped[NMOVES][8] = | ||
| 80 | { [x] = {[UFR]=2,[UBR]=1,[DBR]=2,[DFR]=1,[UFL]=1,[UBL]=2,[DBL]=1,[DFL]=2} }; | ||
| 81 | int corl_flipped[NMOVES][8] = | ||
| 82 | { [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 }, | ||
| 83 | [y] = {[UFR]=1,[UBR]=2,[UBL]=1,[UFL]=2,[DFR]=2,[DBR]=1,[DBL]=2,[DFL]=1} }; | ||
| 84 | int cofb_flipped[NMOVES][8] = | ||
| 85 | { [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 }, | ||
| 86 | [x] = {[UFR]=1,[UBR]=2,[DFR]=2,[DBR]=1,[UBL]=1,[UFL]=2,[DBL]=2,[DFL]=1}, | ||
| 87 | [y] = {[UFR]=2,[UBR]=1,[UBL]=2,[UFL]=1,[DFR]=1,[DBR]=2,[DBL]=1,[DFL]=2} }; | ||
| 88 | int center_cycle[NMOVES][6] = | ||
| 89 | { [x] = {F_center, B_center, R_center, L_center, D_center, U_center}, | ||
| 90 | [y] = {U_center, D_center, B_center, F_center, R_center, L_center} }; | ||
| 91 | |||
| 92 | /* Each move is reduced to a combination of U, x and y using this table */ | ||
| 93 | Move equiv_moves[NMOVES][14] = { | ||
| 94 | [U] = { U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 95 | [U2] = { U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 96 | [U3] = { U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 97 | [D] = { x, x, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 98 | [D2] = { x, x, U, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 99 | [D3] = { x, x, U, U, U, x, x, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 100 | [R] = { y, x, U, x, x, x, y, y, y, 0, 0, 0, 0, 0 }, | ||
| 101 | [R2] = { y, x, U, U, x, x, x, y, y, y, 0, 0, 0, 0 }, | ||
| 102 | [R3] = { y, x, U, U, U, x, x, x, y, y, y, 0, 0, 0 }, | ||
| 103 | [L] = { y, y, y, x, U, x, x, x, y, 0, 0, 0, 0, 0 }, | ||
| 104 | [L2] = { y, y, y, x, U, U, x, x, x, y, 0, 0, 0, 0 }, | ||
| 105 | [L3] = { y, y, y, x, U, U, U, x, x, x, y, 0, 0, 0 }, | ||
| 106 | [F] = { x, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 107 | [F2] = { x, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 108 | [F3] = { x, U, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 109 | [B] = { x, x, x, U, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 110 | [B2] = { x, x, x, U, U, x, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 111 | [B3] = { x, x, x, U, U, U, x, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 112 | |||
| 113 | [Uw] = { x, x, U, x, x, y, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 114 | [Uw2] = { x, x, U, U, x, x, y, y, 0, 0, 0, 0, 0, 0 }, | ||
| 115 | [Uw3] = { x, x, U, U, U, x, x, y, y, y, 0, 0, 0, 0 }, | ||
| 116 | [Dw] = { U, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 117 | [Dw2] = { U, U, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 118 | [Dw3] = { U, U, U, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 119 | [Rw] = { y, y, y, x, U, x, x, x, y, x, 0, 0, 0, 0 }, | ||
| 120 | [Rw2] = { y, y, y, x, U, U, x, x, x, y, x, x, 0, 0 }, | ||
| 121 | [Rw3] = { y, y, y, x, U, U, U, y, x, x, x, y, 0, 0 }, | ||
| 122 | [Lw] = { y, x, U, x, x, x, y, y, y, x, x, x, 0, 0 }, | ||
| 123 | [Lw2] = { y, x, U, U, x, x, x, y, y, y, x, x, 0, 0 }, | ||
| 124 | [Lw3] = { y, x, U, U, U, x, x, x, y, y, y, x, 0, 0 }, | ||
| 125 | [Fw] = { x, x, x, U, y, y, y, x, 0, 0, 0, 0, 0, 0 }, | ||
| 126 | [Fw2] = { x, x, x, U, U, y, y, x, 0, 0, 0, 0, 0, 0 }, | ||
| 127 | [Fw3] = { x, x, x, U, U, U, y, x, 0, 0, 0, 0, 0, 0 }, | ||
| 128 | [Bw] = { x, U, y, y, y, x, x, x, 0, 0, 0, 0, 0, 0 }, | ||
| 129 | [Bw2] = { x, U, U, y, y, x, x, x, 0, 0, 0, 0, 0, 0 }, | ||
| 130 | [Bw3] = { x, U, U, U, y, x, x, x, 0, 0, 0, 0, 0, 0 }, | ||
| 131 | |||
| 132 | [M] = { y, x, U, x, x, U, U, U, y, x, y, y, y, 0 }, | ||
| 133 | [M2] = { y, x, U, U, x, x, U, U, x, x, x, y, 0, 0 }, | ||
| 134 | [M3] = { y, x, U, U, U, x, x, U, y, x, x, x, y, 0 }, | ||
| 135 | [S] = { x, U, U, U, x, x, U, y, y, y, x, 0, 0, 0 }, | ||
| 136 | [S2] = { x, U, U, x, x, U, U, y, y, x, 0, 0, 0, 0 }, | ||
| 137 | [S3] = { x, U, x, x, U, U, U, y, x, 0, 0, 0, 0, 0 }, | ||
| 138 | [E] = { U, x, x, U, U, U, x, x, y, y, y, 0, 0, 0 }, | ||
| 139 | [E2] = { U, U, x, x, U, U, x, x, y, y, 0, 0, 0, 0 }, | ||
| 140 | [E3] = { U, U, U, x, x, U, x, x, y, 0, 0, 0, 0, 0 }, | ||
| 141 | |||
| 142 | [x] = { x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 143 | [x2] = { x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 144 | [x3] = { x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 145 | [y] = { y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 146 | [y2] = { y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 147 | [y3] = { y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 148 | [z] = { y, y, y, x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 149 | [z2] = { y, y, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 150 | [z3] = { y, x, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | /* Movesets */ | ||
| 154 | bool standard_moveset[NMOVES] = { | ||
| 155 | [U] = true, [U2] = true, [U3] = true, [D] = true, [D2] = true, [D3] = true, | ||
| 156 | [R] = true, [R2] = true, [R3] = true, [L] = true, [L2] = true, [L3] = true, | ||
| 157 | [F] = true, [F2] = true, [F3] = true, [B] = true, [B2] = true, [B3] = true, | ||
| 158 | }; | ||
| 159 | |||
| 160 | bool is_solved_up_to_reorient(Cube cube) { | ||
| 161 | for (int i = 0; i < 25; i++) | ||
| 162 | if (is_solved(apply_alg(rotation_algs[i], cube))) | ||
| 163 | return true; | ||
| 164 | return false; | ||
| 165 | } | ||
| 166 | |||
| 167 | Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f) { | ||
| 168 | return move_via_arrays((CubeArray) | ||
| 169 | { edge_cycle[m], eofb_flipped[m], eorl_flipped[m], eoud_flipped[m], | ||
| 170 | corner_cycle[m], coud_flipped[m], corl_flipped[m], cofb_flipped[m], | ||
| 171 | center_cycle[m] }, cube, f); | ||
| 172 | } | ||
| 173 | |||
| 174 | int len(NissMove *alg) { | ||
| 175 | int i; | ||
| 176 | for (i = 0; alg[i].m != NULLMOVE; i++); | ||
| 177 | return i; | ||
| 178 | } | ||
| 179 | |||
| 180 | int copy_alg(NissMove *src, NissMove *dest) { | ||
| 181 | int i; | ||
| 182 | for (i = 0; src[i].m != NULLMOVE; i++) | ||
| 183 | dest[i] = src[i]; | ||
| 184 | dest[i].m = NULLMOVE; | ||
| 185 | return i; | ||
| 186 | } | ||
| 187 | |||
| 188 | int invert_alg(NissMove *src, NissMove *dest) { | ||
| 189 | int n = len(src); | ||
| 190 | for (int i = 0; i < n; i++) | ||
| 191 | dest[n-i-1] = (NissMove){.m=inverse[src[i].m], .inverse=src[i].inverse}; | ||
| 192 | dest[n].m = NULLMOVE; | ||
| 193 | return n; | ||
| 194 | } | ||
| 195 | |||
| 196 | int concat(NissMove *src1, NissMove *src2, NissMove *dest) { | ||
| 197 | int n1 = len(src1), n2 = len(src2); | ||
| 198 | copy_alg(src1, dest); | ||
| 199 | copy_alg(src2, dest+n1); | ||
| 200 | return n1+n2; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* TODO: all strings start with space?? */ | ||
| 204 | void print_moves(NissMove *alg) { | ||
| 205 | bool niss = false; | ||
| 206 | for (int i = 0; alg[i].m != NULLMOVE; i++) { | ||
| 207 | char *fill = !niss && alg[i].inverse ? " (" : | ||
| 208 | (niss && !alg[i].inverse ? ") " : " "); | ||
| 209 | printf("%s%s", fill, move_string[alg[i].m]); | ||
| 210 | niss = alg[i].inverse; | ||
| 211 | } | ||
| 212 | printf("%s\n", niss ? ")" : ""); | ||
| 213 | } | ||
| 214 | |||
| 215 | int read_moves(char *str, NissMove *alg, int n) { | ||
| 216 | bool niss = false; | ||
| 217 | int c = 0; | ||
| 218 | |||
| 219 | for (int i = 0; str[i] && c < n; i++) { | ||
| 220 | if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n') | ||
| 221 | continue; | ||
| 222 | |||
| 223 | if (str[i] == '(' || str[i] == ')') { | ||
| 224 | if ((niss && str[i] == '(') || (!niss && str[i] == ')')) | ||
| 225 | return -1; | ||
| 226 | niss = !niss; | ||
| 227 | continue; | ||
| 228 | } | ||
| 229 | |||
| 230 | alg[c].inverse = niss; alg[c].m = NULLMOVE; | ||
| 231 | for (Move j = 0; j < NMOVES; j++) { | ||
| 232 | if (str[i] == move_string[j][0]) { | ||
| 233 | alg[c].m = j; | ||
| 234 | if (alg[c].m <= B && str[i+1]=='w') { alg[c].m += Uw - U; i++; } | ||
| 235 | if (str[i+1]=='2') { alg[c].m += 1; i++; } | ||
| 236 | else if (str[i+1]=='\'' || str[i+1]=='3') { alg[c].m += 2; i++; } | ||
| 237 | c++; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | alg[c].m = NULLMOVE; | ||
| 244 | return c; | ||
| 245 | } | ||
| 246 | |||
| 247 | /* Helper function for cleanup. alg must contain only basic moves, no 2 or '. | ||
| 248 | top and front describe an admissible orientation of the cube. * | ||
| 249 | void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front) { | ||
| 250 | int c = 0, i = 0; | ||
| 251 | PieceFilter cpos_only = { .cpos = true }; | ||
| 252 | NissMove aux[n+3]; | ||
| 253 | aux[0].m = NULLMOVE; | ||
| 254 | |||
| 255 | while (i < n && alg[i].m != NULLMOVE) { | ||
| 256 | int j = i; | ||
| 257 | while (j < n && commute[alg[i].m][alg[j].m]) j++; | ||
| 258 | Move base = 6*((alg[i].m-1)/6); | ||
| 259 | int t1 = 0, t2 = 0; | ||
| 260 | for (int k = i; k < j; k++) | ||
| 261 | if (alg[k].m == base+1) t1 = (t1+1)%4; | ||
| 262 | else t2 = (t2+1)%4; | ||
| 263 | if (t1) { aux[c].inverse = inv; aux[c].m = base+t1; c++; } | ||
| 264 | if (t2) { aux[c].inverse = inv; aux[c].m = base+t2+3; c++; } | ||
| 265 | i = j; | ||
| 266 | } | ||
| 267 | aux[c].m = NULLMOVE; | ||
| 268 | |||
| 269 | CubeArray q; | ||
| 270 | cube_to_arrays((Cube){0}, &q, cpos_only); | ||
| 271 | * First we try to rotate in one move, then we try an x or y rotation | ||
| 272 | followed by a z rotation | ||
| 273 | TODO: change once I implement the "is_rotaton(Move) function" * | ||
| 274 | for (int r = x; r <= z3; r++) { | ||
| 275 | move_cubearray(r, &q, cpos_only); | ||
| 276 | if (q.cpos[F_center] == front && q.cpos[U_center] == top) { | ||
| 277 | aux[c].inverse = inv; aux[c].m = r; | ||
| 278 | |||
| 279 | aux[++c].m = NULLMOVE; | ||
| 280 | copy_alg(aux, alg); | ||
| 281 | return; | ||
| 282 | } | ||
| 283 | move_cubearray(inverse[r], &q, cpos_only); | ||
| 284 | } | ||
| 285 | for (int r = x; r <= y3; r++) { | ||
| 286 | move_cubearray(r, &q, cpos_only); | ||
| 287 | if (q.cpos[F_center] == front) { | ||
| 288 | aux[c].inverse = inv; aux[c++].m = r; | ||
| 289 | break; | ||
| 290 | } | ||
| 291 | move_cubearray(inverse[r], &q, cpos_only); | ||
| 292 | } | ||
| 293 | for (int r = z; r <= z3; r++) { | ||
| 294 | move_cubearray(r, &q, cpos_only); | ||
| 295 | if (q.cpos[U_center] == top) { | ||
| 296 | aux[c].inverse = inv; aux[c++].m = r; | ||
| 297 | break; | ||
| 298 | } | ||
| 299 | move_cubearray(inverse[r], &q, cpos_only); | ||
| 300 | } | ||
| 301 | |||
| 302 | aux[c].m = NULLMOVE; | ||
| 303 | copy_alg(aux, alg); | ||
| 304 | } | ||
| 305 | |||
| 306 | * TODO: does not work with niss + rotations * | ||
| 307 | void cleanup(NissMove *alg, int n) { | ||
| 308 | int count_n = 0, count_i = 0, *count; | ||
| 309 | PieceFilter cpos_only = { .cpos = true }; | ||
| 310 | NissMove aux_n[n+1], aux_i[n+1], *aux; | ||
| 311 | CubeArray cube_n, cube_i, *cube; | ||
| 312 | cube_to_arrays((Cube){0}, &cube_n, cpos_only); | ||
| 313 | cube_to_arrays((Cube){0}, &cube_i, cpos_only); | ||
| 314 | |||
| 315 | for (int i = 0; count_n + count_i < n && alg[i].m != NULLMOVE; i++) { | ||
| 316 | if (alg[i].inverse) { count = &count_i; aux = aux_i; cube = &cube_i; } | ||
| 317 | else { count = &count_n; aux = aux_n; cube = &cube_n; } | ||
| 318 | |||
| 319 | for (int j = 0; equiv_moves[alg[i].m][j]; j++) { | ||
| 320 | Move m = equiv_moves[alg[i].m][j]; | ||
| 321 | aux[*count].inverse = alg[i].inverse; | ||
| 322 | move_cubearray(m, cube, cpos_only); | ||
| 323 | if (m == U) aux[(*count)++].m = 3 * cube->cpos[0] + 1; | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | aux_n[count_n].m = NULLMOVE; | ||
| 328 | aux_i[count_i].m = NULLMOVE; | ||
| 329 | sort_cancel_rotate(aux_n, count_n, false, cube_n.cpos[0], cube_n.cpos[4]); | ||
| 330 | sort_cancel_rotate(aux_i, count_i, true, cube_i.cpos[0], cube_n.cpos[4]); | ||
| 331 | copy_alg(aux_n, alg); | ||
| 332 | copy_alg(aux_i, alg+count_n); | ||
| 333 | } | ||
| 334 | */ | ||
| 335 | |||
| 336 | bool read_ttables_file() { | ||
| 337 | FILE *ttf; | ||
| 338 | long unsigned int me[11] = { factorial12/factorial8, factorial12/factorial8, | ||
| 339 | factorial12/factorial8, pow2to11, pow2to11, pow2to11, | ||
| 340 | factorial8, pow3to7, pow3to7, pow3to7, factorial6 }; | ||
| 341 | if ((ttf = fopen("ttables", "rb")) != NULL) { | ||
| 342 | bool r = true; | ||
| 343 | for (int m = 0; m < NMOVES; m++) { | ||
| 344 | r = r && fread(epose_ttable[m], sizeof(uint16_t), me[0], ttf) == me[0]; | ||
| 345 | r = r && fread(eposs_ttable[m], sizeof(uint16_t), me[1], ttf) == me[1]; | ||
| 346 | r = r && fread(eposm_ttable[m], sizeof(uint16_t), me[2], ttf) == me[2]; | ||
| 347 | r = r && fread(eofb_ttable[m], sizeof(uint16_t), me[3], ttf) == me[3]; | ||
| 348 | r = r && fread(eorl_ttable[m], sizeof(uint16_t), me[4], ttf) == me[4]; | ||
| 349 | r = r && fread(eoud_ttable[m], sizeof(uint16_t), me[5], ttf) == me[5]; | ||
| 350 | r = r && fread(cp_ttable[m], sizeof(uint16_t), me[6], ttf) == me[6]; | ||
| 351 | r = r && fread(coud_ttable[m], sizeof(uint16_t), me[7], ttf) == me[7]; | ||
| 352 | r = r && fread(corl_ttable[m], sizeof(uint16_t), me[8], ttf) == me[8]; | ||
| 353 | r = r && fread(cofb_ttable[m], sizeof(uint16_t), me[9], ttf) == me[9]; | ||
| 354 | r = r && fread(cpos_ttable[m], sizeof(uint16_t), me[10], ttf) == me[10]; | ||
| 355 | } | ||
| 356 | fclose(ttf); | ||
| 357 | return r; | ||
| 358 | } else return false; | ||
| 359 | } | ||
| 360 | |||
| 361 | bool write_ttables_file() { | ||
| 362 | FILE *ttf; | ||
| 363 | long unsigned int me[11] = { factorial12/factorial8, factorial12/factorial8, | ||
| 364 | factorial12/factorial8, pow2to11, pow2to11, pow2to11, | ||
| 365 | factorial8, pow3to7, pow3to7, pow3to7, factorial6 }; | ||
| 366 | if ((ttf = fopen("ttables", "wb")) != NULL) { | ||
| 367 | bool r = true; | ||
| 368 | for (int m = 0; m < NMOVES; m++) { | ||
| 369 | r = r && fwrite(epose_ttable[m], sizeof(uint16_t), me[0], ttf) == me[0]; | ||
| 370 | r = r && fwrite(eposs_ttable[m], sizeof(uint16_t), me[1], ttf) == me[1]; | ||
| 371 | r = r && fwrite(eposm_ttable[m], sizeof(uint16_t), me[2], ttf) == me[2]; | ||
| 372 | r = r && fwrite(eofb_ttable[m], sizeof(uint16_t), me[3], ttf) == me[3]; | ||
| 373 | r = r && fwrite(eorl_ttable[m], sizeof(uint16_t), me[4], ttf) == me[4]; | ||
| 374 | r = r && fwrite(eoud_ttable[m], sizeof(uint16_t), me[5], ttf) == me[5]; | ||
| 375 | r = r && fwrite(cp_ttable[m], sizeof(uint16_t), me[6], ttf) == me[6]; | ||
| 376 | r = r && fwrite(coud_ttable[m], sizeof(uint16_t), me[7], ttf) == me[7]; | ||
| 377 | r = r && fwrite(corl_ttable[m], sizeof(uint16_t), me[8], ttf) == me[8]; | ||
| 378 | r = r && fwrite(cofb_ttable[m], sizeof(uint16_t), me[9], ttf) == me[9]; | ||
| 379 | r = r && fwrite(cpos_ttable[m], sizeof(uint16_t), me[10],ttf) == me[10]; | ||
| 380 | } | ||
| 381 | fclose(ttf); | ||
| 382 | return r; | ||
| 383 | } else return false; | ||
| 384 | } | ||
| 385 | |||
| 386 | void init_ttables(bool read, bool write) { | ||
| 387 | /* Generate all move cycles and flips; I do this regardless */ | ||
| 388 | for (int i = 0; i < NMOVES; i++) { | ||
| 389 | if (i == U || i == x || i == y) | ||
| 390 | continue; | ||
| 391 | |||
| 392 | Cube c = {0}; | ||
| 393 | for (int j = 0; equiv_moves[i][j]; j++) | ||
| 394 | c = apply_move_cubearray(equiv_moves[i][j], c, pf_all); | ||
| 395 | |||
| 396 | CubeArray arrs = { | ||
| 397 | edge_cycle[i], eofb_flipped[i], eorl_flipped[i], eoud_flipped[i], | ||
| 398 | corner_cycle[i], coud_flipped[i], corl_flipped[i], cofb_flipped[i], | ||
| 399 | center_cycle[i] | ||
| 400 | }; | ||
| 401 | cube_to_arrays(c, &arrs, pf_all); | ||
| 402 | } | ||
| 403 | |||
| 404 | if (read) | ||
| 405 | if (read_ttables_file()) | ||
| 406 | return; | ||
| 407 | |||
| 408 | /* Initialize transition tables */ | ||
| 409 | for (int m = 0; m < NMOVES; m++) { | ||
| 410 | for (uint16_t i = 0; i < factorial12/factorial8; i++) { | ||
| 411 | epose_ttable[m][i] = apply_move_cubearray(m,(Cube){.epose=i},pf_e).epose; | ||
| 412 | eposs_ttable[m][i] = apply_move_cubearray(m,(Cube){.eposs=i},pf_s).eposs; | ||
| 413 | eposm_ttable[m][i] = apply_move_cubearray(m,(Cube){.eposm=i},pf_m).eposm; | ||
| 414 | } | ||
| 415 | for (uint16_t i = 0; i < pow2to11; i++ ) { | ||
| 416 | eofb_ttable[m][i] = apply_move_cubearray(m,(Cube){.eofb=i},pf_eo).eofb; | ||
| 417 | eorl_ttable[m][i] = apply_move_cubearray(m,(Cube){.eorl=i},pf_eo).eorl; | ||
| 418 | eoud_ttable[m][i] = apply_move_cubearray(m,(Cube){.eoud=i},pf_eo).eoud; | ||
| 419 | } | ||
| 420 | for (uint16_t i = 0; i < pow3to7; i++) { | ||
| 421 | coud_ttable[m][i] = apply_move_cubearray(m,(Cube){.coud=i},pf_co).coud; | ||
| 422 | corl_ttable[m][i] = apply_move_cubearray(m,(Cube){.corl=i},pf_co).corl; | ||
| 423 | cofb_ttable[m][i] = apply_move_cubearray(m,(Cube){.cofb=i},pf_co).cofb; | ||
| 424 | } | ||
| 425 | for (uint16_t i = 0; i < factorial8; i++) | ||
| 426 | cp_ttable[m][i] = apply_move_cubearray(m,(Cube){.cp=i},pf_cp).cp; | ||
| 427 | for (uint16_t i = 0; i < factorial6; i++) | ||
| 428 | cpos_ttable[m][i] = apply_move_cubearray(m,(Cube){.cpos=i},pf_cpos).cpos; | ||
| 429 | } | ||
| 430 | |||
| 431 | if (write) | ||
| 432 | if (!write_ttables_file()) | ||
| 433 | printf("Error in writing ttables: file not writable\n"); | ||
| 434 | } | ||
| 435 | |||
| 436 | Cube move_cube(Move m, Cube cube) { | ||
| 437 | Cube moved = {0}; | ||
| 438 | |||
| 439 | moved.epose = epose_ttable[m][cube.epose]; | ||
| 440 | moved.eposs = eposs_ttable[m][cube.eposs]; | ||
| 441 | moved.eposm = eposm_ttable[m][cube.eposm]; | ||
| 442 | moved.eofb = eofb_ttable[m][cube.eofb]; | ||
| 443 | moved.eorl = eorl_ttable[m][cube.eorl]; | ||
| 444 | moved.eoud = eoud_ttable[m][cube.eoud]; | ||
| 445 | moved.coud = coud_ttable[m][cube.coud]; | ||
| 446 | moved.cofb = cofb_ttable[m][cube.cofb]; | ||
| 447 | moved.corl = corl_ttable[m][cube.corl]; | ||
| 448 | moved.cp = cp_ttable[m][cube.cp]; | ||
| 449 | moved.cpos = cpos_ttable[m][cube.cpos]; | ||
| 450 | |||
| 451 | return moved; | ||
| 452 | } | ||
| 453 | |||
| 454 | Cube apply_alg(NissMove *alg, Cube cube) { | ||
| 455 | Cube ret = {0}; | ||
| 456 | for (int i = 0; alg[i].m != NULLMOVE; i++) | ||
| 457 | if (alg[i].inverse) | ||
| 458 | ret = move_cube(alg[i].m, ret); | ||
| 459 | |||
| 460 | ret = compose(cube, inverse_cube(ret)); | ||
| 461 | |||
| 462 | for (int i = 0; alg[i].m != NULLMOVE; i++) | ||
| 463 | if (!alg[i].inverse) | ||
| 464 | ret = move_cube(alg[i].m, ret); | ||
| 465 | return ret; | ||
| 466 | } | ||
| 467 | |||
| 468 | void init_aux_tables() { | ||
| 469 | /* Commute */ | ||
| 470 | for (int i = 0; i < NMOVES; i++) | ||
| 471 | for (int j = 0; j < NMOVES; j++) | ||
| 472 | commute[i][j] = equal(move_cube(i, move_cube(j, (Cube){0})), | ||
| 473 | move_cube(j, move_cube(i, (Cube){0}))); | ||
| 474 | |||
| 475 | /* Possible next (if the sequence i j k is valid) */ | ||
| 476 | for (int i = 0; i < NMOVES; i++) | ||
| 477 | for (int j = 0; j < NMOVES; j++) | ||
| 478 | for (int k = 0; k < NMOVES; k++) | ||
| 479 | possible_next[i][j][k] = | ||
| 480 | (j == 0) || | ||
| 481 | (j != 0 && (j-(j-1)%3) != (k-(k-1)%3) && | ||
| 482 | !(i != 0 && commute[i][j] && (i-(i-1)%3) == (k-(k-1)%3))); | ||
| 483 | |||
| 484 | /* Inverse */ | ||
| 485 | for (int i = 0; i < NMOVES; i++) | ||
| 486 | inverse[i] = i == NULLMOVE ? NULLMOVE : i + 2 - 2*((i-1)%3); | ||
| 487 | |||
| 488 | } | ||
| 489 | |||
