nissy-classic

Stable branch of nissy
git clone https://git.tronto.net/nissy-classic
Download | Log | Files | Refs | README | LICENSE

trans.c (10747B)


      1 #include "trans.h"
      2 
      3 /* Local functions ***********************************************************/
      4 
      5 static bool        read_ttables_file(void);
      6 static Cube        rotate_via_compose(Trans r, Cube c, PieceFilter f);
      7 static bool        write_ttables_file(void);
      8 
      9 /* Tables and other data *****************************************************/
     10 
     11 static int              ep_mirror[12] = {
     12 	[UF] = UF, [UL] = UR, [UB] = UB, [UR] = UL,
     13 	[DF] = DF, [DL] = DR, [DB] = DB, [DR] = DL,
     14 	[FR] = FL, [FL] = FR, [BL] = BR, [BR] = BL
     15 };
     16 
     17 static int              cp_mirror[8] = {
     18 	[UFR] = UFL, [UFL] = UFR, [UBL] = UBR, [UBR] = UBL,
     19 	[DFR] = DFL, [DFL] = DFR, [DBL] = DBR, [DBR] = DBL
     20 };
     21 
     22 static int              cpos_mirror[6] = {
     23 	[U_center] = U_center, [D_center] = D_center,
     24 	[R_center] = L_center, [L_center] = R_center,
     25 	[F_center] = F_center, [B_center] = B_center
     26 };
     27 
     28 static char             rotation_alg_string[100][NROTATIONS] = {
     29 	[uf] = "",     [ur] = "y",    [ub] = "y2",    [ul] = "y3",
     30 	[df] = "z2",   [dr] = "y z2", [db] = "x2",    [dl] = "y3 z2",
     31 	[rf] = "z3",   [rd] = "z3 y", [rb] = "z3 y2", [ru] = "z3 y3",
     32 	[lf] = "z",    [ld] = "z y3", [lb] = "z y2",  [lu] = "z y",
     33 	[fu] = "x y2", [fr] = "x y",  [fd] = "x",     [fl] = "x y3",
     34 	[bu] = "x3",   [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3",
     35 };
     36 
     37 static int              epose_source[NTRANS];  /* 0=epose, 1=eposs, 2=eposm */
     38 static int              eposs_source[NTRANS];
     39 static int              eposm_source[NTRANS];
     40 static int              eofb_source[NTRANS];   /* 0=eoud,  1=eorl,  2=eofb  */
     41 static int              eorl_source[NTRANS];
     42 static int              eoud_source[NTRANS];
     43 static int              coud_source[NTRANS];   /* 0=coud,  1=corl,  2=cofb  */
     44 static int              cofb_source[NTRANS];
     45 static int              corl_source[NTRANS];
     46 
     47 int                     epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
     48 int                     eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
     49 int                     eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
     50 int                     eo_ttable[NTRANS][POW2TO11];
     51 int                     cp_ttable[NTRANS][FACTORIAL8];
     52 int                     co_ttable[NTRANS][POW3TO7];
     53 int                     cpos_ttable[NTRANS][FACTORIAL6];
     54 Move                    moves_ttable[NTRANS][NMOVES];
     55 
     56 /* Local functions implementation ********************************************/
     57 
     58 static bool
     59 read_ttables_file(void)
     60 {
     61 	init_env();
     62 
     63 	FILE *f;
     64 	char fname[strlen(tabledir)+20];
     65 	int b = sizeof(int);
     66 	bool r = true;
     67 	Move m;
     68 
     69 	/* Table sizes, used for reading and writing files */
     70 	uint64_t me[11] = {
     71 		[0] = FACTORIAL12/FACTORIAL8,
     72 		[1] = FACTORIAL12/FACTORIAL8,
     73 		[2] = FACTORIAL12/FACTORIAL8,
     74 		[3] = POW2TO11,
     75 		[4] = FACTORIAL8,
     76 		[5] = POW3TO7,
     77 		[6] = FACTORIAL6,
     78 		[7] = NMOVES
     79 	};
     80 
     81 	strcpy(fname, tabledir);
     82 	strcat(fname, "/");
     83 	strcat(fname, "ttables");
     84 
     85 	if ((f = fopen(fname, "rb")) == NULL)
     86 		return false;
     87 
     88 	for (m = 0; m < NTRANS; m++) {
     89 		r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
     90 		r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
     91 		r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
     92 		r = r && fread(eo_ttable[m],    b, me[3], f) == me[3];
     93 		r = r && fread(cp_ttable[m],    b, me[4], f) == me[4];
     94 		r = r && fread(co_ttable[m],    b, me[5], f) == me[5];
     95 		r = r && fread(cpos_ttable[m],  b, me[6], f) == me[6];
     96 		r = r && fread(moves_ttable[m], b, me[7], f) == me[7];
     97 	}
     98 
     99 	fclose(f);
    100 	return r;
    101 }
    102 
    103 static Cube
    104 rotate_via_compose(Trans r, Cube c, PieceFilter f)
    105 {
    106 	static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    107 	static int zero8[8]   = { 0, 0, 0, 0, 0, 0, 0, 0 };
    108 	static CubeArray ma = {
    109 		.ep   = ep_mirror,
    110 		.eofb = zero12,
    111 		.eorl = zero12,
    112 		.eoud = zero12,
    113 		.cp   = cp_mirror,
    114 		.coud = zero8,
    115 		.corl = zero8,
    116 		.cofb = zero8,
    117 		.cpos = cpos_mirror
    118 	};
    119 
    120 	Alg *inv = inverse_alg(rotation_alg(r));
    121 	Cube ret = {0};
    122 
    123 	if (r >= NROTATIONS)
    124 		ret = move_via_arrays(&ma, ret, f);
    125 	ret = apply_alg_generic(inv, ret, f, true);
    126 
    127 	ret = compose_filtered(c, ret, f);
    128 
    129 	ret = apply_alg_generic(rotation_alg(r), ret, f, true);
    130 	if (r >= NROTATIONS)
    131 		ret = move_via_arrays(&ma, ret, f);
    132 
    133 	free_alg(inv);
    134 	return ret;
    135 }
    136 
    137 static bool
    138 write_ttables_file(void)
    139 {
    140 	init_env();
    141 
    142 	FILE *f;
    143 	char fname[strlen(tabledir)+20];
    144 	bool r = true;
    145 	int b = sizeof(int);
    146 	Move m;
    147 
    148 	/* Table sizes, used for reading and writing files */
    149 	uint64_t me[11] = {
    150 		[0] = FACTORIAL12/FACTORIAL8,
    151 		[1] = FACTORIAL12/FACTORIAL8,
    152 		[2] = FACTORIAL12/FACTORIAL8,
    153 		[3] = POW2TO11,
    154 		[4] = FACTORIAL8,
    155 		[5] = POW3TO7,
    156 		[6] = FACTORIAL6,
    157 		[7] = NMOVES
    158 	};
    159 
    160 	strcpy(fname, tabledir);
    161 	strcat(fname, "/ttables");
    162 
    163 	if ((f = fopen(fname, "wb")) == NULL)
    164 		return false;
    165 
    166 	for (m = 0; m < NTRANS; m++) {
    167 		r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
    168 		r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
    169 		r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
    170 		r = r && fwrite(eo_ttable[m],    b, me[3], f) == me[3];
    171 		r = r && fwrite(cp_ttable[m],    b, me[4], f) == me[4];
    172 		r = r && fwrite(co_ttable[m],    b, me[5], f) == me[5];
    173 		r = r && fwrite(cpos_ttable[m],  b, me[6], f) == me[6];
    174 		r = r && fwrite(moves_ttable[m], b, me[7], f) == me[7];
    175 	}
    176 
    177 	fclose(f);
    178 	return r;
    179 }
    180 
    181 /* Public functions **********************************************************/
    182 
    183 Cube
    184 apply_trans(Trans t, Cube cube)
    185 {
    186 	/*init_trans();*/
    187 
    188 	int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
    189 	int aux_eo[3]   = { cube.eoud,  cube.eorl,  cube.eofb  };
    190 	int aux_co[3]   = { cube.coud,  cube.corl,  cube.cofb  };
    191 
    192 	return (Cube) {
    193 		.epose = epose_ttable[t][aux_epos[epose_source[t]]],
    194 		.eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
    195 		.eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
    196 		.eofb  = eo_ttable[t][aux_eo[eofb_source[t]]],
    197 		.eorl  = eo_ttable[t][aux_eo[eorl_source[t]]],
    198 		.eoud  = eo_ttable[t][aux_eo[eoud_source[t]]],
    199 		.coud  = co_ttable[t][aux_co[coud_source[t]]],
    200 		.corl  = co_ttable[t][aux_co[corl_source[t]]],
    201 		.cofb  = co_ttable[t][aux_co[cofb_source[t]]],
    202 		.cp    = cp_ttable[t][cube.cp],
    203 		.cpos  = cpos_ttable[t][cube.cpos]
    204 	};
    205 }
    206 
    207 Trans
    208 inverse_trans(Trans t)
    209 {
    210 	static Trans inverse_trans_aux[NTRANS] = {
    211 		[uf] = uf, [ur] = ul, [ul] = ur, [ub] = ub,
    212 		[df] = df, [dr] = dr, [dl] = dl, [db] = db,
    213 		[rf] = lf, [rd] = bl, [rb] = rb, [ru] = fr,
    214 		[lf] = rf, [ld] = br, [lb] = lb, [lu] = fl,
    215 		[fu] = fu, [fr] = ru, [fd] = bu, [fl] = lu,
    216 		[bu] = fd, [br] = ld, [bd] = bd, [bl] = rd,
    217 
    218 		[uf_mirror] = uf_mirror, [ur_mirror] = ur_mirror,
    219 		[ul_mirror] = ul_mirror, [ub_mirror] = ub_mirror,
    220 		[df_mirror] = df_mirror, [dr_mirror] = dl_mirror,
    221 		[dl_mirror] = dr_mirror, [db_mirror] = db_mirror,
    222 		[rf_mirror] = rf_mirror, [rd_mirror] = br_mirror,
    223 		[rb_mirror] = lb_mirror, [ru_mirror] = fl_mirror,
    224 		[lf_mirror] = lf_mirror, [ld_mirror] = bl_mirror,
    225 		[lb_mirror] = rb_mirror, [lu_mirror] = fr_mirror,
    226 		[fu_mirror] = fu_mirror, [fr_mirror] = lu_mirror,
    227 		[fd_mirror] = bu_mirror, [fl_mirror] = ru_mirror,
    228 		[bu_mirror] = fd_mirror, [br_mirror] = rd_mirror,
    229 		[bd_mirror] = bd_mirror, [bl_mirror] = ld_mirror
    230 	};
    231 
    232 	return inverse_trans_aux[t];
    233 }
    234 
    235 Alg *
    236 rotation_alg(Trans t)
    237 {
    238 	int i;
    239 
    240 	static Alg *rotation_alg_arr[NROTATIONS];
    241 	static bool initialized = false;
    242 
    243 	if (!initialized) {
    244 		for (i = 0; i < NROTATIONS; i++)
    245 			rotation_alg_arr[i] = new_alg(rotation_alg_string[i]);
    246 
    247 		initialized = true;
    248 	}
    249 
    250 	return rotation_alg_arr[t % NROTATIONS];
    251 }
    252 
    253 void
    254 transform_alg(Trans t, Alg *alg)
    255 {
    256 	int i;
    257 
    258 	/*init_trans();*/
    259 	
    260 	for (i = 0; i < alg->len; i++)
    261 		alg->move[i] = moves_ttable[t][alg->move[i]];
    262 }
    263 
    264 void
    265 init_trans(void)
    266 {
    267 	static bool initialized = false;
    268 	if (initialized)
    269 		return;
    270 	initialized = true;
    271 
    272 	init_moves();
    273 
    274 	Cube aux, cube, c[3];
    275 	CubeArray epcp;
    276 	int i, eparr[12], eoarr[12], cparr[8], coarr[8];
    277 	unsigned int ui;
    278 	Move mi, move;
    279 	Trans m;
    280 
    281 	/* Compute sources */
    282 	for (i = 0; i < NTRANS; i++) {
    283 		cube = apply_alg(rotation_alg(i), (Cube){0});
    284 
    285 		epose_source[i] = edge_slice(what_edge_at(cube, FR));
    286 		eposs_source[i] = edge_slice(what_edge_at(cube, UR));
    287 		eposm_source[i] = edge_slice(what_edge_at(cube, UF));
    288 		eofb_source[i]  = what_center_at(cube, F_center)/2;
    289 		eorl_source[i]  = what_center_at(cube, R_center)/2;
    290 		eoud_source[i]  = what_center_at(cube, U_center)/2;
    291 		coud_source[i]  = what_center_at(cube, U_center)/2;
    292 		cofb_source[i]  = what_center_at(cube, F_center)/2;
    293 		corl_source[i]  = what_center_at(cube, R_center)/2;
    294 	}
    295 
    296 	if (read_ttables_file())
    297 		return;
    298 
    299 	fprintf(stderr, "Cannot load %s, generating it\n", "ttables"); 
    300 
    301 	/* Initialize tables */
    302 	for (m = 0; m < NTRANS; m++) {
    303 		epcp = (CubeArray){ .ep = eparr, .cp = cparr };
    304 		cube = apply_alg(rotation_alg(m), (Cube){0});
    305 		cube_to_arrays(cube, &epcp, pf_epcp);
    306 		if (m >= NROTATIONS) {
    307 			apply_permutation(ep_mirror, eparr, 12);
    308 			apply_permutation(cp_mirror, cparr,  8);
    309 		}
    310 
    311 		for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
    312 			c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
    313 			c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
    314 			c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
    315 
    316 			cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
    317 			epose_ttable[m][ui] = cube.epose;
    318 
    319 			cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
    320 			eposs_ttable[m][ui] = cube.eposs;
    321 
    322 			cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
    323 			eposm_ttable[m][ui] = cube.eposm;
    324 		}
    325 		for (ui = 0; ui < POW2TO11; ui++ ) {
    326 			int_to_sum_zero_array(ui, 2, 12, eoarr);
    327 			apply_permutation(eparr, eoarr, 12);
    328 			eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
    329 		}
    330 		for (ui = 0; ui < POW3TO7; ui++) {
    331 			int_to_sum_zero_array(ui, 3, 8, coarr);
    332 			apply_permutation(cparr, coarr, 8);
    333 			co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
    334 			if (m >= NROTATIONS)
    335 				co_ttable[m][ui] =
    336 					invert_digits(co_ttable[m][ui], 3, 7);
    337 		}
    338 		for (ui = 0; ui < FACTORIAL8; ui++) {
    339 			cube = (Cube){ .cp = ui };
    340 			cube = rotate_via_compose(m, cube, pf_cp);
    341 			cp_ttable[m][ui] = cube.cp;
    342 		}
    343 		for (ui = 0; ui < FACTORIAL6; ui++) {
    344 			cube = (Cube){ .cpos = ui };
    345 			cube = rotate_via_compose(m, cube, pf_cpos);
    346 			cpos_ttable[m][ui] = cube.cpos;
    347 		}
    348 		for (mi = 0; mi < NMOVES; mi++) {
    349 			/* Old version:
    350 			 *
    351 			aux = apply_trans(m, apply_move(mi, (Cube){0}));
    352 			for (move = 0; move < NMOVES; move++) {
    353 				cube = apply_move(inverse_move(move), aux);
    354 				mirr = apply_trans(uf_mirror, cube);
    355 				if (is_solved(cube) || is_solved(mirr))
    356 					moves_ttable[m][mi] = move;
    357 			}
    358 			*/
    359 
    360 			aux = apply_trans(m, apply_move(mi, (Cube){0}));
    361 			for (move = 0; move < NMOVES; move++) {
    362 				cube = apply_move(inverse_move(move), aux);
    363 				if (is_solved(cube)) {
    364 					moves_ttable[m][mi] = move;
    365 					break;
    366 				}
    367 			}
    368 		}
    369 	}
    370 
    371 	if (!write_ttables_file())
    372 		fprintf(stderr, "Error writing ttables\n");
    373 }
    374