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 /src/moves.c | |
| parent | 67e1b5e6e6a2c917a2fe58a37a1382c982b1e5c5 (diff) | |
| download | nissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.tar.gz nissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.zip | |
Rewritten from scratch. Welocme nissy 2.0!
Diffstat (limited to 'src/moves.c')
| -rw-r--r-- | src/moves.c | 860 |
1 files changed, 407 insertions, 453 deletions
diff --git a/src/moves.c b/src/moves.c index ce47e8f..25ce779 100644 --- a/src/moves.c +++ b/src/moves.c | |||
| @@ -1,521 +1,475 @@ | |||
| 1 | /* This file contains the definitions of the basic moves of the cube. | ||
| 2 | * There is no object or type representing the cube. | ||
| 3 | * Data about the cube can be represented by arrays (describing the position | ||
| 4 | * of pieces of certain types), integers (representing for example a bitmask | ||
| 5 | * for the orientation of pieces of certain type, or the permutation index of | ||
| 6 | * an array representing the permutation of pieces). | ||
| 7 | * Each of the moves functions operates on one such piece of data. | ||
| 8 | * | ||
| 9 | * For example, a way of representing the cube can be: | ||
| 10 | * - An integer eo, which is a bitmask for the orientation of the edges. | ||
| 11 | * - An integer co, same for corners. | ||
| 12 | * - An array ep[12], where a[i]=j means that the edge j is in place i. | ||
| 13 | * - An integer cp representing the permutation index of a permutation array | ||
| 14 | * which is the analogue of that described for edges. | ||
| 15 | * | ||
| 16 | * Different representations will be used for different use-cases. */ | ||
| 17 | |||
| 18 | #include "coordinates.h" | ||
| 19 | #include "moves.h" | 1 | #include "moves.h" |
| 20 | 2 | ||
| 21 | /* possible_next[i][j] is a bitmask representing the possible | 3 | /* Local functions ***********************************************************/ |
| 22 | * next moves we can apply. For example, if the last moves a 0 R then it does | ||
| 23 | * not make sense to apply R, R2 or R'. If they are U D2 it does not make | ||
| 24 | * sense to apply any U* or D*. */ | ||
| 25 | int possible_next[19][19]; | ||
| 26 | 4 | ||
| 27 | int parallel(int m1, int m2) { | 5 | static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f); |
| 28 | if (m1 == 0 || m2 == 0) return 0; | 6 | static bool read_mtables_file(); |
| 29 | return ((m1-1)/6 == (m2-1)/6); | 7 | static bool write_mtables_file(); |
| 30 | } | ||
| 31 | 8 | ||
| 32 | int compute_possible_next(int last1, int last2) { | 9 | /* Tables and other data *****************************************************/ |
| 33 | if (last1 == 0) return move_mask_all; | ||
| 34 | 10 | ||
| 35 | /* Removes the 2 or ' (e.g. turns U2 to U, R' to R). */ | 11 | /* Every move is translated to a an <U, x, y> alg before filling the |
| 36 | last2 = (last2 == 0) ? last2 : 3*((last2-1)/3) + 1; | 12 | transition tables, see init_moves() */ |
| 37 | last1 = 3*((last1-1)/3) + 1; | ||
| 38 | 13 | ||
| 39 | int mask = move_mask_all ^ (7 << last1); | 14 | static int edge_cycle[NMOVES][12] = |
| 15 | { | ||
| 16 | [U] = { UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR }, | ||
| 17 | [x] = { DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR }, | ||
| 18 | [y] = { UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL } | ||
| 19 | }; | ||
| 40 | 20 | ||
| 41 | if (parallel(last1, last2)) | 21 | static int corner_cycle[NMOVES][8] = |
| 42 | mask ^= 7 << last2; | 22 | { |
| 43 | else if (last1 % 6 == 4) /*Always U before D, R before L, F before B*/ | 23 | [U] = { UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR }, |
| 44 | mask ^= 7 << (last1-3); | 24 | [x] = { DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR }, |
| 25 | [y] = { UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL } | ||
| 26 | }; | ||
| 45 | 27 | ||
| 46 | return mask; | 28 | static int center_cycle[NMOVES][6] = |
| 47 | } | 29 | { |
| 30 | [x] = { F_center, B_center, R_center, L_center, D_center, U_center }, | ||
| 31 | [y] = { U_center, D_center, B_center, F_center, R_center, L_center } | ||
| 32 | }; | ||
| 48 | 33 | ||
| 49 | void init_possible_next() { | 34 | static int eofb_flipped[NMOVES][12] = { |
| 50 | for (int i = 0; i < 19; i++) | 35 | [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 }, |
| 51 | for (int j = 0; j < 19; j++) | 36 | [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } |
| 52 | possible_next[i][j] = compute_possible_next(i, j); | 37 | }; |
| 53 | } | ||
| 54 | 38 | ||
| 55 | /* Piece cycles depending on the move. For example edge_cycle[U2][UF] | 39 | static int eorl_flipped[NMOVES][12] = { |
| 56 | * gives the piece in position UF after applying U2 to a solved cube */ | 40 | [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
| 41 | [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } | ||
| 42 | }; | ||
| 57 | 43 | ||
| 58 | int edge_cycle[19][12] = { | 44 | static int eoud_flipped[NMOVES][12] = { |
| 59 | {UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR}, /* - */ | 45 | [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 }, |
| 60 | {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR}, /* U */ | 46 | [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 }, |
| 61 | {UB, UR, UF, UL, DF, DL, DB, DR, FR, FL, BL, BR}, /* U2 */ | 47 | [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } |
| 62 | {UL, UB, UR, UF, DF, DL, DB, DR, FR, FL, BL, BR}, /* U' */ | ||
| 63 | {UF, UL, UB, UR, DL, DB, DR, DF, FR, FL, BL, BR}, /* D */ | ||
| 64 | {UF, UL, UB, UR, DB, DR, DF, DL, FR, FL, BL, BR}, /* D2 */ | ||
| 65 | {UF, UL, UB, UR, DR, DF, DL, DB, FR, FL, BL, BR}, /* D' */ | ||
| 66 | {UF, UL, UB, FR, DF, DL, DB, BR, DR, FL, BL, UR}, /* R */ | ||
| 67 | {UF, UL, UB, DR, DF, DL, DB, UR, BR, FL, BL, FR}, /* R2 */ | ||
| 68 | {UF, UL, UB, BR, DF, DL, DB, FR, UR, FL, BL, DR}, /* R' */ | ||
| 69 | {UF, BL, UB, UR, DF, FL, DB, DR, FR, UL, DL, BR}, /* L */ | ||
| 70 | {UF, DL, UB, UR, DF, UL, DB, DR, FR, BL, FL, BR}, /* L2 */ | ||
| 71 | {UF, FL, UB, UR, DF, BL, DB, DR, FR, DL, UL, BR}, /* L' */ | ||
| 72 | {FL, UL, UB, UR, FR, DL, DB, DR, UF, DF, BL, BR}, /* F */ | ||
| 73 | {DF, UL, UB, UR, UF, DL, DB, DR, FL, FR, BL, BR}, /* F2 */ | ||
| 74 | {FR, UL, UB, UR, FL, DL, DB, DR, DF, UF, BL, BR}, /* F' */ | ||
| 75 | {UF, UL, BR, UR, DF, DL, BL, DR, FR, FL, UB, DB}, /* B */ | ||
| 76 | {UF, UL, DB, UR, DF, DL, UB, DR, FR, FL, BR, BL}, /* B2 */ | ||
| 77 | {UF, UL, BL, UR, DF, DL, BR, DR, FR, FL, DB, UB} /* B' */ | ||
| 78 | }; | 48 | }; |
| 79 | 49 | ||
| 80 | int corner_cycle[19][8] = { | 50 | static int coud_flipped[NMOVES][8] = { |
| 81 | {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR}, /* - */ | 51 | [x] = { |
| 82 | {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR}, /* U */ | 52 | [UFR] = 2, [UBR] = 1, [UFL] = 1, [UBL] = 2, |
| 83 | {UBL, UBR, UFR, UFL, DFR, DFL, DBL, DBR}, /* U2 */ | 53 | [DBR] = 2, [DFR] = 1, [DBL] = 1, [DFL] = 2 |
| 84 | {UFL, UBL, UBR, UFR, DFR, DFL, DBL, DBR}, /* U' */ | 54 | } |
| 85 | {UFR, UFL, UBL, UBR, DFL, DBL, DBR, DFR}, /* D */ | ||
| 86 | {UFR, UFL, UBL, UBR, DBL, DBR, DFR, DFL}, /* D2 */ | ||
| 87 | {UFR, UFL, UBL, UBR, DBR, DFR, DFL, DBL}, /* D' */ | ||
| 88 | {DFR, UFL, UBL, UFR, DBR, DFL, DBL, UBR}, /* R */ | ||
| 89 | {DBR, UFL, UBL, DFR, UBR, DFL, DBL, UFR}, /* R2 */ | ||
| 90 | {UBR, UFL, UBL, DBR, UFR, DFL, DBL, DFR}, /* R' */ | ||
| 91 | {UFR, UBL, DBL, UBR, DFR, UFL, DFL, DBR}, /* L */ | ||
| 92 | {UFR, DBL, DFL, UBR, DFR, UBL, UFL, DBR}, /* L2 */ | ||
| 93 | {UFR, DFL, UFL, UBR, DFR, DBL, UBL, DBR}, /* L' */ | ||
| 94 | {UFL, DFL, UBL, UBR, UFR, DFR, DBL, DBR}, /* F */ | ||
| 95 | {DFL, DFR, UBL, UBR, UFL, UFR, DBL, DBR}, /* F2 */ | ||
| 96 | {DFR, UFR, UBL, UBR, DFL, UFL, DBL, DBR}, /* F' */ | ||
| 97 | {UFR, UFL, UBR, DBR, DFR, DFL, UBL, DBL}, /* B */ | ||
| 98 | {UFR, UFL, DBR, DBL, DFR, DFL, UBR, UBL}, /* B2 */ | ||
| 99 | {UFR, UFL, DBL, UBL, DFR, DFL, DBR, UBR}, /* U' */ | ||
| 100 | }; | 55 | }; |
| 101 | 56 | ||
| 102 | /* Transition tables */ | 57 | static int corl_flipped[NMOVES][8] = { |
| 58 | [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 }, | ||
| 59 | [y] = { | ||
| 60 | [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2, | ||
| 61 | [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1 | ||
| 62 | } | ||
| 63 | }; | ||
| 103 | 64 | ||
| 104 | int eofb_transition_table[pow2to11][19]; | 65 | static int cofb_flipped[NMOVES][8] = { |
| 105 | int eorl_transition_table[pow2to11][19]; | 66 | [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 }, |
| 106 | int eoud_transition_table[pow2to11][19]; | 67 | [x] = { |
| 107 | int coud_transition_table[pow3to7][19]; | 68 | [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2, |
| 108 | int cofb_transition_table[pow3to7][19]; | 69 | [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1 |
| 109 | int corl_transition_table[pow3to7][19]; | 70 | }, |
| 110 | int epud_transition_table[factorial8][19]; | 71 | [y] = { |
| 111 | int eprl_transition_table[factorial8][19]; | 72 | [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1, |
| 112 | int epfb_transition_table[factorial8][19]; | 73 | [DFR] = 1, [DBR] = 2, [DBL] = 1, [DFL] = 2 |
| 113 | int epose_transition_table[binom12on4][19]; | 74 | } |
| 114 | int eposs_transition_table[binom12on4][19]; | 75 | }; |
| 115 | int eposm_transition_table[binom12on4][19]; | ||
| 116 | int epe_transition_table[factorial4][19]; | ||
| 117 | int eps_transition_table[factorial4][19]; | ||
| 118 | int epm_transition_table[factorial4][19]; | ||
| 119 | int emslices_transition_table[binom12on4*binom8on4][19]; | ||
| 120 | int cp_transition_table[factorial8][19]; | ||
| 121 | 76 | ||
| 122 | /***/ | 77 | static char equiv_alg_string[100][NMOVES] = { |
| 123 | /* Functions for permuting pieces (given in array format) */ | 78 | [NULLMOVE] = "", |
| 124 | /***/ | ||
| 125 | 79 | ||
| 126 | void apply_move_ep_array(int move, int ep[12]) { | 80 | [U] = " U ", |
| 127 | int aux[12]; | 81 | [U2] = " UU ", |
| 128 | for (int i = 0; i < 12; i++) | 82 | [U3] = " UUU ", |
| 129 | aux[i] = ep[i]; | 83 | [D] = " xx U xx ", |
| 130 | for (int i = 0; i < 12; i++) | 84 | [D2] = " xx UU xx ", |
| 131 | ep[i] = aux[edge_cycle[move][i]]; | 85 | [D3] = " xx UUU xx ", |
| 132 | } | 86 | [R] = " yx U xxxyyy ", |
| 87 | [R2] = " yx UU xxxyyy ", | ||
| 88 | [R3] = " yx UUU xxxyyy ", | ||
| 89 | [L] = " yyyx U xxxy ", | ||
| 90 | [L2] = " yyyx UU xxxy ", | ||
| 91 | [L3] = " yyyx UUU xxxy ", | ||
| 92 | [F] = " x U xxx ", | ||
| 93 | [F2] = " x UU xxx ", | ||
| 94 | [F3] = " x UUU xxx ", | ||
| 95 | [B] = " xxx U x ", | ||
| 96 | [B2] = " xxx UU x ", | ||
| 97 | [B3] = " xxx UUU x ", | ||
| 133 | 98 | ||
| 134 | void apply_move_cp_array(int move, int cp[8]) { | 99 | [Uw] = " xx U xx y ", |
| 135 | int aux[8]; | 100 | [Uw2] = " xx UU xx yy ", |
| 136 | for (int i = 0; i < 8; i++) | 101 | [Uw3] = " xx UUU xx yyy ", |
| 137 | aux[i] = cp[i]; | 102 | [Dw] = " U yyy ", |
| 138 | for (int i = 0; i < 8; i++) | 103 | [Dw2] = " UU yy ", |
| 139 | cp[i] = aux[corner_cycle[move][i]]; | 104 | [Dw3] = " UUU y ", |
| 140 | } | 105 | [Rw] = " yyyx U xxxy x ", |
| 106 | [Rw2] = " yyyx UU xxxy xx ", | ||
| 107 | [Rw3] = " yyyx UUU xxxy xxx ", | ||
| 108 | [Lw] = " yx U xxxyyy xxx ", | ||
| 109 | [Lw2] = " yx UU xxxyyy xx ", | ||
| 110 | [Lw3] = " yx UUU xxxyyy x ", | ||
| 111 | [Fw] = " xxx U x yxxxyyy ", | ||
| 112 | [Fw2] = " xxx UU x yxxyyy ", | ||
| 113 | [Fw3] = " xxx UUU x yxyyy ", | ||
| 114 | [Bw] = " x U xxx yxyyy ", | ||
| 115 | [Bw2] = " x UU xxx yxxyyy ", | ||
| 116 | [Bw3] = " x UUU xxx yxxxyyy ", | ||
| 141 | 117 | ||
| 142 | /***/ | 118 | [M] = " yx U xx UUU yxyyy ", |
| 143 | /* Functions for permuting pieces (given in integer format) */ | 119 | [M2] = " yx UU xx UU xxxy ", |
| 144 | /***/ | 120 | [M3] = " yx UUU xx U yxxxy ", |
| 121 | [S] = " x UUU xx U yyyx ", | ||
| 122 | [S2] = " x UU xx UU yyx ", | ||
| 123 | [S3] = " x U xx UUU yx ", | ||
| 124 | [E] = " U xx UUU xxyyy ", | ||
| 125 | [E2] = " UU xx UU xxyy ", | ||
| 126 | [E3] = " UUU xx U xxy ", | ||
| 145 | 127 | ||
| 146 | int apply_move_ep_int(int move, int ep) { | 128 | [x] = " x ", |
| 147 | int a[12]; | 129 | [x2] = " xx ", |
| 148 | ep_int_to_array(ep, a); | 130 | [x3] = " xxx ", |
| 149 | apply_move_ep_array(move, a); | 131 | [y] = " y ", |
| 150 | return ep_array_to_int(a); | 132 | [y2] = " yy ", |
| 151 | } | 133 | [y3] = " yyy ", |
| 134 | [z] = " yyy x y ", | ||
| 135 | [z2] = " yy xx ", | ||
| 136 | [z3] = " y x yyy " | ||
| 137 | }; | ||
| 152 | 138 | ||
| 153 | int apply_move_epud_int(int move, int ep) { | 139 | /* Transition tables, to be loaded up at the beginning */ |
| 154 | int a[12]; | 140 | static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8]; |
| 155 | epud_int_to_array(ep, a); | 141 | static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8]; |
| 156 | apply_move_ep_array(move, a); | 142 | static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8]; |
| 157 | return epud_array_to_int(a); | 143 | static int eofb_mtable[NMOVES][POW2TO11]; |
| 158 | } | 144 | static int eorl_mtable[NMOVES][POW2TO11]; |
| 145 | static int eoud_mtable[NMOVES][POW2TO11]; | ||
| 146 | static int cp_mtable[NMOVES][FACTORIAL8]; | ||
| 147 | static int coud_mtable[NMOVES][POW3TO7]; | ||
| 148 | static int cofb_mtable[NMOVES][POW3TO7]; | ||
| 149 | static int corl_mtable[NMOVES][POW3TO7]; | ||
| 150 | static int cpos_mtable[NMOVES][FACTORIAL6]; | ||
| 159 | 151 | ||
| 160 | int apply_move_eprl_int(int move, int ep) { | ||
| 161 | int a[12]; | ||
| 162 | eprl_int_to_array(ep, a); | ||
| 163 | apply_move_ep_array(move, a); | ||
| 164 | return eprl_array_to_int(a); | ||
| 165 | } | ||
| 166 | 152 | ||
| 167 | int apply_move_epfb_int(int move, int ep) { | 153 | /* Local functions implementation ********************************************/ |
| 168 | int a[12]; | ||
| 169 | epfb_int_to_array(ep, a); | ||
| 170 | apply_move_ep_array(move, a); | ||
| 171 | return epfb_array_to_int(a); | ||
| 172 | } | ||
| 173 | 154 | ||
| 174 | int apply_move_epose_int(int move, int ep) { | 155 | static Cube |
| 175 | int a[12]; | 156 | apply_move_cubearray(Move m, Cube cube, PieceFilter f) |
| 176 | epose_int_to_array(ep, a); | 157 | { |
| 177 | apply_move_ep_array(move, a); | 158 | /*init_moves();*/ |
| 178 | return epose_array_to_int(a); | ||
| 179 | } | ||
| 180 | 159 | ||
| 181 | int apply_move_eposs_int(int move, int ep) { | 160 | CubeArray m_arr = { |
| 182 | int a[12]; | 161 | edge_cycle[m], |
| 183 | eposs_int_to_array(ep, a); | 162 | eofb_flipped[m], |
| 184 | apply_move_ep_array(move, a); | 163 | eorl_flipped[m], |
| 185 | return eposs_array_to_int(a); | 164 | eoud_flipped[m], |
| 186 | } | 165 | corner_cycle[m], |
| 166 | coud_flipped[m], | ||
| 167 | corl_flipped[m], | ||
| 168 | cofb_flipped[m], | ||
| 169 | center_cycle[m] | ||
| 170 | }; | ||
| 187 | 171 | ||
| 188 | int apply_move_eposm_int(int move, int ep) { | 172 | return move_via_arrays(&m_arr, cube, f); |
| 189 | int a[12]; | ||
| 190 | eposm_int_to_array(ep, a); | ||
| 191 | apply_move_ep_array(move, a); | ||
| 192 | return eposm_array_to_int(a); | ||
| 193 | } | 173 | } |
| 194 | 174 | ||
| 195 | int apply_move_epe_int(int move, int ep) { | 175 | /* Public functions **********************************************************/ |
| 196 | int a[12]; | ||
| 197 | epe_int_to_array(ep, a); | ||
| 198 | apply_move_ep_array(move, a); | ||
| 199 | return epe_array_to_int(a); | ||
| 200 | } | ||
| 201 | 176 | ||
| 202 | int apply_move_eps_int(int move, int ep) { | 177 | Cube |
| 203 | int a[12]; | 178 | apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a) |
| 204 | eps_int_to_array(ep, a); | 179 | { |
| 205 | apply_move_ep_array(move, a); | 180 | Cube ret = {0}; |
| 206 | return eps_array_to_int(a); | 181 | int i; |
| 207 | } | ||
| 208 | 182 | ||
| 209 | int apply_move_epm_int(int move, int ep) { | 183 | for (i = 0; i < alg->len; i++) |
| 210 | int a[12]; | 184 | if (alg->inv[i]) |
| 211 | epm_int_to_array(ep, a); | 185 | ret = a ? apply_move(alg->move[i], ret) : |
| 212 | apply_move_ep_array(move, a); | 186 | apply_move_cubearray(alg->move[i], ret, f); |
| 213 | return epm_array_to_int(a); | ||
| 214 | } | ||
| 215 | 187 | ||
| 216 | int apply_move_emslices_int(int move, int e) { | 188 | ret = compose_filtered(c, inverse_cube(ret), f); |
| 217 | int a[12]; | ||
| 218 | emslices_int_to_array(e, a); | ||
| 219 | apply_move_ep_array(move, a); | ||
| 220 | return emslices_array_to_int(a); | ||
| 221 | } | ||
| 222 | 189 | ||
| 223 | int apply_move_cp_int(int move, int cp) { | 190 | for (i = 0; i < alg->len; i++) |
| 224 | int a[8]; | 191 | if (!alg->inv[i]) |
| 225 | cp_int_to_array(cp, a); | 192 | ret = a ? apply_move(alg->move[i], ret) : |
| 226 | apply_move_cp_array(move, a); | 193 | apply_move_cubearray(alg->move[i], ret, f); |
| 227 | return cp_array_to_int(a); | ||
| 228 | } | ||
| 229 | 194 | ||
| 230 | int apply_move_eofb_int(int move, int eo) { | 195 | return ret; |
| 231 | int a[12]; | ||
| 232 | eo_11bits_to_array(eo, a); | ||
| 233 | apply_move_ep_array(move, a); | ||
| 234 | /* Change edge orientation */ | ||
| 235 | if (move == F || move == F3) { | ||
| 236 | a[UF] = 1 - a[UF]; | ||
| 237 | a[DF] = 1 - a[DF]; | ||
| 238 | a[FR] = 1 - a[FR]; | ||
| 239 | a[FL] = 1 - a[FL]; | ||
| 240 | } | ||
| 241 | if (move == B || move == B3) { | ||
| 242 | a[UB] = 1 - a[UB]; | ||
| 243 | a[DB] = 1 - a[DB]; | ||
| 244 | a[BL] = 1 - a[BL]; | ||
| 245 | a[BR] = 1 - a[BR]; | ||
| 246 | } | ||
| 247 | return eo_array_to_11bits(a); | ||
| 248 | } | 196 | } |
| 249 | 197 | ||
| 250 | int apply_move_eorl_int(int move, int eo) { | 198 | Cube |
| 251 | int a[12]; | 199 | apply_alg(Alg *alg, Cube cube) |
| 252 | eo_11bits_to_array(eo, a); | 200 | { |
| 253 | apply_move_ep_array(move, a); | 201 | return apply_alg_generic(alg, cube, pf_all, true); |
| 254 | /* Change edge orientation */ | ||
| 255 | if (move == R || move == R3) { | ||
| 256 | a[UR] = 1 - a[UR]; | ||
| 257 | a[DR] = 1 - a[DR]; | ||
| 258 | a[FR] = 1 - a[FR]; | ||
| 259 | a[BR] = 1 - a[BR]; | ||
| 260 | } | ||
| 261 | if (move == L || move == L3) { | ||
| 262 | a[UL] = 1 - a[UL]; | ||
| 263 | a[DL] = 1 - a[DL]; | ||
| 264 | a[FL] = 1 - a[FL]; | ||
| 265 | a[BL] = 1 - a[BL]; | ||
| 266 | } | ||
| 267 | return eo_array_to_11bits(a); | ||
| 268 | } | 202 | } |
| 269 | 203 | ||
| 270 | int apply_move_eoud_int(int move, int eo) { | 204 | Cube |
| 271 | int a[12]; | 205 | apply_move(Move m, Cube cube) |
| 272 | eo_11bits_to_array(eo, a); | 206 | { |
| 273 | apply_move_ep_array(move, a); | 207 | /*init_moves();*/ |
| 274 | /* Change edge orientation */ | ||
| 275 | if (move == U || move == U3) { | ||
| 276 | a[UF] = 1 - a[UF]; | ||
| 277 | a[UL] = 1 - a[UL]; | ||
| 278 | a[UB] = 1 - a[UB]; | ||
| 279 | a[UR] = 1 - a[UR]; | ||
| 280 | } | ||
| 281 | if (move == D || move == D3) { | ||
| 282 | a[DF] = 1 - a[DF]; | ||
| 283 | a[DL] = 1 - a[DL]; | ||
| 284 | a[DB] = 1 - a[DB]; | ||
| 285 | a[DR] = 1 - a[DR]; | ||
| 286 | } | ||
| 287 | return eo_array_to_11bits(a); | ||
| 288 | } | ||
| 289 | 208 | ||
| 290 | int apply_move_coud_int(int move, int co) { | 209 | return (Cube) { |
| 291 | int a[8]; | 210 | .epose = epose_mtable[m][cube.epose], |
| 292 | co_7trits_to_array(co, a); | 211 | .eposs = eposs_mtable[m][cube.eposs], |
| 293 | apply_move_cp_array(move, a); | 212 | .eposm = eposm_mtable[m][cube.eposm], |
| 294 | /* Change corner orientation */ | 213 | .eofb = eofb_mtable[m][cube.eofb], |
| 295 | if (move == R || move == R3) { | 214 | .eorl = eorl_mtable[m][cube.eorl], |
| 296 | a[UFR] = (a[UFR] + 2) % 3; | 215 | .eoud = eoud_mtable[m][cube.eoud], |
| 297 | a[UBR] = (a[UBR] + 1) % 3; | 216 | .coud = coud_mtable[m][cube.coud], |
| 298 | a[DBR] = (a[DBR] + 2) % 3; | 217 | .cofb = cofb_mtable[m][cube.cofb], |
| 299 | a[DFR] = (a[DFR] + 1) % 3; | 218 | .corl = corl_mtable[m][cube.corl], |
| 300 | } | 219 | .cp = cp_mtable[m][cube.cp], |
| 301 | if (move == L || move == L3) { | 220 | .cpos = cpos_mtable[m][cube.cpos] |
| 302 | a[UBL] = (a[UBL] + 2) % 3; | 221 | }; |
| 303 | a[UFL] = (a[UFL] + 1) % 3; | ||
| 304 | a[DFL] = (a[DFL] + 2) % 3; | ||
| 305 | a[DBL] = (a[DBL] + 1) % 3; | ||
| 306 | } | ||
| 307 | if (move == F || move == F3) { | ||
| 308 | a[UFL] = (a[UFL] + 2) % 3; | ||
| 309 | a[UFR] = (a[UFR] + 1) % 3; | ||
| 310 | a[DFR] = (a[DFR] + 2) % 3; | ||
| 311 | a[DFL] = (a[DFL] + 1) % 3; | ||
| 312 | } | ||
| 313 | if (move == B || move == B3) { | ||
| 314 | a[UBR] = (a[UBR] + 2) % 3; | ||
| 315 | a[UBL] = (a[UBL] + 1) % 3; | ||
| 316 | a[DBL] = (a[DBL] + 2) % 3; | ||
| 317 | a[DBR] = (a[DBR] + 1) % 3; | ||
| 318 | } | ||
| 319 | return co_array_to_7trits(a); | ||
| 320 | } | 222 | } |
| 321 | 223 | ||
| 322 | int apply_move_cofb_int(int move, int co) { | 224 | static bool |
| 323 | int a[8]; | 225 | read_mtables_file() |
| 324 | co_7trits_to_array(co, a); | 226 | { |
| 325 | apply_move_cp_array(move, a); | 227 | init_env(); |
| 326 | /* Change corner orientation */ | ||
| 327 | if (move == R || move == R3) { | ||
| 328 | a[UFR] = (a[UFR] + 1) % 3; | ||
| 329 | a[UBR] = (a[UBR] + 2) % 3; | ||
| 330 | a[DBR] = (a[DBR] + 1) % 3; | ||
| 331 | a[DFR] = (a[DFR] + 2) % 3; | ||
| 332 | } | ||
| 333 | if (move == L || move == L3) { | ||
| 334 | a[UBL] = (a[UBL] + 1) % 3; | ||
| 335 | a[UFL] = (a[UFL] + 2) % 3; | ||
| 336 | a[DFL] = (a[DFL] + 1) % 3; | ||
| 337 | a[DBL] = (a[DBL] + 2) % 3; | ||
| 338 | } | ||
| 339 | if (move == U || move == U3) { | ||
| 340 | a[UFL] = (a[UFL] + 1) % 3; | ||
| 341 | a[UFR] = (a[UFR] + 2) % 3; | ||
| 342 | a[UBL] = (a[UBL] + 2) % 3; | ||
| 343 | a[UBR] = (a[UBR] + 1) % 3; | ||
| 344 | } | ||
| 345 | if (move == D || move == D3) { | ||
| 346 | a[DFL] = (a[DFL] + 2) % 3; | ||
| 347 | a[DFR] = (a[DFR] + 1) % 3; | ||
| 348 | a[DBL] = (a[DBL] + 1) % 3; | ||
| 349 | a[DBR] = (a[DBR] + 2) % 3; | ||
| 350 | } | ||
| 351 | return co_array_to_7trits(a); | ||
| 352 | } | ||
| 353 | 228 | ||
| 354 | int apply_move_corl_int(int move, int co) { | 229 | FILE *f; |
| 355 | int a[8]; | 230 | char fname[strlen(tabledir)+20]; |
| 356 | co_7trits_to_array(co, a); | 231 | int m, b = sizeof(int); |
| 357 | apply_move_cp_array(move, a); | 232 | bool r = true; |
| 358 | /* Change corner orientation */ | ||
| 359 | if (move == F || move == F3) { | ||
| 360 | a[UFR] = (a[UFR] + 2) % 3; | ||
| 361 | a[UFL] = (a[UFL] + 1) % 3; | ||
| 362 | a[DFL] = (a[DFL] + 2) % 3; | ||
| 363 | a[DFR] = (a[DFR] + 1) % 3; | ||
| 364 | } | ||
| 365 | if (move == B || move == B3) { | ||
| 366 | a[UBL] = (a[UBL] + 2) % 3; | ||
| 367 | a[UBR] = (a[UBR] + 1) % 3; | ||
| 368 | a[DBR] = (a[DBR] + 2) % 3; | ||
| 369 | a[DBL] = (a[DBL] + 1) % 3; | ||
| 370 | } | ||
| 371 | if (move == U || move == U3) { | ||
| 372 | a[UFL] = (a[UFL] + 2) % 3; | ||
| 373 | a[UFR] = (a[UFR] + 1) % 3; | ||
| 374 | a[UBL] = (a[UBL] + 1) % 3; | ||
| 375 | a[UBR] = (a[UBR] + 2) % 3; | ||
| 376 | } | ||
| 377 | if (move == D || move == D3) { | ||
| 378 | a[DFL] = (a[DFL] + 1) % 3; | ||
| 379 | a[DFR] = (a[DFR] + 2) % 3; | ||
| 380 | a[DBL] = (a[DBL] + 2) % 3; | ||
| 381 | a[DBR] = (a[DBR] + 1) % 3; | ||
| 382 | } | ||
| 383 | return co_array_to_7trits(a); | ||
| 384 | } | ||
| 385 | |||
| 386 | 233 | ||
| 234 | /* Table sizes, used for reading and writing files */ | ||
| 235 | uint64_t me[11] = { | ||
| 236 | [0] = FACTORIAL12/FACTORIAL8, | ||
| 237 | [1] = FACTORIAL12/FACTORIAL8, | ||
| 238 | [2] = FACTORIAL12/FACTORIAL8, | ||
| 239 | [3] = POW2TO11, | ||
| 240 | [4] = POW2TO11, | ||
| 241 | [5] = POW2TO11, | ||
| 242 | [6] = FACTORIAL8, | ||
| 243 | [7] = POW3TO7, | ||
| 244 | [8] = POW3TO7, | ||
| 245 | [9] = POW3TO7, | ||
| 246 | [10] = FACTORIAL6 | ||
| 247 | }; | ||
| 387 | 248 | ||
| 388 | /* Initialize transition tables */ | 249 | strcpy(fname, tabledir); |
| 250 | strcat(fname, "/mtables"); | ||
| 389 | 251 | ||
| 390 | void init_epud_transition_table() { | 252 | if ((f = fopen(fname, "rb")) == NULL) |
| 391 | for (int i = 0; i < factorial8; i++) | 253 | return false; |
| 392 | for (int j = 0; j < 19; j++) | ||
| 393 | if (move_mask_drud & (1 << j)) | ||
| 394 | epud_transition_table[i][j] = apply_move_epud_int(j, i); | ||
| 395 | } | ||
| 396 | 254 | ||
| 397 | void init_eprl_transition_table() { | 255 | for (m = 0; m < NMOVES; m++) { |
| 398 | for (int i = 0; i < factorial8; i++) | 256 | r = r && fread(epose_mtable[m], b, me[0], f) == me[0]; |
| 399 | for (int j = 0; j < 19; j++) | 257 | r = r && fread(eposs_mtable[m], b, me[1], f) == me[1]; |
| 400 | if (move_mask_drrl & (1 << j)) | 258 | r = r && fread(eposm_mtable[m], b, me[2], f) == me[2]; |
| 401 | eprl_transition_table[i][j] = apply_move_eprl_int(j, i); | 259 | r = r && fread(eofb_mtable[m], b, me[3], f) == me[3]; |
| 402 | } | 260 | r = r && fread(eorl_mtable[m], b, me[4], f) == me[4]; |
| 261 | r = r && fread(eoud_mtable[m], b, me[5], f) == me[5]; | ||
| 262 | r = r && fread(cp_mtable[m], b, me[6], f) == me[6]; | ||
| 263 | r = r && fread(coud_mtable[m], b, me[7], f) == me[7]; | ||
| 264 | r = r && fread(corl_mtable[m], b, me[8], f) == me[8]; | ||
| 265 | r = r && fread(cofb_mtable[m], b, me[9], f) == me[9]; | ||
| 266 | r = r && fread(cpos_mtable[m], b, me[10], f) == me[10]; | ||
| 267 | } | ||
| 403 | 268 | ||
| 404 | void init_epfb_transition_table() { | 269 | fclose(f); |
| 405 | for (int i = 0; i < factorial8; i++) | 270 | return r; |
| 406 | for (int j = 0; j < 19; j++) | ||
| 407 | if (move_mask_drfb & (1 << j)) | ||
| 408 | epfb_transition_table[i][j] = apply_move_epfb_int(j, i); | ||
| 409 | } | 271 | } |
| 410 | 272 | ||
| 411 | void init_epose_transition_table() { | 273 | static bool |
| 412 | for (int i = 0; i < binom12on4; i++) | 274 | write_mtables_file() |
| 413 | for (int j = 0; j < 19; j++) | 275 | { |
| 414 | epose_transition_table[i][j] = apply_move_epose_int(j, i); | 276 | init_env(); |
| 415 | } | ||
| 416 | 277 | ||
| 417 | void init_eposs_transition_table() { | 278 | FILE *f; |
| 418 | for (int i = 0; i < binom12on4; i++) | 279 | char fname[strlen(tabledir)+20]; |
| 419 | for (int j = 0; j < 19; j++) | 280 | int m, b = sizeof(int); |
| 420 | eposs_transition_table[i][j] = apply_move_eposs_int(j, i); | 281 | bool r = true; |
| 421 | } | ||
| 422 | 282 | ||
| 423 | void init_eposm_transition_table() { | 283 | /* Table sizes, used for reading and writing files */ |
| 424 | for (int i = 0; i < binom12on4; i++) | 284 | uint64_t me[11] = { |
| 425 | for (int j = 0; j < 19; j++) | 285 | [0] = FACTORIAL12/FACTORIAL8, |
| 426 | eposm_transition_table[i][j] = apply_move_eposm_int(j, i); | 286 | [1] = FACTORIAL12/FACTORIAL8, |
| 427 | } | 287 | [2] = FACTORIAL12/FACTORIAL8, |
| 288 | [3] = POW2TO11, | ||
| 289 | [4] = POW2TO11, | ||
| 290 | [5] = POW2TO11, | ||
| 291 | [6] = FACTORIAL8, | ||
| 292 | [7] = POW3TO7, | ||
| 293 | [8] = POW3TO7, | ||
| 294 | [9] = POW3TO7, | ||
| 295 | [10] = FACTORIAL6 | ||
| 296 | }; | ||
| 428 | 297 | ||
| 429 | void init_epe_transition_table() { | 298 | strcpy(fname, tabledir); |
| 430 | for (int i = 0; i < factorial4; i++) { | 299 | strcat(fname, "/mtables"); |
| 431 | for (int j = 0; j < 19; j++) | ||
| 432 | if (move_mask_drud & (1 << j)) | ||
| 433 | epe_transition_table[i][j] = apply_move_epe_int(j, i); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | 300 | ||
| 437 | void init_eps_transition_table() { | 301 | if ((f = fopen(fname, "wb")) == NULL) |
| 438 | for (int i = 0; i < factorial4; i++) { | 302 | return false; |
| 439 | for (int j = 0; j < 19; j++) | ||
| 440 | if (move_mask_drfb & (1 << j)) | ||
| 441 | eps_transition_table[i][j] = apply_move_eps_int(j, i); | ||
| 442 | } | ||
| 443 | } | ||
| 444 | 303 | ||
| 445 | void init_epm_transition_table() { | 304 | for (m = 0; m < NMOVES; m++) { |
| 446 | for (int i = 0; i < factorial4; i++) { | 305 | r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0]; |
| 447 | for (int j = 0; j < 19; j++) | 306 | r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1]; |
| 448 | if (move_mask_drrl & (1 << j)) | 307 | r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2]; |
| 449 | epm_transition_table[i][j] = apply_move_epm_int(j, i); | 308 | r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3]; |
| 450 | } | 309 | r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4]; |
| 451 | } | 310 | r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5]; |
| 311 | r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6]; | ||
| 312 | r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7]; | ||
| 313 | r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8]; | ||
| 314 | r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9]; | ||
| 315 | r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10]; | ||
| 316 | } | ||
| 452 | 317 | ||
| 453 | void init_emslices_transition_table() { | 318 | fclose(f); |
| 454 | for (int i = 0; i < binom12on4*binom8on4; i++) { | 319 | return r; |
| 455 | for (int j = 0; j < 19; j++) | ||
| 456 | emslices_transition_table[i][j] = apply_move_emslices_int(j, i); | ||
| 457 | } | ||
| 458 | } | 320 | } |
| 459 | 321 | ||
| 460 | void init_cp_transition_table() { | 322 | bool |
| 461 | for (int i = 0; i < factorial8; i++) | 323 | commute(Move m1, Move m2) |
| 462 | for (int j = 0; j < 19; j++) | 324 | { |
| 463 | cp_transition_table[i][j] = apply_move_cp_int(j, i); | 325 | static bool initialized = false; |
| 464 | } | 326 | static bool commute_aux[NMOVES][NMOVES]; |
| 465 | 327 | ||
| 466 | void init_eofb_transition_table() { | 328 | if (!initialized) { |
| 467 | for (int i = 0; i < pow2to11; i++) | 329 | Cube c1, c2; |
| 468 | for (int j = 0; j < 19; j++) | 330 | int i, j; |
| 469 | eofb_transition_table[i][j] = apply_move_eofb_int(j, i); | ||
| 470 | } | ||
| 471 | 331 | ||
| 472 | void init_eorl_transition_table() { | 332 | for (i = 0; i < NMOVES; i++) { |
| 473 | for (int i = 0; i < pow2to11; i++) | 333 | for (j = 0; j < NMOVES; j++) { |
| 474 | for (int j = 0; j < 19; j++) | 334 | c1 = apply_move(i, apply_move(j, (Cube){0})); |
| 475 | eorl_transition_table[i][j] = apply_move_eorl_int(j, i); | 335 | c2 = apply_move(j, apply_move(i, (Cube){0})); |
| 476 | } | 336 | commute_aux[i][j] = equal(c1, c2) && i && j; |
| 337 | } | ||
| 338 | } | ||
| 477 | 339 | ||
| 478 | void init_eoud_transition_table() { | 340 | initialized = true; |
| 479 | for (int i = 0; i < pow2to11; i++) | 341 | } |
| 480 | for (int j = 0; j < 19; j++) | ||
| 481 | eoud_transition_table[i][j] = apply_move_eoud_int(j, i); | ||
| 482 | } | ||
| 483 | 342 | ||
| 484 | void init_coud_transition_table() { | 343 | return commute_aux[m1][m2]; |
| 485 | for (int i = 0; i < pow3to7; i++) | ||
| 486 | for (int j = 0; j < 19; j++ ) | ||
| 487 | coud_transition_table[i][j] = apply_move_coud_int(j, i); | ||
| 488 | } | 344 | } |
| 489 | 345 | ||
| 490 | void init_cofb_transition_table() { | 346 | bool |
| 491 | for (int i = 0; i < pow3to7; i++) | 347 | possible_next(Move m1, Move m2, Move m3) |
| 492 | for (int j = 0; j < 19; j++ ) | 348 | { |
| 493 | cofb_transition_table[i][j] = apply_move_cofb_int(j, i); | 349 | static bool initialized = false; |
| 494 | } | 350 | static bool paux[NMOVES][NMOVES][NMOVES]; |
| 351 | |||
| 352 | if (!initialized) { | ||
| 353 | int i, j, k; | ||
| 354 | bool p, q, c; | ||
| 495 | 355 | ||
| 496 | void init_corl_transition_table() { | 356 | for (i = 0; i < NMOVES; i++) { |
| 497 | for (int i = 0; i < pow3to7; i++) | 357 | for (j = 0; j < NMOVES; j++) { |
| 498 | for (int j = 0; j < 19; j++ ) | 358 | for (k = 0; k < NMOVES; k++) { |
| 499 | corl_transition_table[i][j] = apply_move_corl_int(j, i); | 359 | p = j && base_move(j) == base_move(k); |
| 360 | q = i && base_move(i) == base_move(k); | ||
| 361 | c = commute(i, j); | ||
| 362 | paux[i][j][k] = !(p || (c && q)); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | } | ||
| 366 | |||
| 367 | initialized = true; | ||
| 368 | } | ||
| 369 | |||
| 370 | return paux[m1][m2][m3]; | ||
| 500 | } | 371 | } |
| 501 | 372 | ||
| 502 | void init_transition_table() { | 373 | void |
| 503 | init_epud_transition_table(); | 374 | init_moves() { |
| 504 | init_eprl_transition_table(); | 375 | static bool initialized = false; |
| 505 | init_epfb_transition_table(); | 376 | if (initialized) |
| 506 | init_epose_transition_table(); | 377 | return; |
| 507 | init_eposs_transition_table(); | 378 | initialized = true; |
| 508 | init_eposm_transition_table(); | 379 | |
| 509 | init_epe_transition_table(); | 380 | Cube c; |
| 510 | init_eps_transition_table(); | 381 | CubeArray arrs; |
| 511 | init_epm_transition_table(); | 382 | int i; |
| 512 | init_emslices_transition_table(); | 383 | unsigned int ui; |
| 513 | init_cp_transition_table(); | 384 | Move m; |
| 514 | init_eofb_transition_table(); | 385 | Alg *equiv_alg[NMOVES]; |
| 515 | init_eorl_transition_table(); | 386 | |
| 516 | init_eoud_transition_table(); | 387 | for (i = 0; i < NMOVES; i++) |
| 517 | init_coud_transition_table(); | 388 | equiv_alg[i] = new_alg(equiv_alg_string[i]); |
| 518 | init_cofb_transition_table(); | 389 | |
| 519 | init_corl_transition_table(); | 390 | /* Generate all move cycles and flips; I do this regardless */ |
| 391 | for (i = 0; i < NMOVES; i++) { | ||
| 392 | if (i == U || i == x || i == y) | ||
| 393 | continue; | ||
| 394 | |||
| 395 | c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false); | ||
| 396 | |||
| 397 | arrs = (CubeArray) { | ||
| 398 | edge_cycle[i], | ||
| 399 | eofb_flipped[i], | ||
| 400 | eorl_flipped[i], | ||
| 401 | eoud_flipped[i], | ||
| 402 | corner_cycle[i], | ||
| 403 | coud_flipped[i], | ||
| 404 | corl_flipped[i], | ||
| 405 | cofb_flipped[i], | ||
| 406 | center_cycle[i] | ||
| 407 | }; | ||
| 408 | cube_to_arrays(c, &arrs, pf_all); | ||
| 409 | } | ||
| 410 | |||
| 411 | if (read_mtables_file()) | ||
| 412 | return; | ||
| 413 | |||
| 414 | fprintf(stderr, "Cannot load %s, generating it\n", "mtables"); | ||
| 415 | |||
| 416 | /* Initialize transition tables */ | ||
| 417 | for (m = 0; m < NMOVES; m++) { | ||
| 418 | for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) { | ||
| 419 | c = (Cube){ .epose = ui }; | ||
| 420 | c = apply_move_cubearray(m, c, pf_e); | ||
| 421 | epose_mtable[m][ui] = c.epose; | ||
| 422 | |||
| 423 | c = (Cube){ .eposs = ui }; | ||
| 424 | c = apply_move_cubearray(m, c, pf_s); | ||
| 425 | eposs_mtable[m][ui] = c.eposs; | ||
| 426 | |||
| 427 | c = (Cube){ .eposm = ui }; | ||
| 428 | c = apply_move_cubearray(m, c, pf_m); | ||
| 429 | eposm_mtable[m][ui] = c.eposm; | ||
| 430 | } | ||
| 431 | for (ui = 0; ui < POW2TO11; ui++ ) { | ||
| 432 | c = (Cube){ .eofb = ui }; | ||
| 433 | c = apply_move_cubearray(m, c, pf_eo); | ||
| 434 | eofb_mtable[m][ui] = c.eofb; | ||
| 435 | |||
| 436 | c = (Cube){ .eorl = ui }; | ||
| 437 | c = apply_move_cubearray(m, c, pf_eo); | ||
| 438 | eorl_mtable[m][ui] = c.eorl; | ||
| 439 | |||
| 440 | c = (Cube){ .eoud = ui }; | ||
| 441 | c = apply_move_cubearray(m, c, pf_eo); | ||
| 442 | eoud_mtable[m][ui] = c.eoud; | ||
| 443 | } | ||
| 444 | for (ui = 0; ui < POW3TO7; ui++) { | ||
| 445 | c = (Cube){ .coud = ui }; | ||
| 446 | c = apply_move_cubearray(m, c, pf_co); | ||
| 447 | coud_mtable[m][ui] = c.coud; | ||
| 448 | |||
| 449 | c = (Cube){ .corl = ui }; | ||
| 450 | c = apply_move_cubearray(m, c, pf_co); | ||
| 451 | corl_mtable[m][ui] = c.corl; | ||
| 452 | |||
| 453 | c = (Cube){ .cofb = ui }; | ||
| 454 | c = apply_move_cubearray(m, c, pf_co); | ||
| 455 | cofb_mtable[m][ui] = c.cofb; | ||
| 456 | } | ||
| 457 | for (ui = 0; ui < FACTORIAL8; ui++) { | ||
| 458 | c = (Cube){ .cp = ui }; | ||
| 459 | c = apply_move_cubearray(m, c, pf_cp); | ||
| 460 | cp_mtable[m][ui] = c.cp; | ||
| 461 | } | ||
| 462 | for (ui = 0; ui < FACTORIAL6; ui++) { | ||
| 463 | c = (Cube){ .cpos = ui }; | ||
| 464 | c = apply_move_cubearray(m, c, pf_cpos); | ||
| 465 | cpos_mtable[m][ui] = c.cpos; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | |||
| 469 | if (!write_mtables_file()) | ||
| 470 | fprintf(stderr, "Error writing mtables\n"); | ||
| 471 | |||
| 472 | for (i = 0; i < NMOVES; i++) | ||
| 473 | free_alg(equiv_alg[i]); | ||
| 520 | } | 474 | } |
| 521 | 475 | ||
