trans.c (4576B)
1 #define TRANS_C 2 3 #include "trans.h" 4 5 /* Local functions ***********************************************************/ 6 7 /* Tables and other data *****************************************************/ 8 9 static Cube mirror_cube = { 10 .ep = { [UF] = UF, [UL] = UR, [UB] = UB, [UR] = UL, 11 [DF] = DF, [DL] = DR, [DB] = DB, [DR] = DL, 12 [FR] = FL, [FL] = FR, [BL] = BR, [BR] = BL }, 13 .cp = { [UFR] = UFL, [UFL] = UFR, [UBL] = UBR, [UBR] = UBL, 14 [DFR] = DFL, [DFL] = DFR, [DBL] = DBR, [DBR] = DBL }, 15 .xp = { [U_center] = U_center, [D_center] = D_center, 16 [R_center] = L_center, [L_center] = R_center, 17 [F_center] = F_center, [B_center] = B_center } 18 }; 19 20 static char rotation_alg_string[100][NROTATIONS] = { 21 [uf] = "", [ur] = "y", [ub] = "y2", [ul] = "y3", 22 [df] = "z2", [dr] = "y z2", [db] = "x2", [dl] = "y3 z2", 23 [rf] = "z3", [rd] = "z3 y", [rb] = "z3 y2", [ru] = "z3 y3", 24 [lf] = "z", [ld] = "z y3", [lb] = "z y2", [lu] = "z y", 25 [fu] = "x y2", [fr] = "x y", [fd] = "x", [fl] = "x y3", 26 [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3", 27 }; 28 29 Alg *rotation_alg_arr[NROTATIONS]; 30 Move moves_ttable[NTRANS][NMOVES]; 31 Trans trans_ttable[NTRANS][NTRANS]; 32 Trans trans_itable[NTRANS]; 33 34 /* Public functions **********************************************************/ 35 36 void 37 apply_trans(Trans t, Cube *cube) 38 { 39 Cube aux; 40 Alg *inv; 41 int i; 42 43 inv = inverse_alg(rotation_alg(t % NROTATIONS)); 44 copy_cube(cube, &aux); 45 make_solved(cube); 46 47 if (t >= NROTATIONS) 48 compose(&mirror_cube, cube); 49 apply_alg(inv, cube); 50 compose(&aux, cube); 51 apply_alg(rotation_alg(t % NROTATIONS), cube); 52 if (t >= NROTATIONS) { 53 compose(&mirror_cube, cube); 54 for (i = 0; i < 8; i++) 55 cube->co[i] = (3 - cube->co[i]) % 3; 56 } 57 58 free_alg(inv); 59 } 60 61 /* 62 Trans 63 inverse_trans(Trans t) 64 { 65 static Trans inverse_trans_aux[NTRANS] = { 66 [uf] = uf, [ur] = ul, [ul] = ur, [ub] = ub, 67 [df] = df, [dr] = dr, [dl] = dl, [db] = db, 68 [rf] = lf, [rd] = bl, [rb] = rb, [ru] = fr, 69 [lf] = rf, [ld] = br, [lb] = lb, [lu] = fl, 70 [fu] = fu, [fr] = ru, [fd] = bu, [fl] = lu, 71 [bu] = fd, [br] = ld, [bd] = bd, [bl] = rd, 72 73 [uf_mirror] = uf_mirror, [ur_mirror] = ur_mirror, 74 [ul_mirror] = ul_mirror, [ub_mirror] = ub_mirror, 75 [df_mirror] = df_mirror, [dr_mirror] = dl_mirror, 76 [dl_mirror] = dr_mirror, [db_mirror] = db_mirror, 77 [rf_mirror] = rf_mirror, [rd_mirror] = br_mirror, 78 [rb_mirror] = lb_mirror, [ru_mirror] = fl_mirror, 79 [lf_mirror] = lf_mirror, [ld_mirror] = bl_mirror, 80 [lb_mirror] = rb_mirror, [lu_mirror] = fr_mirror, 81 [fu_mirror] = fu_mirror, [fr_mirror] = lu_mirror, 82 [fd_mirror] = bu_mirror, [fl_mirror] = ru_mirror, 83 [bu_mirror] = fd_mirror, [br_mirror] = rd_mirror, 84 [bd_mirror] = bd_mirror, [bl_mirror] = ld_mirror 85 }; 86 87 return inverse_trans_aux[t]; 88 } 89 */ 90 91 Trans 92 inverse_trans(Trans t) 93 { 94 return trans_itable[t]; 95 } 96 97 Alg * 98 rotation_alg(Trans i) 99 { 100 return rotation_alg_arr[i % NROTATIONS]; 101 } 102 103 void 104 transform_alg(Trans t, Alg *alg) 105 { 106 int i; 107 108 for (i = 0; i < alg->len; i++) 109 alg->move[i] = transform_move(t, alg->move[i]); 110 } 111 112 Move 113 transform_move(Trans t, Move m) 114 { 115 return moves_ttable[t][m]; 116 } 117 118 Trans 119 transform_trans(Trans t, Trans m) 120 { 121 return trans_ttable[t][m]; 122 } 123 124 void 125 init_trans() { 126 static bool initialized = false; 127 if (initialized) 128 return; 129 initialized = true; 130 131 int i; 132 Alg *nonsym_alg, *nonsym_inv; 133 Cube aux, cube; 134 Move mi, move; 135 Trans t, u, v; 136 137 init_moves(); 138 139 for (i = 0; i < NROTATIONS; i++) 140 rotation_alg_arr[i] = new_alg(rotation_alg_string[i]); 141 142 for (t = 0; t < NTRANS; t++) { 143 for (mi = 0; mi < NMOVES; mi++) { 144 make_solved(&aux); 145 apply_move(mi, &aux); 146 apply_trans(t, &aux); 147 for (move = 0; move < NMOVES; move++) { 148 copy_cube(&aux, &cube); 149 apply_move(inverse_move(move), &cube); 150 if (is_solved(&cube)) { 151 moves_ttable[t][mi] = move; 152 break; 153 } 154 } 155 } 156 } 157 158 nonsym_alg = new_alg("R' U' F"); 159 nonsym_inv = inverse_alg(nonsym_alg); 160 161 for (t = 0; t < NTRANS; t++) { 162 for (u = 0; u < NTRANS; u++) { 163 make_solved(&aux); 164 apply_alg(nonsym_alg, &aux); 165 apply_trans(u, &aux); 166 apply_trans(t, &aux); 167 for (v = 0; v < NTRANS; v++) { 168 copy_cube(&aux, &cube); 169 apply_trans(v, &cube); 170 apply_alg(nonsym_inv, &cube); 171 if (is_solved(&cube)) { 172 /* This is the inverse of the correct 173 value, it will be inverted later */ 174 trans_ttable[t][u] = v; 175 if (v == uf) 176 trans_itable[t] = u; 177 break; 178 } 179 } 180 } 181 } 182 for (t = 0; t < NTRANS; t++) 183 for (u = 0; u < NTRANS; u++) 184 trans_ttable[t][u] = trans_itable[trans_ttable[t][u]]; 185 186 187 free_alg(nonsym_alg); 188 free_alg(nonsym_inv); 189 } 190