nissy-nx

A Rubik's cube optimal solver
git clone https://git.tronto.net/nissy-nx
Download | Log | Files | Refs | README | LICENSE

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