3 | #include "facecube.h"
4 | #include "cubiecube.h"
5 |
6 |
7 | facelet_t cornerFacelet[8][3] = { { U9, R1, F3 }, { U7, F1, L3 }, { U1, L1, B3 }, { U3, B1, R3 },
8 | { D3, F9, R7 }, { D1, L9, F7 }, { D7, B9, L7 }, { D9, R9, B7 } };
9 |
10 | facelet_t edgeFacelet[12][2] = { { U6, R2 }, { U8, F2 }, { U4, L2 }, { U2, B2 }, { D6, R8 }, { D2, F8 },
11 | { D4, L8 }, { D8, B8 }, { F6, R4 }, { F4, L6 }, { B6, L4 }, { B4, R6 } };
12 |
13 | color_t cornerColor[8][3] = { { U, R, F }, { U, F, L }, { U, L, B }, { U, B, R }, { D, F, R }, { D, L, F },
14 | { D, B, L }, { D, R, B } };
15 |
16 | color_t edgeColor[12][2] = { { U, R }, { U, F }, { U, L }, { U, B }, { D, R }, { D, F }, { D, L }, { D, B },
17 | { F, R }, { F, L }, { B, L }, { B, R } };
18 |
19 |
20 | facecube_t* get_facecube()
21 | {
22 | facecube_t* res = (facecube_t *) calloc(1, sizeof(facecube_t));
23 | static const color_t f[54] = {U, U, U, U, U, U, U, U, U, R, R, R, R, R, R, R, R, R, F, F, F, F, F, F, F, F, F, D, D, D, D, D, D, D, D, D, L, L, L, L, L, L, L, L, L, B, B, B, B, B, B, B, B, B};
24 | memcpy(res->f, f, sizeof(f));
25 | return res;
26 | }
27 |
28 | facecube_t* get_facecube_fromstring(char* cubeString)
29 | {
30 | int i;
31 | facecube_t* res = (facecube_t *) calloc(1, sizeof(facecube_t));
32 | for (i = 0; i < 54; i++) {
33 | switch(cubeString[i]) {
34 | case 'U':
35 | res->f[i] = U;
36 | break;
37 | case 'R':
38 | res->f[i] = R;
39 | break;
40 | case 'F':
41 | res->f[i] = F;
42 | break;
43 | case 'D':
44 | res->f[i] = D;
45 | break;
46 | case 'L':
47 | res->f[i] = L;
48 | break;
49 | case 'B':
50 | res->f[i] = B;
51 | break;
52 | }
53 | }
54 | return res;
55 | }
56 |
57 | void to_String(facecube_t* facecube, char* res)
58 | {
59 | int i;
60 | for (i = 0; i < 54; i++)
61 | switch(facecube->f[i]) {
62 | case U:
63 | res[i] = 'U';
64 | break;
65 | case R:
66 | res[i] = 'R';
67 | break;
68 | case F:
69 | res[i] = 'F';
70 | break;
71 | case D:
72 | res[i] = 'D';
73 | break;
74 | case L:
75 | res[i] = 'L';
76 | break;
77 | case B:
78 | res[i] = 'B';
79 | break;
80 | }
81 | res[54] = 0;
82 | }
83 |
84 | cubiecube_t* toCubieCube(facecube_t* facecube)
85 | {
86 | int i, j;
87 | signed char ori;
88 | color_t col1, col2;
89 | cubiecube_t* ccRet = (cubiecube_t*) calloc(1, sizeof(cubiecube_t));
90 | for (i = 0; i < 8; i++)
91 | ccRet->cp[i] = URF;// invalidate corners
92 | for (i = 0; i < 12; i++)
93 | ccRet->ep[i] = UR;// and edges
94 |
95 | for(i = 0; i < CORNER_COUNT; i++) {
96 | // get the colors of the cubie at corner i, starting with U/D
97 | for (ori = 0; ori < 3; ori++)
98 | if (facecube->f[cornerFacelet[i][ori]] == U || facecube->f[cornerFacelet[i][ori]] == D)
99 | break;
100 | col1 = facecube->f[cornerFacelet[i][(ori + 1) % 3]];
101 | col2 = facecube->f[cornerFacelet[i][(ori + 2) % 3]];
102 |
103 | for (j = 0; j < CORNER_COUNT; j++) {
104 | if (col1 == cornerColor[j][1] && col2 == cornerColor[j][2]) {
105 | // in cornerposition i we have cornercubie j
106 | ccRet->cp[i] = corner_t( j);
107 | ccRet->co[i] = ori % 3;
108 | break;
109 | }
110 | }
111 | }
112 |
113 | for (i = 0; i < EDGE_COUNT; i++) {
114 | for (j = 0; j < EDGE_COUNT; j++) {
115 | if (facecube->f[edgeFacelet[i][0]] == edgeColor[j][0]
116 | && facecube->f[edgeFacelet[i][1]] == edgeColor[j][1]) {
117 | ccRet->ep[i] = edge_t(j);
118 | ccRet->eo[i] = 0;
119 | break;
120 | }
121 | if (facecube->f[edgeFacelet[i][0]] == edgeColor[j][1]
122 | && facecube->f[edgeFacelet[i][1]] == edgeColor[j][0]) {
123 | ccRet->ep[i] = edge_t(j);
124 | ccRet->eo[i] = 1;
125 | break;
126 | }
127 | }
128 | }
129 | return ccRet;
130 | }
131 |
--------------------------------------------------------------------------------
/kociemba/facecube.h:
--------------------------------------------------------------------------------
1 | #ifndef FACECUBE_H
2 | #define FACECUBE_H
3 |
4 | #include "facelet.h"
5 | #include "color.h"
6 | #include "corner.h"
7 | #include "edge.h"
8 |
9 | //Cube on the facelet level
10 | struct facecube {
11 | color_t f[54];
12 | };
13 | typedef struct facecube facecube_t;
14 |
15 | // forward declaration
16 | struct cubiecube;
17 |
18 | // Map the corner positions to facelet positions. cornerFacelet[URF.ordinal()][0] e.g. gives the position of the
19 | // facelet in the URF corner position, which defines the orientation.
20 | // cornerFacelet[URF.ordinal()][1] and cornerFacelet[URF.ordinal()][2] give the position of the other two facelets
21 | // of the URF corner (clockwise).
22 | extern facelet_t cornerFacelet[8][3];
23 |
24 | // Map the edge positions to facelet positions. edgeFacelet[UR.ordinal()][0] e.g. gives the position of the facelet in
25 | // the UR edge position, which defines the orientation.
26 | // edgeFacelet[UR.ordinal()][1] gives the position of the other facelet
27 | extern facelet_t edgeFacelet[12][2];
28 |
29 | // Map the corner positions to facelet colors.
30 | extern color_t cornerColor[8][3];
31 |
32 | // Map the edge positions to facelet colors.
33 | extern color_t edgeColor[12][2];
34 |
35 | facecube_t* get_facecube(void);
36 | facecube_t* get_facecube_fromstring(char* cubeString);
37 |
38 | void to_String(facecube_t* facecube, char* res);
39 | struct cubiecube* toCubieCube(facecube_t* facecube);
40 |
41 | #endif
42 |
--------------------------------------------------------------------------------
/kociemba/facelet.h:
--------------------------------------------------------------------------------
1 | #ifndef FACELET_H
2 | #define FACELET_H
3 |
4 | /**
5 | *
6 | * The names of the facelet positions of the cube
7 | * |************|
8 | * |*U1**U2**U3*|
9 | * |************|
10 | * |*U4**U5**U6*|
11 | * |************|
12 | * |*U7**U8**U9*|
13 | * |************|
14 | * ************|************|************|************|
15 | * *L1**L2**L3*|*F1**F2**F3*|*R1**R2**F3*|*B1**B2**B3*|
16 | * ************|************|************|************|
17 | * *L4**L5**L6*|*F4**F5**F6*|*R4**R5**R6*|*B4**B5**B6*|
18 | * ************|************|************|************|
19 | * *L7**L8**L9*|*F7**F8**F9*|*R7**R8**R9*|*B7**B8**B9*|
20 | * ************|************|************|************|
21 | * |************|
22 | * |*D1**D2**D3*|
23 | * |************|
24 | * |*D4**D5**D6*|
25 | * |************|
26 | * |*D7**D8**D9*|
27 | * |************|
28 | *
29 | *
30 | *A cube definition string "UBL..." means for example: In position U1 we have the U-color, in position U2 we have the
31 | * B-color, in position U3 we have the L color etc. according to the order U1, U2, U3, U4, U5, U6, U7, U8, U9, R1, R2,
32 | * R3, R4, R5, R6, R7, R8, R9, F1, F2, F3, F4, F5, F6, F7, F8, F9, D1, D2, D3, D4, D5, D6, D7, D8, D9, L1, L2, L3, L4,
33 | * L5, L6, L7, L8, L9, B1, B2, B3, B4, B5, B6, B7, B8, B9 of the enum constants.
34 | */
35 | typedef enum {
36 | U1, U2, U3, U4, U5, U6, U7, U8, U9, R1, R2, R3, R4, R5, R6, R7, R8, R9, F1, F2, F3, F4, F5, F6, F7, F8, F9, D1, D2, D3, D4, D5, D6, D7, D8, D9, L1, L2, L3, L4, L5, L6, L7, L8, L9, B1, B2, B3, B4, B5, B6, B7, B8, B9
37 | } facelet_t;
38 |
39 | #define FACELET_COUNT 54
40 |
41 | #endif
42 |
--------------------------------------------------------------------------------
/kociemba/prunetable_helpers.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include "prunetable_helpers.h"
7 |
8 | char * join_path(const char *dir, const char *filename)
9 | {
10 | size_t path_len = strnlen(dir, 500);
11 | char *fpath = (char *)calloc(path_len + 32, 1);
12 | if (path_len == 500) {
13 | return NULL;
14 | }
15 | strcpy(fpath, dir);
16 | strcat(fpath, "/");
17 | strncat(fpath, filename, 30);
18 | return fpath;
19 | }
20 |
21 | int check_cached_table(const char* name, void* ptr, int len, const char *cache_dir)
22 | {
23 | int res = 0;
24 | char *fname = join_path(cache_dir, name);
25 | if (fname == NULL) {
26 | fprintf(stderr, "Path to cache tables is too long\n");
27 | return -1;
28 | }
29 |
30 | if (access(fname, F_OK | R_OK) != -1) {
31 | // fprintf(stderr, "Found cache for %s. Loading...", name);
32 | read_from_file(ptr, len, fname);
33 | // fprintf(stderr, "done.\n");
34 | res = 0;
35 | } else {
36 | fprintf(stderr, "Cache table %s was not found. Recalculating.\n", fname);
37 | res = 1;
38 | }
39 | free(fname);
40 | return res;
41 | }
42 |
43 | void read_from_file(void* ptr, int len, const char* name)
44 | {
45 | FILE* f = fopen(name, "rb");
46 | if (!fread(ptr, len, 1, f))
47 | ((void)0); // suppress -Wunused-result warning
48 | fclose(f);
49 | }
50 |
51 | int make_dir(const char *cache_dir)
52 | {
53 | #if defined(_WIN32)
54 | return _mkdir(cache_dir);
55 | #else
56 | return mkdir(cache_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
57 | #endif
58 | }
59 |
60 | void dump_to_file(void* ptr, int len, const char* name, const char *cache_dir)
61 | {
62 | int status;
63 | status = make_dir(cache_dir);
64 | if (status == 0 || errno == EEXIST) {
65 | char *fname = join_path(cache_dir, name);
66 | if (fname == NULL) {
67 | fprintf(stderr, "Path to cache tables is too long\n");
68 | } else {
69 | FILE* f = fopen(fname, "wb");
70 | fwrite(ptr, len, 1, f);
71 | free(fname);
72 | fclose(f);
73 | }
74 | } else {
75 | fprintf(stderr, "cannot create cache tables directory\n");
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/kociemba/prunetable_helpers.h:
--------------------------------------------------------------------------------
1 | #ifndef PRUNETABLE_HELPERS_H
2 | #define PRUNETABLE_HELPERS_H
3 |
4 | #if defined(_WIN32)
5 | #include
6 | #include "direct.h"
7 | #define R_OK 4 /* Test for read permission. */
8 | #define W_OK 2 /* Test for write permission. */
9 | #define X_OK 1 /* Test for execute permission. */
10 | #define F_OK 0 /* Test for existence. */
11 | #define access _access
12 | #else
13 | #include
14 | #endif
15 |
16 | int make_dir(const char *cache_dir);
17 | int check_cached_table(const char* name, void* ptr, int len, const char *cache_dir);
18 | void dump_to_file(void* ptr, int len, const char* name, const char *cache_dir);
19 | void read_from_file(void* ptr, int len, const char* name);
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/kociemba/search.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "search.h"
5 | #include "color.h"
6 | #include "facecube.h"
7 | #include "coordcube.h"
8 |
9 | #define MIN(a, b) (((a)<(b))?(a):(b))
10 | #define MAX(a, b) (((a)>(b))?(a):(b))
11 |
12 | char* solutionToString(search_t* search, int length, int depthPhase1)
13 | {
14 | char* s = (char*) calloc(length * 3 + 5, 1);
15 | int cur = 0, i;
16 | for (i = 0; i < length; i++) {
17 | switch (search->ax[i]) {
18 | case 0:
19 | s[cur++] = 'U';
20 | break;
21 | case 1:
22 | s[cur++] = 'R';
23 | break;
24 | case 2:
25 | s[cur++] = 'F';
26 | break;
27 | case 3:
28 | s[cur++] = 'D';
29 | break;
30 | case 4:
31 | s[cur++] = 'L';
32 | break;
33 | case 5:
34 | s[cur++] = 'B';
35 | break;
36 | }
37 | switch (search->po[i]) {
38 | case 1:
39 | s[cur++] = ' ';
40 | break;
41 | case 2:
42 | s[cur++] = '2';
43 | s[cur++] = ' ';
44 | break;
45 | case 3:
46 | s[cur++] = '\'';
47 | s[cur++] = ' ';
48 | break;
49 | }
50 | if (i == depthPhase1 - 1) {
51 | s[cur++] = '.';
52 | s[cur++] = ' ';
53 | }
54 | }
55 | return s;
56 | }
57 |
58 |
59 | char* solution(char* facelets, int maxDepth, long timeOut, int useSeparator, const char* cache_dir)
60 | {
61 | search_t* search = (search_t*) calloc(1, sizeof(search_t));
62 | facecube_t* fc;
63 | cubiecube_t* cc;
64 | coordcube_t* c;
65 |
66 | int s, i;
67 | int mv, n;
68 | int busy;
69 | int depthPhase1;
70 | time_t tStart;
71 | // +++++++++++++++++++++check for wrong input +++++++++++++++++++++++++++++
72 | int count[6] = {0};
73 |
74 | if (PRUNING_INITED == 0) {
75 | initPruning(cache_dir);
76 | }
77 |
78 | for (i = 0; i < 54; i++)
79 | switch(facelets[i]) {
80 | case 'U':
81 | count[U]++;
82 | break;
83 | case 'R':
84 | count[R]++;
85 | break;
86 | case 'F':
87 | count[F]++;
88 | break;
89 | case 'D':
90 | count[D]++;
91 | break;
92 | case 'L':
93 | count[L]++;
94 | break;
95 | case 'B':
96 | count[B]++;
97 | break;
98 | }
99 |
100 | for (i = 0; i < 6; i++)
101 | if (count[i] != 9) {
102 | free(search);
103 | return NULL;
104 | }
105 |
106 | fc = get_facecube_fromstring(facelets);
107 | cc = toCubieCube(fc);
108 | if ((s = verify(cc)) != 0) {
109 | free(search);
110 | return NULL;
111 | }
112 |
113 | // +++++++++++++++++++++++ initialization +++++++++++++++++++++++++++++++++
114 | c = get_coordcube(cc);
115 |
116 | search->po[0] = 0;
117 | search->ax[0] = 0;
118 | search->flip[0] = c->flip;
119 | search->twist[0] = c->twist;
120 | search->parity[0] = c->parity;
121 | search->slice[0] = c->FRtoBR / 24;
122 | search->URFtoDLF[0] = c->URFtoDLF;
123 | search->FRtoBR[0] = c->FRtoBR;
124 | search->URtoUL[0] = c->URtoUL;
125 | search->UBtoDF[0] = c->UBtoDF;
126 |
127 | search->minDistPhase1[1] = 1;// else failure for depth=1, n=0
128 | mv = 0;
129 | n = 0;
130 | busy = 0;
131 | depthPhase1 = 1;
132 |
133 | tStart = time(NULL);
134 |
135 | // +++++++++++++++++++ Main loop ++++++++++++++++++++++++++++++++++++++++++
136 | do {
137 | do {
138 | if ((depthPhase1 - n > search->minDistPhase1[n + 1]) && !busy) {
139 |
140 | if (search->ax[n] == 0 || search->ax[n] == 3)// Initialize next move
141 | search->ax[++n] = 1;
142 | else
143 | search->ax[++n] = 0;
144 | search->po[n] = 1;
145 | } else if (++search->po[n] > 3) {
146 | do {// increment axis
147 | if (++search->ax[n] > 5) {
148 |
149 | if (time(NULL) - tStart > timeOut)
150 | return NULL;
151 |
152 | if (n == 0) {
153 | if (depthPhase1 >= maxDepth)
154 | return NULL;
155 | else {
156 | depthPhase1++;
157 | search->ax[n] = 0;
158 | search->po[n] = 1;
159 | busy = 0;
160 | break;
161 | }
162 | } else {
163 | n--;
164 | busy = 1;
165 | break;
166 | }
167 |
168 | } else {
169 | search->po[n] = 1;
170 | busy = 0;
171 | }
172 | } while (n != 0 && (search->ax[n - 1] == search->ax[n] || search->ax[n - 1] - 3 == search->ax[n]));
173 | } else
174 | busy = 0;
175 | } while (busy);
176 |
177 | // +++++++++++++ compute new coordinates and new minDistPhase1 ++++++++++
178 | // if minDistPhase1 =0, the H subgroup is reached
179 | mv = 3 * search->ax[n] + search->po[n] - 1;
180 | search->flip[n + 1] = flipMove[search->flip[n]][mv];
181 | search->twist[n + 1] = twistMove[search->twist[n]][mv];
182 | search->slice[n + 1] = FRtoBR_Move[search->slice[n] * 24][mv] / 24;
183 | search->minDistPhase1[n + 1] = MAX(
184 | getPruning(Slice_Flip_Prun, N_SLICE1 * search->flip[n + 1] + search->slice[n + 1]),
185 | getPruning(Slice_Twist_Prun, N_SLICE1 * search->twist[n + 1] + search->slice[n + 1])
186 | );
187 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
188 | // System.out.format("%d %d\n", n, depthPhase1);
189 | if (search->minDistPhase1[n + 1] == 0 && n >= depthPhase1 - 5) {
190 | search->minDistPhase1[n + 1] = 10;// instead of 10 any value >5 is possible
191 | if (n == depthPhase1 - 1 && (s = totalDepth(search, depthPhase1, maxDepth)) >= 0) {
192 | if (s == depthPhase1
193 | || (search->ax[depthPhase1 - 1] != search->ax[depthPhase1] && search->ax[depthPhase1 - 1] != search->ax[depthPhase1] + 3)) {
194 | char* res;
195 | free((void*) fc);
196 | free((void*) cc);
197 | free((void*) c);
198 | if (useSeparator) {
199 | res = solutionToString(search, s, depthPhase1);
200 | } else {
201 | res = solutionToString(search, s, -1);
202 | }
203 | free((void*) search);
204 | return res;
205 | }
206 | }
207 |
208 | }
209 | } while (1);
210 | }
211 |
212 | int totalDepth(search_t* search, int depthPhase1, int maxDepth)
213 | {
214 | int mv = 0, d1 = 0, d2 = 0, i;
215 | int maxDepthPhase2 = MIN(10, maxDepth - depthPhase1);// Allow only max 10 moves in phase2
216 | int depthPhase2;
217 | int n;
218 | int busy;
219 | for (i = 0; i < depthPhase1; i++) {
220 | mv = 3 * search->ax[i] + search->po[i] - 1;
221 | // System.out.format("%d %d %d %d\n", i, mv, ax[i], po[i]);
222 | search->URFtoDLF[i + 1] = URFtoDLF_Move[search->URFtoDLF[i]][mv];
223 | search->FRtoBR[i + 1] = FRtoBR_Move[search->FRtoBR[i]][mv];
224 | search->parity[i + 1] = parityMove[search->parity[i]][mv];
225 | }
226 |
227 | if ((d1 = getPruning(Slice_URFtoDLF_Parity_Prun,
228 | (N_SLICE2 * search->URFtoDLF[depthPhase1] + search->FRtoBR[depthPhase1]) * 2 + search->parity[depthPhase1])) > maxDepthPhase2)
229 | return -1;
230 |
231 | for (i = 0; i < depthPhase1; i++) {
232 | mv = 3 * search->ax[i] + search->po[i] - 1;
233 | search->URtoUL[i + 1] = URtoUL_Move[search->URtoUL[i]][mv];
234 | search->UBtoDF[i + 1] = UBtoDF_Move[search->UBtoDF[i]][mv];
235 | }
236 | search->URtoDF[depthPhase1] = MergeURtoULandUBtoDF[search->URtoUL[depthPhase1]][search->UBtoDF[depthPhase1]];
237 |
238 | if ((d2 = getPruning(Slice_URtoDF_Parity_Prun,
239 | (N_SLICE2 * search->URtoDF[depthPhase1] + search->FRtoBR[depthPhase1]) * 2 + search->parity[depthPhase1])) > maxDepthPhase2)
240 | return -1;
241 |
242 | if ((search->minDistPhase2[depthPhase1] = MAX(d1, d2)) == 0)// already solved
243 | return depthPhase1;
244 |
245 | // now set up search
246 |
247 | depthPhase2 = 1;
248 | n = depthPhase1;
249 | busy = 0;
250 | search->po[depthPhase1] = 0;
251 | search->ax[depthPhase1] = 0;
252 | search->minDistPhase2[n + 1] = 1;// else failure for depthPhase2=1, n=0
253 | // +++++++++++++++++++ end initialization +++++++++++++++++++++++++++++++++
254 | do {
255 | do {
256 | if ((depthPhase1 + depthPhase2 - n > search->minDistPhase2[n + 1]) && !busy) {
257 |
258 | if (search->ax[n] == 0 || search->ax[n] == 3)// Initialize next move
259 | {
260 | search->ax[++n] = 1;
261 | search->po[n] = 2;
262 | } else {
263 | search->ax[++n] = 0;
264 | search->po[n] = 1;
265 | }
266 | } else if ((search->ax[n] == 0 || search->ax[n] == 3) ? (++search->po[n] > 3) : ((search->po[n] = search->po[n] + 2) > 3)) {
267 | do {// increment axis
268 | if (++search->ax[n] > 5) {
269 | if (n == depthPhase1) {
270 | if (depthPhase2 >= maxDepthPhase2)
271 | return -1;
272 | else {
273 | depthPhase2++;
274 | search->ax[n] = 0;
275 | search->po[n] = 1;
276 | busy = 0;
277 | break;
278 | }
279 | } else {
280 | n--;
281 | busy = 1;
282 | break;
283 | }
284 |
285 | } else {
286 | if (search->ax[n] == 0 || search->ax[n] == 3)
287 | search->po[n] = 1;
288 | else
289 | search->po[n] = 2;
290 | busy = 0;
291 | }
292 | } while (n != depthPhase1 && (search->ax[n - 1] == search->ax[n] || search->ax[n - 1] - 3 == search->ax[n]));
293 | } else
294 | busy = 0;
295 | } while (busy);
296 | // +++++++++++++ compute new coordinates and new minDist ++++++++++
297 | mv = 3 * search->ax[n] + search->po[n] - 1;
298 |
299 | search->URFtoDLF[n + 1] = URFtoDLF_Move[search->URFtoDLF[n]][mv];
300 | search->FRtoBR[n + 1] = FRtoBR_Move[search->FRtoBR[n]][mv];
301 | search->parity[n + 1] = parityMove[search->parity[n]][mv];
302 | search->URtoDF[n + 1] = URtoDF_Move[search->URtoDF[n]][mv];
303 |
304 | search->minDistPhase2[n + 1] = MAX(getPruning(Slice_URtoDF_Parity_Prun, (N_SLICE2
305 | * search->URtoDF[n + 1] + search->FRtoBR[n + 1])
306 | * 2 + search->parity[n + 1]), getPruning(Slice_URFtoDLF_Parity_Prun, (N_SLICE2
307 | * search->URFtoDLF[n + 1] + search->FRtoBR[n + 1])
308 | * 2 + search->parity[n + 1]));
309 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
310 |
311 | } while (search->minDistPhase2[n + 1] != 0);
312 | return depthPhase1 + depthPhase2;
313 | }
314 |
315 | void patternize(char* facelets, char* pattern, char* patternized)
316 | {
317 | facecube_t* fc;
318 | facecube_t* start_fc = get_facecube_fromstring(facelets);
319 | facecube_t* pattern_fc = get_facecube_fromstring(pattern);
320 | cubiecube_t* start_cc = toCubieCube(start_fc);
321 | cubiecube_t* pattern_cc = toCubieCube(pattern_fc);
322 | cubiecube_t* inv_pattern_cc = get_cubiecube();
323 | invCubieCube(pattern_cc, inv_pattern_cc);
324 | multiply(inv_pattern_cc, start_cc);
325 | fc = toFaceCube(inv_pattern_cc);
326 | to_String(fc, patternized);
327 | free(start_fc);
328 | free(pattern_fc);
329 | free(start_cc);
330 | free(pattern_cc);
331 | free(inv_pattern_cc);
332 | free(fc);
333 | }
334 |
--------------------------------------------------------------------------------
/kociemba/search.h:
--------------------------------------------------------------------------------
1 | #ifndef SEARCH_H
2 | #define SEARCH_H
3 |
4 | typedef struct {
5 | int ax[31]; // The axis of the move
6 | int po[31]; // The power of the move
7 | int flip[31]; // phase1 coordinates
8 | int twist[31];
9 | int slice[31];
10 | int parity[31]; // phase2 coordinates
11 | int URFtoDLF[31];
12 | int FRtoBR[31];
13 | int URtoUL[31];
14 | int UBtoDF[31];
15 | int URtoDF[31];
16 | int minDistPhase1[31]; // IDA* distance do goal estimations
17 | int minDistPhase2[31];
18 | } search_t;
19 |
20 | search_t* get_search(void);
21 |
22 | // generate the solution string from the array data including a separator between phase1 and phase2 moves
23 | char* solutionToString(search_t* search, int length, int depthPhase1);
24 | /**
25 | * Computes the solver string for a given cube.
26 | *
27 | * @param facelets
28 | * is the cube definition string, see {@link Facelet} for the format.
29 | *
30 | * @param maxDepth
31 | * defines the maximal allowed maneuver length. For random cubes, a maxDepth of 21 usually will return a
32 | * solution in less than 0.5 seconds. With a maxDepth of 20 it takes a few seconds on average to find a
33 | * solution, but it may take much longer for specific cubes.
34 | *
35 | *@param timeOut
36 | * defines the maximum computing time of the method in seconds. If it does not return with a solution, it returns with
37 | * an error code.
38 | *
39 | * @param useSeparator
40 | * determines if a " . " separates the phase1 and phase2 parts of the solver string like in F' R B R L2 F .
41 | * U2 U D for example.
42 | * @return The solution string or an error code:
43 | * Error 1: There is not exactly one facelet of each colour
44 | * Error 2: Not all 12 edges exist exactly once
45 | * Error 3: Flip error: One edge has to be flipped
46 | * Error 4: Not all corners exist exactly once
47 | * Error 5: Twist error: One corner has to be twisted
48 | * Error 6: Parity error: Two corners or two edges have to be exchanged
49 | * Error 7: No solution exists for the given maxDepth
50 | * Error 8: Timeout, no solution within given time
51 | */
52 | char* solution(char* facelets, int maxDepth, long timeOut, int useSeparator, const char* cache_dir);
53 |
54 | // Apply phase2 of algorithm and return the combined phase1 and phase2 depth. In phase2, only the moves
55 | // U,D,R2,F2,L2 and B2 are allowed.
56 | int totalDepth(search_t* search, int depthPhase1, int maxDepth);
57 |
58 |
59 | // Add a pattern to the state of a cube, so that the solution for new_facelets
60 | // applied to facelets will result into the given pattern
61 | void patternize(char* facelets, char* pattern, char* patternized);
62 |
63 | #endif
64 |
--------------------------------------------------------------------------------
/kociemba/solve.cpp:
--------------------------------------------------------------------------------
1 | //#include
2 | //#include
3 | //#include "search.h"
4 | //
5 | //int main(int argc, char **argv)
6 | //{
7 | // argc = 2;
8 | // argv[1] = "RUURULDDLDFRRRFBBRLRBLFUDFLRDULDUFDFFBFDLBUUBBFURBLDBL";
9 | // if (argc > 1) {
10 | // char patternized[64];
11 | // char* facelets = argv[1];
12 | // if (argc > 2) {
13 | // patternize(facelets, argv[2], patternized);
14 | // facelets = patternized;
15 | // }
16 | // char *sol = solution(
17 | // facelets,
18 | // 21,
19 | // 1000,
20 | // 0,
21 | // "cache"
22 | // );
23 | // if (sol == NULL) {
24 | // puts("Unsolvable cube!");
25 | // return 2;
26 | // }
27 | // puts(sol);
28 | // free(sol);
29 | // system("pause");
30 | // return 0;
31 | // } else {
32 | // return 1;
33 | // }
34 | //}
35 |
--------------------------------------------------------------------------------
/kociemba/umm:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/vision/mend.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubhe/cubesolver/d7dd64d3764e32285cdffbeac0e4452a9bee9331/vision/mend.cpp
--------------------------------------------------------------------------------
/vision/mend.h:
--------------------------------------------------------------------------------
1 | #ifndef MEND_H
2 | #define MEND_H
3 | #include
4 | using std::string;
5 | void MendCubeCenter(string & str);
6 | void MendCubeCorner(string & str);
7 | void MendCubeEdge(string & str);
8 | void ChangeColor(string & str);
9 | #endif // !MEND_H
--------------------------------------------------------------------------------
/vision/vision.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubhe/cubesolver/d7dd64d3764e32285cdffbeac0e4452a9bee9331/vision/vision.cpp
--------------------------------------------------------------------------------
/vision/vision.h:
--------------------------------------------------------------------------------
1 | #ifndef VISION_H
2 | #define SOLVE_H
3 | #include
4 | std::string vision();
5 | void training();
6 | #endif // !VISION_H
7 |
--------------------------------------------------------------------------------
/vision/源.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include"vision.h"
4 | using namespace std;
5 | int main() {
6 | string color=ReadColor();
7 | if (color.length() != 0) {
8 | cout <