nissy-nx

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

cube.c (4714B)


      1 #define CUBE_C
      2 
      3 #include "cube.h"
      4 
      5 static int where_is_piece(int piece, int *arr, int n);
      6 
      7 void
      8 compose_centers(Cube *c2, Cube *c1)
      9 {
     10 	apply_permutation(c2->xp, c1->xp, 6);
     11 }
     12 
     13 void
     14 compose_corners(Cube *c2, Cube *c1)
     15 {
     16 	apply_permutation(c2->cp, c1->cp, 8);
     17 	apply_permutation(c2->cp, c1->co, 8);
     18 	sum_arrays_mod(c2->co, c1->co, 8, 3);
     19 }
     20 
     21 void
     22 compose_edges(Cube *c2, Cube *c1)
     23 {
     24 	apply_permutation(c2->ep, c1->ep, 12);
     25 	apply_permutation(c2->ep, c1->eo, 12);
     26 	sum_arrays_mod(c2->eo, c1->eo, 12, 2);
     27 }
     28 
     29 void
     30 compose(Cube *c2, Cube *c1)
     31 {
     32 	compose_centers(c2, c1);
     33 	compose_corners(c2, c1);
     34 	compose_edges(c2, c1);
     35 }
     36 
     37 void
     38 copy_cube_centers(Cube *src, Cube *dst)
     39 {
     40 	memcpy(dst->xp, src->xp,  6 * sizeof(int));
     41 }
     42 
     43 void
     44 copy_cube_corners(Cube *src, Cube *dst)
     45 {
     46 	memcpy(dst->cp, src->cp,  8 * sizeof(int));
     47 	memcpy(dst->co, src->co,  8 * sizeof(int));
     48 }
     49 
     50 void
     51 copy_cube_edges(Cube *src, Cube *dst)
     52 {
     53 	memcpy(dst->ep, src->ep, 12 * sizeof(int));
     54 	memcpy(dst->eo, src->eo, 12 * sizeof(int));
     55 }
     56 
     57 void
     58 copy_cube(Cube *src, Cube *dst)
     59 {
     60 	copy_cube_centers(src, dst);
     61 	copy_cube_corners(src, dst);
     62 	copy_cube_edges(src, dst);
     63 }
     64 
     65 bool
     66 equal(Cube *c1, Cube *c2)
     67 {
     68 	int i;
     69 
     70 	for (i = 0; i < 12; i++)
     71 		if (c1->ep[i] != c2->ep[i] || c1->eo[i] != c2->eo[i])
     72 			return false;
     73 
     74 	for (i = 0; i < 8; i++)
     75 		if (c1->cp[i] != c2->cp[i] || c1->co[i] != c2->co[i])
     76 			return false;
     77 
     78 	for (i = 0; i < 6; i++)
     79 		if (c1->xp[i] != c2->xp[i])
     80 			return false;
     81 
     82 	return true;
     83 }
     84 
     85 void
     86 invert_cube_centers(Cube *cube)
     87 {
     88 	int i;
     89 	Cube aux;
     90 
     91 	copy_cube_centers(cube, &aux);
     92 
     93 	for (i = 0; i < 6; i++)
     94 		cube->xp[aux.xp[i]] = i;
     95 }
     96 
     97 void
     98 invert_cube_corners(Cube *cube)
     99 {
    100 	int i;
    101 	Cube aux;
    102 
    103 	copy_cube_corners(cube, &aux);
    104 
    105 	for (i = 0; i < 8; i++) {
    106 		cube->cp[aux.cp[i]] = i;
    107 		cube->co[aux.cp[i]] = (3 - aux.co[i]) % 3;
    108 	}
    109 }
    110 
    111 void
    112 invert_cube_edges(Cube *cube)
    113 {
    114 	int i;
    115 	Cube aux;
    116 
    117 	copy_cube_edges(cube, &aux);
    118 
    119 	for (i = 0; i < 12; i++) {
    120 		cube->ep[aux.ep[i]] = i;
    121 		cube->eo[aux.ep[i]] = aux.eo[i];
    122 	}
    123 }
    124 
    125 void
    126 invert_cube(Cube *cube)
    127 {
    128 	invert_cube_centers(cube);
    129 	invert_cube_corners(cube);
    130 	invert_cube_edges(cube);
    131 }
    132 
    133 bool
    134 is_admissible(Cube *c) {
    135 	bool perm;
    136 	int sign, i;
    137 	int sum_e, sum_c;
    138 
    139 	perm = is_perm(c->ep, 12) && is_perm(c->cp, 8) && is_perm(c->xp, 6);
    140 
    141 	sign = perm_sign(c->ep,12) + perm_sign(c->cp,8) + perm_sign(c->xp,6);
    142 
    143 	for (i = 0, sum_e = 0; i < 12; i++)
    144 		if (c->eo[i] > 1)
    145 			return false;
    146 		else
    147 			sum_e += c->eo[i];
    148 
    149 	for (i = 0, sum_c = 0; i < 8; i++)
    150 		if (c->co[i] > 2)
    151 			return false;
    152 		else
    153 			sum_c += c->co[i];
    154 
    155 	return (perm && sign % 2 == 0 && sum_e % 2 == 0 && sum_c % 2 == 0);
    156 }
    157 
    158 bool
    159 is_solved(Cube *cube)
    160 {
    161 	Cube solved_cube;
    162 	make_solved(&solved_cube);
    163 
    164 	return equal(cube, &solved_cube);
    165 }
    166 
    167 void
    168 make_solved_centers(Cube *cube)
    169 {
    170 	static int sorted[6] = {0, 1, 2, 3, 4, 5};
    171 
    172 	memcpy(cube->xp, sorted,  6 * sizeof(int));
    173 }
    174 
    175 void
    176 make_solved_corners(Cube *cube)
    177 {
    178 	static int sorted[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    179 
    180 	memcpy(cube->cp, sorted,  8 * sizeof(int));
    181 	memset(cube->co, 0,       8 * sizeof(int));
    182 }
    183 
    184 void
    185 make_solved_edges(Cube *cube)
    186 {
    187 	static int sorted[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    188 
    189 	memcpy(cube->ep, sorted, 12 * sizeof(int));
    190 	memset(cube->eo, 0,      12 * sizeof(int));
    191 }
    192 
    193 void
    194 make_solved(Cube *cube)
    195 {
    196 	make_solved_centers(cube);
    197 	make_solved_corners(cube);
    198 	make_solved_edges(cube);
    199 }
    200 
    201 void
    202 print_cube(Cube *cube)
    203 {
    204 	static char edge_string[12][7] = {
    205 		[UF] = "UF", [UL] = "UL", [UB] = "UB", [UR] = "UR",
    206 		[DF] = "DF", [DL] = "DL", [DB] = "DB", [DR] = "DR",
    207 		[FR] = "FR", [FL] = "FL", [BL] = "BL", [BR] = "BR"
    208 	};
    209 
    210 	static char corner_string[8][7] = {
    211 		[UFR] = "UFR", [UFL] = "UFL", [UBL] = "UBL", [UBR] = "UBR",
    212 		[DFR] = "DFR", [DFL] = "DFL", [DBL] = "DBL", [DBR] = "DBR"
    213 	};
    214 
    215 	static char center_string[6][7] = {
    216 		[U_center] = "U", [D_center] = "D",
    217 		[R_center] = "R", [L_center] = "L", 
    218 		[F_center] = "F", [B_center] = "B"
    219 	};
    220 
    221 	for (int i = 0; i < 12; i++)
    222 		printf(" %s ", edge_string[cube->ep[i]]);
    223 	printf("\n");
    224 
    225 	for (int i = 0; i < 12; i++)
    226 		printf("  %" PRIu8 " ", cube->eo[i]);
    227 	printf("\n");
    228 
    229 	for (int i = 0; i < 8; i++)
    230 		printf("%s ", corner_string[cube->cp[i]]);
    231 	printf("\n");
    232 
    233 	for (int i = 0; i < 8; i++)
    234 		printf("  %" PRIu8 " ", cube->co[i]);
    235 	printf("\n");
    236 
    237 	for (int i = 0; i < 6; i++)
    238 		printf("  %s ", center_string[cube->xp[i]]);
    239 	printf("\n");
    240 }
    241 
    242 int
    243 where_is_center(Center x, Cube *c)
    244 {
    245 	return where_is_piece(x, c->xp, 6);
    246 }
    247 
    248 int
    249 where_is_corner(Corner k, Cube *c)
    250 {
    251 	return where_is_piece(k, c->cp, 8);
    252 }
    253 
    254 int
    255 where_is_edge(Edge e, Cube *c)
    256 {
    257 	return where_is_piece(e, c->ep, 12);
    258 }
    259 
    260 static int
    261 where_is_piece(int piece, int *arr, int n)
    262 {
    263 	int i;
    264 
    265 	for (i = 0; i < n; i++)
    266 		if (arr[i] == piece)
    267 			return i;
    268 
    269 	return -1;
    270 }