From 418c37b20469347a99aa077118ac16c2ddf16586 Mon Sep 17 00:00:00 2001 From: Maxim Tsoy Date: Sun, 18 Mar 2018 22:19:51 +0100 Subject: [PATCH 1/8] refactor code to satisfy Visual C++ compiler (it doesn't support inline variables in C code) --- .gitignore | 3 + kociemba/build_ckociemba.py | 15 +- kociemba/ckociemba/Makefile | 3 +- kociemba/ckociemba/coordcube.c | 179 ++++++-------- kociemba/ckociemba/cubiecube.c | 220 ++++++++++-------- kociemba/ckociemba/facecube.c | 22 +- kociemba/ckociemba/include/coordcube.h | 5 +- .../ckociemba/include/prunetable_helpers.h | 21 ++ kociemba/ckociemba/prunetable_helpers.c | 77 ++++++ kociemba/ckociemba/search.c | 64 ++--- 10 files changed, 346 insertions(+), 263 deletions(-) create mode 100644 kociemba/ckociemba/include/prunetable_helpers.h create mode 100644 kociemba/ckociemba/prunetable_helpers.c diff --git a/.gitignore b/.gitignore index 7972ad0..39212bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ kociemba/ckociemba/bin/* kociemba/ckociemba/cache/* +.vscode/** +Release/** +ckociembawrapper.c # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/kociemba/build_ckociemba.py b/kociemba/build_ckociemba.py index 1a80d44..ca48eb7 100644 --- a/kociemba/build_ckociemba.py +++ b/kociemba/build_ckociemba.py @@ -4,19 +4,19 @@ ffi.set_source( "kociemba.ckociembawrapper", """ - #include - #include - #include + #include "search.h" char* solve(char *cubestring, char *patternstring, char *cache_dir) { char patternized[64]; + char *sol; + if (patternstring) { patternize(cubestring, patternstring, patternized); cubestring = patternized; } - char *sol = solution( + sol = solution( cubestring, 24, 1000, @@ -28,11 +28,14 @@ """, include_dirs=['kociemba/ckociemba/include'], sources=[ + 'kociemba/ckociemba/prunetable_helpers.c', 'kociemba/ckociemba/coordcube.c', 'kociemba/ckociemba/cubiecube.c', 'kociemba/ckociemba/facecube.c', - 'kociemba/ckociemba/search.c'], - extra_compile_args=['-std=c99', '-O3', '-D_XOPEN_SOURCE=700']) + 'kociemba/ckociemba/search.c' + ], + extra_compile_args=['-std=c99', '-O3', '-D_XOPEN_SOURCE=700'] +) ffi.cdef("char* solve(char *cubestring, char *patternstring, char *cache_dir);") diff --git a/kociemba/ckociemba/Makefile b/kociemba/ckociemba/Makefile index d693b00..0d12251 100644 --- a/kociemba/ckociemba/Makefile +++ b/kociemba/ckociemba/Makefile @@ -1,4 +1,4 @@ -CKOCIEMBA_SRC = coordcube.c cubiecube.c facecube.c search.c +CKOCIEMBA_SRC = coordcube.c cubiecube.c facecube.c search.c prunetable_helpers.c CKOCIEMBA_INCLUDE = include CFLAGS = -std=c99 -O3 BINDIR = bin @@ -7,4 +7,3 @@ BIN = kociemba solve: solve.c $(CKOCIEMBA_SRC) mkdir -p $(BINDIR) gcc $(CFLAGS) $(CKOCIEMBA_SRC) -I$(CKOCIEMBA_INCLUDE) solve.c -o $(BINDIR)/$(BIN) - diff --git a/kociemba/ckociemba/coordcube.c b/kociemba/ckociemba/coordcube.c index 1a619d5..4b8a03e 100644 --- a/kociemba/ckociemba/coordcube.c +++ b/kociemba/ckociemba/coordcube.c @@ -1,10 +1,6 @@ -#include -#include -#include #include -#include -#include -#include +#include +#include "prunetable_helpers.h" #include "coordcube.h" #include "cubiecube.h" @@ -44,67 +40,6 @@ void move(coordcube_t* coordcube, int m, const char *cache_dir) coordcube->URtoDF = MergeURtoULandUBtoDF[coordcube->URtoUL][coordcube->UBtoDF]; } -char * join_path(const char *dir, const char *filename) -{ - size_t path_len = strnlen(dir, 200); - if (path_len == 200) { - return NULL; - } - char *fpath = calloc(path_len + 32, 1); - strcpy(fpath, dir); - strcat(fpath, "/"); - strncat(fpath, filename, 30); - return fpath; -} - -int check_cached_table(const char* name, void* ptr, int len, const char *cache_dir) -{ - char *fname = join_path(cache_dir, name); - if (fname == NULL) { - fprintf(stderr, "Path to cache tables is too long\n"); - return -1; - } - int res = 0; - if (access(fname, F_OK | R_OK) != -1) { - // fprintf(stderr, "Found cache for %s. Loading...", name); - read_from_file(ptr, len, fname); - // fprintf(stderr, "done.\n"); - res = 0; - } else { - fprintf(stderr, "Cache table %s was not found. Recalculating.\n", fname); - res = 1; - } - free(fname); - return res; -} - -void read_from_file(void* ptr, int len, const char* name) -{ - FILE* f = fopen(name, "r"); - if (!fread(ptr, len, 1, f)) - ((void)0); // suppress -Wunused-result warning - fclose(f); -} - -void dump_to_file(void* ptr, int len, const char* name, const char *cache_dir) -{ - int status; - status = mkdir(cache_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (status == 0 || errno == EEXIST) { - char *fname = join_path(cache_dir, name); - if (fname == NULL) { - fprintf(stderr, "Path to cache tables is too long\n"); - } else { - FILE* f = fopen(fname, "w"); - fwrite(ptr, len, 1, f); - free(fname); - fclose(f); - } - } else { - fprintf(stderr, "cannot create cache tables directory\n"); - } -} - coordcube_t* get_coordcube(cubiecube_t* cubiecube) { coordcube_t* result = (coordcube_t *) calloc(1, sizeof(coordcube_t)); @@ -127,11 +62,13 @@ void initPruning(const char *cache_dir) cubiecube_t* moveCube = get_moveCube(); if(check_cached_table("twistMove", (void*) twistMove, sizeof(twistMove), cache_dir) != 0) { + short i; + int k, j; a = get_cubiecube(); - for (short i = 0; i < N_TWIST; i++) { + for (i = 0; i < N_TWIST; i++) { setTwist(a, i); - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 3; k++) { + for (j = 0; j < 6; j++) { + for (k = 0; k < 3; k++) { cornerMultiply(a, &moveCube[j]); twistMove[i][3 * j + k] = getTwist(a); } @@ -143,11 +80,13 @@ void initPruning(const char *cache_dir) } if(check_cached_table("flipMove", (void*) flipMove, sizeof(flipMove), cache_dir) != 0) { + short i; + int k, j; a = get_cubiecube(); - for (short i = 0; i < N_FLIP; i++) { + for (i = 0; i < N_FLIP; i++) { setFlip(a, i); - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 3; k++) { + for (j = 0; j < 6; j++) { + for (k = 0; k < 3; k++) { edgeMultiply(a, &moveCube[j]); flipMove[i][3 * j + k] = getFlip(a); } @@ -159,11 +98,13 @@ void initPruning(const char *cache_dir) } if(check_cached_table("FRtoBR_Move", (void*) FRtoBR_Move, sizeof(FRtoBR_Move), cache_dir) != 0) { + short i; + int k, j; a = get_cubiecube(); - for (short i = 0; i < N_FRtoBR; i++) { + for (i = 0; i < N_FRtoBR; i++) { setFRtoBR(a, i); - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 3; k++) { + for (j = 0; j < 6; j++) { + for (k = 0; k < 3; k++) { edgeMultiply(a, &moveCube[j]); FRtoBR_Move[i][3 * j + k] = getFRtoBR(a); } @@ -175,11 +116,13 @@ void initPruning(const char *cache_dir) } if(check_cached_table("URFtoDLF_Move", (void*) URFtoDLF_Move, sizeof(URFtoDLF_Move), cache_dir) != 0) { + short i; + int k, j; a = get_cubiecube(); - for (short i = 0; i < N_URFtoDLF; i++) { + for (i = 0; i < N_URFtoDLF; i++) { setURFtoDLF(a, i); - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 3; k++) { + for (j = 0; j < 6; j++) { + for (k = 0; k < 3; k++) { cornerMultiply(a, &moveCube[j]); URFtoDLF_Move[i][3 * j + k] = getURFtoDLF(a); } @@ -191,11 +134,13 @@ void initPruning(const char *cache_dir) } if(check_cached_table("URtoDF_Move", (void*) URtoDF_Move, sizeof(URtoDF_Move), cache_dir) != 0) { + short i; + int k, j; a = get_cubiecube(); - for (short i = 0; i < N_URtoDF; i++) { + for (i = 0; i < N_URtoDF; i++) { setURtoDF(a, i); - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 3; k++) { + for (j = 0; j < 6; j++) { + for (k = 0; k < 3; k++) { edgeMultiply(a, &moveCube[j]); URtoDF_Move[i][3 * j + k] = (short) getURtoDF(a); // Table values are only valid for phase 2 moves! @@ -209,11 +154,13 @@ void initPruning(const char *cache_dir) } if(check_cached_table("URtoUL_Move", (void*) URtoUL_Move, sizeof(URtoUL_Move), cache_dir) != 0) { + short i; + int k, j; a = get_cubiecube(); - for (short i = 0; i < N_URtoUL; i++) { + for (i = 0; i < N_URtoUL; i++) { setURtoUL(a, i); - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 3; k++) { + for (j = 0; j < 6; j++) { + for (k = 0; k < 3; k++) { edgeMultiply(a, &moveCube[j]); URtoUL_Move[i][3 * j + k] = getURtoUL(a); } @@ -225,11 +172,13 @@ void initPruning(const char *cache_dir) } if(check_cached_table("UBtoDF_Move", (void*) UBtoDF_Move, sizeof(UBtoDF_Move), cache_dir) != 0) { + short i; + int k, j; a = get_cubiecube(); - for (short i = 0; i < N_UBtoDF; i++) { + for (i = 0; i < N_UBtoDF; i++) { setUBtoDF(a, i); - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 3; k++) { + for (j = 0; j < 6; j++) { + for (k = 0; k < 3; k++) { edgeMultiply(a, &moveCube[j]); UBtoDF_Move[i][3 * j + k] = getUBtoDF(a); } @@ -243,29 +192,30 @@ void initPruning(const char *cache_dir) if(check_cached_table("MergeURtoULandUBtoDF", (void*) MergeURtoULandUBtoDF, sizeof(MergeURtoULandUBtoDF), cache_dir) != 0) { // for i, j <336 the six edges UR,UF,UL,UB,DR,DF are not in the // UD-slice and the index is <20160 - for (short uRtoUL = 0; uRtoUL < 336; uRtoUL++) { - for (short uBtoDF = 0; uBtoDF < 336; uBtoDF++) { + short uRtoUL, uBtoDF; + for (uRtoUL = 0; uRtoUL < 336; uRtoUL++) { + for (uBtoDF = 0; uBtoDF < 336; uBtoDF++) { MergeURtoULandUBtoDF[uRtoUL][uBtoDF] = (short) getURtoDF_standalone(uRtoUL, uBtoDF); } } dump_to_file((void*) MergeURtoULandUBtoDF, sizeof(MergeURtoULandUBtoDF), "MergeURtoULandUBtoDF", cache_dir); } - int depth, done; - if(check_cached_table("Slice_URFtoDLF_Parity_Prun", (void*) Slice_URFtoDLF_Parity_Prun, sizeof(Slice_URFtoDLF_Parity_Prun), cache_dir) != 0) { - for (int i = 0; i < N_SLICE2 * N_URFtoDLF * N_PARITY / 2; i++) + int depth = 0, done = 1; + int i, j; + for (i = 0; i < N_SLICE2 * N_URFtoDLF * N_PARITY / 2; i++) Slice_URFtoDLF_Parity_Prun[i] = -1; - depth = 0; setPruning(Slice_URFtoDLF_Parity_Prun, 0, 0); - done = 1; + printf("1\n"); while (done != N_SLICE2 * N_URFtoDLF * N_PARITY) { - for (int i = 0; i < N_SLICE2 * N_URFtoDLF * N_PARITY; i++) { + // printf("%d %d %d\n", done, N_SLICE2 * N_URFtoDLF * N_PARITY, depth); + for (i = 0; i < N_SLICE2 * N_URFtoDLF * N_PARITY; i++) { int parity = i % 2; int URFtoDLF = (i / 2) / N_SLICE2; int slice = (i / 2) % N_SLICE2; if (getPruning(Slice_URFtoDLF_Parity_Prun, i) == depth) { - for (int j = 0; j < 18; j++) { + for (j = 0; j < 18; j++) { int newSlice; int newURFtoDLF; int newParity; @@ -294,22 +244,24 @@ void initPruning(const char *cache_dir) } depth++; } + printf("2\n"); dump_to_file((void*) Slice_URFtoDLF_Parity_Prun, sizeof(Slice_URFtoDLF_Parity_Prun), "Slice_URFtoDLF_Parity_Prun", cache_dir); + printf("3\n"); } if(check_cached_table("Slice_URtoDF_Parity_Prun", (void*) Slice_URtoDF_Parity_Prun, sizeof(Slice_URtoDF_Parity_Prun), cache_dir) != 0) { - for (int i = 0; i < N_SLICE2 * N_URtoDF * N_PARITY / 2; i++) + int depth = 0, done = 1; + int i, j; + for (i = 0; i < N_SLICE2 * N_URtoDF * N_PARITY / 2; i++) Slice_URtoDF_Parity_Prun[i] = -1; - depth = 0; setPruning(Slice_URtoDF_Parity_Prun, 0, 0); - done = 1; while (done != N_SLICE2 * N_URtoDF * N_PARITY) { - for (int i = 0; i < N_SLICE2 * N_URtoDF * N_PARITY; i++) { + for (i = 0; i < N_SLICE2 * N_URtoDF * N_PARITY; i++) { int parity = i % 2; int URtoDF = (i / 2) / N_SLICE2; int slice = (i / 2) % N_SLICE2; if (getPruning(Slice_URtoDF_Parity_Prun, i) == depth) { - for (int j = 0; j < 18; j++) { + for (j = 0; j < 18; j++) { int newSlice; int newURtoDF; int newParity; @@ -340,18 +292,18 @@ void initPruning(const char *cache_dir) } dump_to_file((void*) Slice_URtoDF_Parity_Prun, sizeof(Slice_URtoDF_Parity_Prun), "Slice_URtoDF_Parity_Prun", cache_dir); } - + if(check_cached_table("Slice_Twist_Prun", (void*) Slice_Twist_Prun, sizeof(Slice_Twist_Prun), cache_dir) != 0) { - for (int i = 0; i < N_SLICE1 * N_TWIST / 2 + 1; i++) + int depth = 0, done = 1; + int i, j; + for (i = 0; i < N_SLICE1 * N_TWIST / 2 + 1; i++) Slice_Twist_Prun[i] = -1; - depth = 0; setPruning(Slice_Twist_Prun, 0, 0); - done = 1; while (done != N_SLICE1 * N_TWIST) { - for (int i = 0; i < N_SLICE1 * N_TWIST; i++) { + for (i = 0; i < N_SLICE1 * N_TWIST; i++) { int twist = i / N_SLICE1, slice = i % N_SLICE1; if (getPruning(Slice_Twist_Prun, i) == depth) { - for (int j = 0; j < 18; j++) { + for (j = 0; j < 18; j++) { int newSlice = FRtoBR_Move[slice * 24][j] / 24; int newTwist = twistMove[twist][j]; if (getPruning(Slice_Twist_Prun, N_SLICE1 * newTwist + newSlice) == 0x0f) { @@ -367,16 +319,16 @@ void initPruning(const char *cache_dir) } if(check_cached_table("Slice_Flip_Prun", (void*) Slice_Flip_Prun, sizeof(Slice_Flip_Prun), cache_dir) != 0) { - for (int i = 0; i < N_SLICE1 * N_FLIP / 2; i++) + int depth = 0, done = 1; + int i, j; + for (i = 0; i < N_SLICE1 * N_FLIP / 2; i++) Slice_Flip_Prun[i] = -1; - depth = 0; setPruning(Slice_Flip_Prun, 0, 0); - done = 1; while (done != N_SLICE1 * N_FLIP) { - for (int i = 0; i < N_SLICE1 * N_FLIP; i++) { + for (i = 0; i < N_SLICE1 * N_FLIP; i++) { int flip = i / N_SLICE1, slice = i % N_SLICE1; if (getPruning(Slice_Flip_Prun, i) == depth) { - for (int j = 0; j < 18; j++) { + for (j = 0; j < 18; j++) { int newSlice = FRtoBR_Move[slice * 24][j] / 24; int newFlip = flipMove[flip][j]; if (getPruning(Slice_Flip_Prun, N_SLICE1 * newFlip + newSlice) == 0x0f) { @@ -412,4 +364,3 @@ signed char getPruning(signed char *table, int index) { return res; } - diff --git a/kociemba/ckociemba/cubiecube.c b/kociemba/ckociemba/cubiecube.c index 7c4115f..b2a6144 100644 --- a/kociemba/ckociemba/cubiecube.c +++ b/kociemba/ckociemba/cubiecube.c @@ -73,7 +73,7 @@ cubiecube_t* get_cubiecube() memcpy(result->co, co, sizeof(co)); memcpy(result->ep, ep, sizeof(ep)); memcpy(result->eo, eo, sizeof(eo)); - + return result; } @@ -93,8 +93,9 @@ int Cnk(int n, int k) { void rotateLeft_corner(corner_t* arr, int l, int r) // Left rotation of all array elements between l and r { + int i; corner_t temp = arr[l]; - for (int i = l; i < r; i++) + for (i = l; i < r; i++) arr[i] = arr[i + 1]; arr[r] = temp; } @@ -102,8 +103,9 @@ void rotateLeft_corner(corner_t* arr, int l, int r) void rotateRight_corner(corner_t* arr, int l, int r) // Right rotation of all array elements between l and r { + int i; corner_t temp = arr[r]; - for (int i = r; i > l; i--) + for (i = r; i > l; i--) arr[i] = arr[i - 1]; arr[l] = temp; } @@ -112,8 +114,9 @@ void rotateRight_corner(corner_t* arr, int l, int r) void rotateLeft_edge(edge_t* arr, int l, int r) // Left rotation of all array elements between l and r { + int i; edge_t temp = arr[l]; - for (int i = l; i < r; i++) + for (i = l; i < r; i++) arr[i] = arr[i + 1]; arr[r] = temp; } @@ -121,28 +124,31 @@ void rotateLeft_edge(edge_t* arr, int l, int r) void rotateRight_edge(edge_t* arr, int l, int r) // Right rotation of all array elements between l and r { + int i; edge_t temp = arr[r]; - for (int i = r; i > l; i--) + for (i = r; i > l; i--) arr[i] = arr[i - 1]; arr[l] = temp; } facecube_t* toFaceCube(cubiecube_t* cubiecube) { + int i, j, n; + signed char ori; facecube_t* fcRet = get_facecube(); - for(int i = 0; i < CORNER_COUNT; i++) { - int j = cubiecube->cp[i];// cornercubie with index j is at + for(i = 0; i < CORNER_COUNT; i++) { + j = cubiecube->cp[i];// cornercubie with index j is at // cornerposition with index i - signed char ori = cubiecube->co[i];// Orientation of this cubie - for (int n = 0; n < 3; n++) + ori = cubiecube->co[i];// Orientation of this cubie + for (n = 0; n < 3; n++) fcRet->f[cornerFacelet[i][(n + ori) % 3]] = cornerColor[j][n]; } - for(int i = 0; i < EDGE_COUNT; i++) + for(i = 0; i < EDGE_COUNT; i++) { - int j = cubiecube->ep[i];// edgecubie with index j is at edgeposition + j = cubiecube->ep[i];// edgecubie with index j is at edgeposition // with index i - signed char ori = cubiecube->eo[i];// Orientation of this cubie - for (int n = 0; n < 2; n++) + ori = cubiecube->eo[i];// Orientation of this cubie + for (n = 0; n < 2; n++) fcRet->f[edgeFacelet[i][(n + ori) % 2]] = edgeColor[j][n]; } return fcRet; @@ -150,14 +156,16 @@ facecube_t* toFaceCube(cubiecube_t* cubiecube) void cornerMultiply(cubiecube_t* cubiecube, cubiecube_t* b) { + int corn; + signed char oriA, oriB, ori; corner_t cPerm[8] = {0}; signed char cOri[8] = {0}; - for (int corn = 0; corn < CORNER_COUNT; corn++) { + for (corn = 0; corn < CORNER_COUNT; corn++) { cPerm[corn] = cubiecube->cp[b->cp[corn]]; - signed char oriA = cubiecube->co[b->cp[corn]]; - signed char oriB = b->co[corn]; - signed char ori = 0; + oriA = cubiecube->co[b->cp[corn]]; + oriB = b->co[corn]; + ori = 0; if (oriA < 3 && oriB < 3) // if both cubes are regular cubes... { @@ -188,24 +196,25 @@ void cornerMultiply(cubiecube_t* cubiecube, cubiecube_t* b) } cOri[corn] = ori; } - for(int c = 0; c < CORNER_COUNT; c++) { - cubiecube->cp[c] = cPerm[c]; - cubiecube->co[c] = cOri[c]; + for(corn = 0; corn < CORNER_COUNT; corn++) { + cubiecube->cp[corn] = cPerm[corn]; + cubiecube->co[corn] = cOri[corn]; } } void edgeMultiply(cubiecube_t* cubiecube, cubiecube_t* b) { + int edge; edge_t ePerm[12] = {0}; signed char eOri[12] = {0}; - for(int edge = 0; edge < EDGE_COUNT; edge++) { + for(edge = 0; edge < EDGE_COUNT; edge++) { ePerm[edge] = cubiecube->ep[b->ep[edge]]; eOri[edge] = (b->eo[edge] + cubiecube->eo[b->ep[edge]]) % 2; } - for(int e = 0; e < EDGE_COUNT; e++) { - cubiecube->ep[e] = ePerm[e]; - cubiecube->eo[e] = eOri[e]; + for(edge = 0; edge < EDGE_COUNT; edge++) { + cubiecube->ep[edge] = ePerm[edge]; + cubiecube->eo[edge] = eOri[edge]; } } @@ -217,13 +226,14 @@ void multiply(cubiecube_t* cubiecube, cubiecube_t* b) void invCubieCube(cubiecube_t* cubiecube, cubiecube_t* c) { - for (int edge = 0; edge < EDGE_COUNT; edge++) + int edge, corn; + for (edge = 0; edge < EDGE_COUNT; edge++) c->ep[cubiecube->ep[edge]] = edge; - for (int edge = 0; edge < EDGE_COUNT; edge++) + for (edge = 0; edge < EDGE_COUNT; edge++) c->eo[edge] = cubiecube->eo[c->ep[edge]]; - for (int corn = 0; corn < CORNER_COUNT; corn++) + for (corn = 0; corn < CORNER_COUNT; corn++) c->cp[cubiecube->cp[corn]] = corn; - for (int corn = 0; corn < CORNER_COUNT; corn++) { + for (corn = 0; corn < CORNER_COUNT; corn++) { signed char ori = cubiecube->co[c->cp[corn]]; if (ori >= 3)// Just for completeness. We do not invert mirrored // cubes in the program. @@ -239,7 +249,8 @@ void invCubieCube(cubiecube_t* cubiecube, cubiecube_t* c) short getTwist(cubiecube_t* cubiecube) { short ret = 0; - for (int i = URF; i < DRB; i++) + int i; + for (i = URF; i < DRB; i++) ret = (short) (3 * ret + cubiecube->co[i]); return ret; } @@ -247,7 +258,8 @@ short getTwist(cubiecube_t* cubiecube) void setTwist(cubiecube_t* cubiecube, short twist) { int twistParity = 0; - for (int i = DRB - 1; i >= URF; i--) { + int i; + for (i = DRB - 1; i >= URF; i--) { twistParity += cubiecube->co[i] = (signed char) (twist % 3); twist /= 3; } @@ -256,16 +268,18 @@ void setTwist(cubiecube_t* cubiecube, short twist) short getFlip(cubiecube_t* cubiecube) { + int i; short ret = 0; - for (int i = UR; i < BR; i++) + for (i = UR; i < BR; i++) ret = (short) (2 * ret + cubiecube->eo[i]); return ret; } void setFlip(cubiecube_t* cubiecube, short flip) { + int i; int flipParity = 0; - for (int i = BR - 1; i >= UR; i--) { + for (i = BR - 1; i >= UR; i--) { flipParity += cubiecube->eo[i] = (signed char) (flip % 2); flip /= 2; } @@ -274,9 +288,10 @@ void setFlip(cubiecube_t* cubiecube, short flip) short cornerParity(cubiecube_t* cubiecube) { + int i, j; int s = 0; - for (int i = DRB; i >= URF + 1; i--) - for (int j = i - 1; j >= URF; j--) + for (i = DRB; i >= URF + 1; i--) + for (j = i - 1; j >= URF; j--) if (cubiecube->cp[j] > cubiecube->cp[i]) s++; return (short) (s % 2); @@ -284,9 +299,10 @@ short cornerParity(cubiecube_t* cubiecube) short edgeParity(cubiecube_t* cubiecube) { + int i, j; int s = 0; - for (int i = BR; i >= UR + 1; i--) - for (int j = i - 1; j >= UR; j--) + for (i = BR; i >= UR + 1; i--) + for (j = i - 1; j >= UR; j--) if (cubiecube->ep[j] > cubiecube->ep[i]) s++; return (short) (s % 2); @@ -294,17 +310,17 @@ short edgeParity(cubiecube_t* cubiecube) short getFRtoBR(cubiecube_t* cubiecube) { - int a = 0, x = 0; + int a = 0, x = 0, j; + int b = 0; edge_t edge4[4] = {0}; // compute the index a < (12 choose 4) and the permutation array perm. - for (int j = BR; j >= UR; j--) + for (j = BR; j >= UR; j--) if (FR <= cubiecube->ep[j] && cubiecube->ep[j] <= BR) { a += Cnk(11 - j, x + 1); edge4[3 - x++] = cubiecube->ep[j]; } - int b = 0; - for (int j = 3; j > 0; j--)// compute the index b < 4! for the + for (j = 3; j > 0; j--)// compute the index b < 4! for the // permutation in perm { int k = 0; @@ -318,15 +334,15 @@ short getFRtoBR(cubiecube_t* cubiecube) } void setFRtoBR(cubiecube_t* cubiecube, short idx) { - int x; + int x, j, k, e; edge_t sliceEdge[4] = { FR, FL, BL, BR }; edge_t otherEdge[8] = { UR, UF, UL, UB, DR, DF, DL, DB }; int b = idx % 24; // Permutation int a = idx / 24; // Combination - for (int e = 0; e < EDGE_COUNT; e++) + for (e = 0; e < EDGE_COUNT; e++) cubiecube->ep[e] = DB;// Use UR to invalidate all edges - for (int j = 1, k; j < 4; j++)// generate permutation from index b + for (j = 1; j < 4; j++)// generate permutation from index b { k = b % (j + 1); b /= j + 1; @@ -335,30 +351,29 @@ void setFRtoBR(cubiecube_t* cubiecube, short idx) } x = 3;// generate combination and set slice edges - for (int j = UR; j <= BR; j++) + for (j = UR; j <= BR; j++) if (a - Cnk(11 - j, x + 1) >= 0) { cubiecube->ep[j] = sliceEdge[3 - x]; a -= Cnk(11 - j, x-- + 1); } x = 0; // set the remaining edges UR..DB - for (int j = UR; j <= BR; j++) + for (j = UR; j <= BR; j++) if (cubiecube->ep[j] == DB) cubiecube->ep[j] = otherEdge[x++]; } short getURFtoDLF(cubiecube_t* cubiecube) { - int a = 0, x = 0; + int a = 0, x = 0, j, b = 0; corner_t corner6[6] = {0}; // compute the index a < (8 choose 6) and the corner permutation. - for (int j = URF; j <= DRB; j++) + for (j = URF; j <= DRB; j++) if (cubiecube->cp[j] <= DLF) { a += Cnk(j, x + 1); corner6[x++] = cubiecube->cp[j]; } - int b = 0; - for (int j = 5; j > 0; j--)// compute the index b < 6! for the + for (j = 5; j > 0; j--)// compute the index b < 6! for the // permutation in corner6 { int k = 0; @@ -378,10 +393,11 @@ void setURFtoDLF(cubiecube_t* cubiecube, short idx) corner_t otherCorner[2] = { DBL, DRB }; int b = idx % 720; // Permutation int a = idx / 720; // Combination - for(int c = 0; c < CORNER_COUNT; c++) + int c, j, k; + for(c = 0; c < CORNER_COUNT; c++) cubiecube->cp[c] = DRB;// Use DRB to invalidate all corners - for (int j = 1, k; j < 6; j++)// generate permutation from index b + for (j = 1; j < 6; j++)// generate permutation from index b { k = b % (j + 1); b /= j + 1; @@ -389,13 +405,13 @@ void setURFtoDLF(cubiecube_t* cubiecube, short idx) rotateRight_corner(corner6, 0, j); } x = 5;// generate combination and set corners - for (int j = DRB; j >= 0; j--) + for (j = DRB; j >= 0; j--) if (a - Cnk(j, x + 1) >= 0) { cubiecube->cp[j] = corner6[x]; a -= Cnk(j, x-- + 1); } x = 0; - for (int j = URF; j <= DRB; j++) + for (j = URF; j <= DRB; j++) if (cubiecube->cp[j] == DRB) cubiecube->cp[j] = otherCorner[x++]; } @@ -403,16 +419,16 @@ void setURFtoDLF(cubiecube_t* cubiecube, short idx) int getURtoDF(cubiecube_t* cubiecube) { int a = 0, x = 0; + int b = 0, j; edge_t edge6[6] = {0}; // compute the index a < (12 choose 6) and the edge permutation. - for (int j = UR; j <= BR; j++) + for (j = UR; j <= BR; j++) if (cubiecube->ep[j] <= DF) { a += Cnk(j, x + 1); edge6[x++] = cubiecube->ep[j]; } - int b = 0; - for (int j = 5; j > 0; j--)// compute the index b < 6! for the + for (j = 5; j > 0; j--)// compute the index b < 6! for the // permutation in edge6 { int k = 0; @@ -427,16 +443,16 @@ int getURtoDF(cubiecube_t* cubiecube) void setURtoDF(cubiecube_t* cubiecube, int idx) { - int x; + int x, e, j, k; edge_t edge6[6] = { UR, UF, UL, UB, DR, DF }; edge_t otherEdge[6] = { DL, DB, FR, FL, BL, BR }; int b = idx % 720; // Permutation int a = idx / 720; // Combination - for(int e = 0; e < EDGE_COUNT; e++) + for(e = 0; e < EDGE_COUNT; e++) cubiecube->ep[e] = BR;// Use BR to invalidate all edges - for (int j = 1, k; j < 6; j++)// generate permutation from index b + for (j = 1; j < 6; j++)// generate permutation from index b { k = b % (j + 1); b /= j + 1; @@ -444,30 +460,29 @@ void setURtoDF(cubiecube_t* cubiecube, int idx) rotateRight_edge(edge6, 0, j); } x = 5;// generate combination and set edges - for (int j = BR; j >= 0; j--) + for (j = BR; j >= 0; j--) if (a - Cnk(j, x + 1) >= 0) { cubiecube->ep[j] = edge6[x]; a -= Cnk(j, x-- + 1); } x = 0; // set the remaining edges DL..BR - for (int j = UR; j <= BR; j++) + for (j = UR; j <= BR; j++) if (cubiecube->ep[j] == BR) cubiecube->ep[j] = otherEdge[x++]; } short getURtoUL(cubiecube_t* cubiecube) { - int a = 0, x = 0; + int a = 0, b = 0, x = 0, j; edge_t edge3[3] = {0}; // compute the index a < (12 choose 3) and the edge permutation. - for (int j = UR; j <= BR; j++) + for (j = UR; j <= BR; j++) if (cubiecube->ep[j] <= UL) { a += Cnk(j, x + 1); edge3[x++] = cubiecube->ep[j]; } - int b = 0; - for (int j = 2; j > 0; j--)// compute the index b < 3! for the + for (j = 2; j > 0; j--)// compute the index b < 3! for the // permutation in edge3 { int k = 0; @@ -482,22 +497,22 @@ short getURtoUL(cubiecube_t* cubiecube) void setURtoUL(cubiecube_t* cubiecube, short idx) { - int x; + int x, e, j, k; edge_t edge3[3] = { UR, UF, UL }; int b = idx % 6; // Permutation int a = idx / 6; // Combination - for(int e = 0; e < EDGE_COUNT; e++) { + for(e = 0; e < EDGE_COUNT; e++) { cubiecube->ep[e] = BR;// Use BR to invalidate all edges } - for (int j = 1, k; j < 3; j++) {// generate permutation from index b + for (j = 1; j < 3; j++) {// generate permutation from index b k = b % (j + 1); b /= j + 1; while (k-- > 0) rotateRight_edge(edge3, 0, j); } x = 2;// generate combination and set edges - for (int j = BR; j >= 0; j--) { + for (j = BR; j >= 0; j--) { if (a - Cnk(j, x + 1) >= 0) { cubiecube->ep[j] = edge3[x]; a -= Cnk(j, x-- + 1); @@ -507,17 +522,16 @@ void setURtoUL(cubiecube_t* cubiecube, short idx) short getUBtoDF(cubiecube_t* cubiecube) { - int a = 0, x = 0; + int a = 0, x = 0, b = 0, j; edge_t edge3[3] = {0}; // compute the index a < (12 choose 3) and the edge permutation. - for (int j = UR; j <= BR; j++) + for (j = UR; j <= BR; j++) if (UB <= cubiecube->ep[j] && cubiecube->ep[j] <= DF) { a += Cnk(j, x + 1); edge3[x++] = cubiecube->ep[j]; } - int b = 0; - for (int j = 2; j > 0; j--)// compute the index b < 3! for the + for (j = 2; j > 0; j--)// compute the index b < 3! for the // permutation in edge3 { int k = 0; @@ -532,14 +546,14 @@ short getUBtoDF(cubiecube_t* cubiecube) void setUBtoDF(cubiecube_t* cubiecube, short idx) { - int x; + int x, e, j, k; edge_t edge3[3] = { UB, DR, DF }; int b = idx % 6; // Permutation int a = idx / 6; // Combination - for (int e = 0; e < EDGE_COUNT; e++) + for (e = 0; e < EDGE_COUNT; e++) cubiecube->ep[e] = BR;// Use BR to invalidate all edges - for (int j = 1, k; j < 3; j++)// generate permutation from index b + for (j = 1; j < 3; j++)// generate permutation from index b { k = b % (j + 1); b /= j + 1; @@ -547,7 +561,7 @@ void setUBtoDF(cubiecube_t* cubiecube, short idx) rotateRight_edge(edge3, 0, j); } x = 2;// generate combination and set edges - for (int j = BR; j >= 0; j--) + for (j = BR; j >= 0; j--) if (a - Cnk(j, x + 1) >= 0) { cubiecube->ep[j] = edge3[x]; a -= Cnk(j, x-- + 1); @@ -557,10 +571,10 @@ void setUBtoDF(cubiecube_t* cubiecube, short idx) int getURFtoDLB(cubiecube_t* cubiecube) { corner_t perm[8] = {0}; - int b = 0; - for (int i = 0; i < 8; i++) + int b = 0, i, j; + for (i = 0; i < 8; i++) perm[i] = cubiecube->cp[i]; - for (int j = 7; j > 0; j--)// compute the index b < 8! for the permutation in perm + for (j = 7; j > 0; j--)// compute the index b < 8! for the permutation in perm { int k = 0; while (perm[j] != j) { @@ -575,25 +589,26 @@ int getURFtoDLB(cubiecube_t* cubiecube) void setURFtoDLB(cubiecube_t* cubiecube, int idx) { corner_t perm[8] = { URF, UFL, ULB, UBR, DFR, DLF, DBL, DRB }; - int k; - for (int j = 1; j < 8; j++) { + int k, j; + int x = 7;// set corners + for (j = 1; j < 8; j++) { k = idx % (j + 1); idx /= j + 1; while (k-- > 0) rotateRight_corner(perm, 0, j); } - int x = 7;// set corners - for (int j = 7; j >= 0; j--) + + for (j = 7; j >= 0; j--) cubiecube->cp[j] = perm[x--]; } int getURtoBR(cubiecube_t* cubiecube) { edge_t perm[12] = {0}; - int b = 0; - for (int i = 0; i < 12; i++) + int b = 0, i, j; + for (i = 0; i < 12; i++) perm[i] = cubiecube->ep[i]; - for (int j = 11; j > 0; j--)// compute the index b < 12! for the permutation in perm + for (j = 11; j > 0; j--)// compute the index b < 12! for the permutation in perm { int k = 0; while (perm[j] != j) { @@ -608,42 +623,43 @@ int getURtoBR(cubiecube_t* cubiecube) void setURtoBR(cubiecube_t* cubiecube, int idx) { edge_t perm[12] = { UR, UF, UL, UB, DR, DF, DL, DB, FR, FL, BL, BR }; - int k; - for (int j = 1; j < 12; j++) { + int k, j; + int x = 11;// set edges + for (j = 1; j < 12; j++) { k = idx % (j + 1); idx /= j + 1; while (k-- > 0) rotateRight_edge(perm, 0, j); } - int x = 11;// set edges - for (int j = 11; j >= 0; j--) + for (j = 11; j >= 0; j--) cubiecube->ep[j] = perm[x--]; } int verify(cubiecube_t* cubiecube) { - int sum = 0; + int sum = 0, e, i, c; int edgeCount[12] = {0}; - for(int e = 0; e < EDGE_COUNT; e++) + int cornerCount[8] = {0}; + + for(e = 0; e < EDGE_COUNT; e++) edgeCount[cubiecube->ep[e]]++; - for (int i = 0; i < 12; i++) + for (i = 0; i < 12; i++) if (edgeCount[i] != 1) return -2; - for (int i = 0; i < 12; i++) + for (i = 0; i < 12; i++) sum += cubiecube->eo[i]; if (sum % 2 != 0) return -3; - int cornerCount[8] = {0}; - for(int c = 0; c < CORNER_COUNT; c++) + for(c = 0; c < CORNER_COUNT; c++) cornerCount[cubiecube->cp[c]]++; - for (int i = 0; i < 8; i++) + for (i = 0; i < 8; i++) if (cornerCount[i] != 1) return -4;// missing corners sum = 0; - for (int i = 0; i < 8; i++) + for (i = 0; i < 8; i++) sum += cubiecube->co[i]; if (sum % 3 != 0) return -5;// twisted corner @@ -656,11 +672,12 @@ int verify(cubiecube_t* cubiecube) int getURtoDF_standalone(short idx1, short idx2) { + int res, i; cubiecube_t *a = get_cubiecube(); cubiecube_t *b = get_cubiecube(); setURtoUL(a, idx1); setUBtoDF(b, idx2); - for (int i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { if (a->ep[i] != BR) { if (b->ep[i] != BR) {// collision return -1; @@ -669,9 +686,8 @@ int getURtoDF_standalone(short idx1, short idx2) } } } - int res = getURtoDF(b); + res = getURtoDF(b); free(a); free(b); return res; } - diff --git a/kociemba/ckociemba/facecube.c b/kociemba/ckociemba/facecube.c index cfee5de..a555999 100644 --- a/kociemba/ckociemba/facecube.c +++ b/kociemba/ckociemba/facecube.c @@ -27,8 +27,9 @@ facecube_t* get_facecube() facecube_t* get_facecube_fromstring(char* cubeString) { + int i; facecube_t* res = (facecube_t *) calloc(1, sizeof(facecube_t)); - for (int i = 0; i < 54; i++) { + for (i = 0; i < 54; i++) { switch(cubeString[i]) { case 'U': res->f[i] = U; @@ -55,7 +56,8 @@ facecube_t* get_facecube_fromstring(char* cubeString) void to_String(facecube_t* facecube, char* res) { - for (int i = 0; i < 54; i++) + int i; + for (i = 0; i < 54; i++) switch(facecube->f[i]) { case U: res[i] = 'U'; @@ -81,14 +83,16 @@ void to_String(facecube_t* facecube, char* res) cubiecube_t* toCubieCube(facecube_t* facecube) { + int i, j; signed char ori; + color_t col1, col2; cubiecube_t* ccRet = (cubiecube_t*) calloc(1, sizeof(cubiecube_t)); - for (int i = 0; i < 8; i++) + for (i = 0; i < 8; i++) ccRet->cp[i] = URF;// invalidate corners - for (int i = 0; i < 12; i++) + for (i = 0; i < 12; i++) ccRet->ep[i] = UR;// and edges - color_t col1, col2; - for(int i = 0; i < CORNER_COUNT; i++) { + + for(i = 0; i < CORNER_COUNT; i++) { // get the colors of the cubie at corner i, starting with U/D for (ori = 0; ori < 3; ori++) if (facecube->f[cornerFacelet[i][ori]] == U || facecube->f[cornerFacelet[i][ori]] == D) @@ -96,7 +100,7 @@ cubiecube_t* toCubieCube(facecube_t* facecube) col1 = facecube->f[cornerFacelet[i][(ori + 1) % 3]]; col2 = facecube->f[cornerFacelet[i][(ori + 2) % 3]]; - for (int j = 0; j < CORNER_COUNT; j++) { + for (j = 0; j < CORNER_COUNT; j++) { if (col1 == cornerColor[j][1] && col2 == cornerColor[j][2]) { // in cornerposition i we have cornercubie j ccRet->cp[i] = j; @@ -106,8 +110,8 @@ cubiecube_t* toCubieCube(facecube_t* facecube) } } - for (int i = 0; i < EDGE_COUNT; i++) { - for (int j = 0; j < EDGE_COUNT; j++) { + for (i = 0; i < EDGE_COUNT; i++) { + for (j = 0; j < EDGE_COUNT; j++) { if (facecube->f[edgeFacelet[i][0]] == edgeColor[j][0] && facecube->f[edgeFacelet[i][1]] == edgeColor[j][1]) { ccRet->ep[i] = j; diff --git a/kociemba/ckociemba/include/coordcube.h b/kociemba/ckociemba/include/coordcube.h index cf16181..badc47f 100644 --- a/kociemba/ckociemba/include/coordcube.h +++ b/kociemba/ckociemba/include/coordcube.h @@ -33,7 +33,7 @@ typedef struct { } coordcube_t; // ******************************************Phase 1 move tables***************************************************** - + // Move table for the twists of the corners // twist < 2187 in phase 2. // twist = 0 in phase 2. @@ -109,8 +109,5 @@ signed char getPruning(signed char *table, int index); coordcube_t* get_coordcube(cubiecube_t* cubiecube); void move(coordcube_t* coordcube, int m, const char *cache_dir); -int check_cached_table(const char* name, void* ptr, int len, const char *cache_dir); -void dump_to_file(void* ptr, int len, const char* name, const char *cache_dir); -void read_from_file(void* ptr, int len, const char* name); #endif diff --git a/kociemba/ckociemba/include/prunetable_helpers.h b/kociemba/ckociemba/include/prunetable_helpers.h new file mode 100644 index 0000000..94184d1 --- /dev/null +++ b/kociemba/ckociemba/include/prunetable_helpers.h @@ -0,0 +1,21 @@ +#ifndef PRUNETABLE_HELPERS_H +#define PRUNETABLE_HELPERS_H + +#if defined(_WIN32) +#include +#include "direct.h" +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ +#define access _access +#else +#include +#endif + +int make_dir(const char *cache_dir); +int check_cached_table(const char* name, void* ptr, int len, const char *cache_dir); +void dump_to_file(void* ptr, int len, const char* name, const char *cache_dir); +void read_from_file(void* ptr, int len, const char* name); + +#endif diff --git a/kociemba/ckociemba/prunetable_helpers.c b/kociemba/ckociemba/prunetable_helpers.c new file mode 100644 index 0000000..7b3993a --- /dev/null +++ b/kociemba/ckociemba/prunetable_helpers.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include "prunetable_helpers.h" + +char * join_path(const char *dir, const char *filename) +{ + size_t path_len = strnlen(dir, 500); + char *fpath = calloc(path_len + 32, 1); + if (path_len == 500) { + return NULL; + } + strcpy(fpath, dir); + strcat(fpath, "/"); + strncat(fpath, filename, 30); + return fpath; +} + +int check_cached_table(const char* name, void* ptr, int len, const char *cache_dir) +{ + int res = 0; + char *fname = join_path(cache_dir, name); + if (fname == NULL) { + fprintf(stderr, "Path to cache tables is too long\n"); + return -1; + } + + if (access(fname, F_OK | R_OK) != -1) { + // fprintf(stderr, "Found cache for %s. Loading...", name); + read_from_file(ptr, len, fname); + // fprintf(stderr, "done.\n"); + res = 0; + } else { + fprintf(stderr, "Cache table %s was not found. Recalculating.\n", fname); + res = 1; + } + free(fname); + return res; +} + +void read_from_file(void* ptr, int len, const char* name) +{ + FILE* f = fopen(name, "rb"); + if (!fread(ptr, len, 1, f)) + ((void)0); // suppress -Wunused-result warning + fclose(f); +} + +int make_dir(const char *cache_dir) +{ +#if defined(_WIN32) + return _mkdir(cache_dir); +#else + return mkdir(cache_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif +} + +void dump_to_file(void* ptr, int len, const char* name, const char *cache_dir) +{ + int status; + status = make_dir(cache_dir); + if (status == 0 || errno == EEXIST) { + char *fname = join_path(cache_dir, name); + if (fname == NULL) { + fprintf(stderr, "Path to cache tables is too long\n"); + } else { + FILE* f = fopen(fname, "wb"); + fwrite(ptr, len, 1, f); + free(fname); + fclose(f); + } + } else { + fprintf(stderr, "cannot create cache tables directory\n"); + } +} diff --git a/kociemba/ckociemba/search.c b/kociemba/ckociemba/search.c index ca0e0bb..7123b0a 100644 --- a/kociemba/ckociemba/search.c +++ b/kociemba/ckociemba/search.c @@ -1,5 +1,6 @@ #include #include +#include #include "search.h" #include "color.h" #include "facecube.h" @@ -11,8 +12,8 @@ char* solutionToString(search_t* search, int length, int depthPhase1) { char* s = (char*) calloc(length * 3 + 5, 1); - int cur = 0; - for (int i = 0; i < length; i++) { + int cur = 0, i; + for (i = 0; i < length; i++) { switch (search->ax[i]) { case 0: s[cur++] = 'U'; @@ -57,17 +58,24 @@ char* solutionToString(search_t* search, int length, int depthPhase1) char* solution(char* facelets, int maxDepth, long timeOut, int useSeparator, const char* cache_dir) { - if (PRUNING_INITED == 0) { - initPruning(cache_dir); - } - search_t* search = (search_t*) calloc(1, sizeof(search_t)); - - int s; + facecube_t* fc; + cubiecube_t* cc; + coordcube_t* c; + + int s, i; + int mv, n; + int busy; + int depthPhase1; + time_t tStart; // +++++++++++++++++++++check for wrong input +++++++++++++++++++++++++++++ int count[6] = {0}; - for (int i = 0; i < 54; i++) + if (PRUNING_INITED == 0) { + initPruning(cache_dir); + } + + for (i = 0; i < 54; i++) switch(facelets[i]) { case 'U': count[U]++; @@ -89,21 +97,21 @@ char* solution(char* facelets, int maxDepth, long timeOut, int useSeparator, con break; } - for (int i = 0; i < 6; i++) + for (i = 0; i < 6; i++) if (count[i] != 9) { free(search); return NULL; } - facecube_t* fc = get_facecube_fromstring(facelets); - cubiecube_t* cc = toCubieCube(fc); + fc = get_facecube_fromstring(facelets); + cc = toCubieCube(fc); if ((s = verify(cc)) != 0) { free(search); return NULL; } // +++++++++++++++++++++++ initialization +++++++++++++++++++++++++++++++++ - coordcube_t* c = get_coordcube(cc); + c = get_coordcube(cc); search->po[0] = 0; search->ax[0] = 0; @@ -117,11 +125,12 @@ char* solution(char* facelets, int maxDepth, long timeOut, int useSeparator, con search->UBtoDF[0] = c->UBtoDF; search->minDistPhase1[1] = 1;// else failure for depth=1, n=0 - int mv = 0, n = 0; - int busy = 0; - int depthPhase1 = 1; + mv = 0; + n = 0; + busy = 0; + depthPhase1 = 1; - long tStart = time(NULL); + tStart = time(NULL); // +++++++++++++++++++ Main loop ++++++++++++++++++++++++++++++++++++++++++ do { @@ -182,10 +191,10 @@ char* solution(char* facelets, int maxDepth, long timeOut, int useSeparator, con if (n == depthPhase1 - 1 && (s = totalDepth(search, depthPhase1, maxDepth)) >= 0) { if (s == depthPhase1 || (search->ax[depthPhase1 - 1] != search->ax[depthPhase1] && search->ax[depthPhase1 - 1] != search->ax[depthPhase1] + 3)) { + char* res; free((void*) fc); free((void*) cc); free((void*) c); - char* res; if (useSeparator) { res = solutionToString(search, s, depthPhase1); } else { @@ -198,14 +207,16 @@ char* solution(char* facelets, int maxDepth, long timeOut, int useSeparator, con } } while (1); - } int totalDepth(search_t* search, int depthPhase1, int maxDepth) { - int mv = 0, d1 = 0, d2 = 0; + int mv = 0, d1 = 0, d2 = 0, i; int maxDepthPhase2 = MIN(10, maxDepth - depthPhase1);// Allow only max 10 moves in phase2 - for (int i = 0; i < depthPhase1; i++) { + int depthPhase2; + int n; + int busy; + for (i = 0; i < depthPhase1; i++) { mv = 3 * search->ax[i] + search->po[i] - 1; // System.out.format("%d %d %d %d\n", i, mv, ax[i], po[i]); search->URFtoDLF[i + 1] = URFtoDLF_Move[search->URFtoDLF[i]][mv]; @@ -217,7 +228,7 @@ int totalDepth(search_t* search, int depthPhase1, int maxDepth) (N_SLICE2 * search->URFtoDLF[depthPhase1] + search->FRtoBR[depthPhase1]) * 2 + search->parity[depthPhase1])) > maxDepthPhase2) return -1; - for (int i = 0; i < depthPhase1; i++) { + for (i = 0; i < depthPhase1; i++) { mv = 3 * search->ax[i] + search->po[i] - 1; search->URtoUL[i + 1] = URtoUL_Move[search->URtoUL[i]][mv]; search->UBtoDF[i + 1] = UBtoDF_Move[search->UBtoDF[i]][mv]; @@ -233,9 +244,9 @@ int totalDepth(search_t* search, int depthPhase1, int maxDepth) // now set up search - int depthPhase2 = 1; - int n = depthPhase1; - int busy = 0; + depthPhase2 = 1; + n = depthPhase1; + busy = 0; search->po[depthPhase1] = 0; search->ax[depthPhase1] = 0; search->minDistPhase2[n + 1] = 1;// else failure for depthPhase2=1, n=0 @@ -303,6 +314,7 @@ int totalDepth(search_t* search, int depthPhase1, int maxDepth) void patternize(char* facelets, char* pattern, char* patternized) { + facecube_t* fc; facecube_t* start_fc = get_facecube_fromstring(facelets); facecube_t* pattern_fc = get_facecube_fromstring(pattern); cubiecube_t* start_cc = toCubieCube(start_fc); @@ -310,7 +322,7 @@ void patternize(char* facelets, char* pattern, char* patternized) cubiecube_t* inv_pattern_cc = get_cubiecube(); invCubieCube(pattern_cc, inv_pattern_cc); multiply(inv_pattern_cc, start_cc); - facecube_t* fc = toFaceCube(inv_pattern_cc); + fc = toFaceCube(inv_pattern_cc); to_String(fc, patternized); free(start_fc); free(pattern_fc); From ea1a690e585100f93e32072eca8c5181085d0e9a Mon Sep 17 00:00:00 2001 From: Maxim Tsoy Date: Sun, 18 Mar 2018 22:27:48 +0100 Subject: [PATCH 2/8] add new python versions to the travis config --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7bfd3a3..14be915 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,10 @@ python: - "3.3" - "3.4" - "3.5" - - "3.5-dev" # 3.5 development branch - - "nightly" # currently points to 3.6-dev + - "3.5-dev" # 3.5 development branch + - "3.6" + - "3.6-dev" # 3.6 development branch + - "3.7-dev" # 3.7 development branch - "pypy" # command to install dependencies install: "python setup.py install" From 911b6842a93f276f6310209567f1880afaa37ae4 Mon Sep 17 00:00:00 2001 From: Maxim Tsoy Date: Sun, 18 Mar 2018 22:32:34 +0100 Subject: [PATCH 3/8] try to fix travis builds --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 14be915..860a9bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,8 @@ python: - "3.7-dev" # 3.7 development branch - "pypy" # command to install dependencies -install: "python setup.py install" +install: + - pip install setuptools_scm + - python setup.py install # command to run tests script: python setup.py test From 017ae21c8a31b4fdf94df244c35d1b88e8b58a98 Mon Sep 17 00:00:00 2001 From: Maxim Tsoy Date: Sun, 18 Mar 2018 22:36:55 +0100 Subject: [PATCH 4/8] install setuptools before the package --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 860a9bf..8bd250b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ python: - "pypy" # command to install dependencies install: - - pip install setuptools_scm + - pip install -U setuptools - python setup.py install # command to run tests script: python setup.py test From a547bdf84c6056244cb6fb23e281b481cdb3f32a Mon Sep 17 00:00:00 2001 From: Maxim Tsoy Date: Sun, 18 Mar 2018 22:45:48 +0100 Subject: [PATCH 5/8] don't test on 2.6 and 3.2 (setuptools incompatibilities) --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8bd250b..f61744a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: python python: - - "2.6" - "2.7" - - "3.2" - "3.3" - "3.4" - "3.5" From f4f9ca08a6aa7af75ed13f84de5f98271e8fcc57 Mon Sep 17 00:00:00 2001 From: Maxim Tsoy Date: Sun, 18 Mar 2018 23:22:18 +0100 Subject: [PATCH 6/8] Update readme --- README.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ed1022b..f2cc727 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,27 @@ Original Java implementation can be found here: http://kociemba.org/download.htm These ports are pretty straightforward (not to say dumb) and most probably can be optimized. But they have been extensively tested in our Rubik's cube solving machines ([FAC System Solver](https://blog.zok.pw/hacking/2015/08/18/fac-rubik-solver/) and [Meccano Rubik's Shrine](http://blog.zok.pw/hacking/2016/08/12/meccano-rubiks-shrine/)), so be confident the algorithm is working. -## Installation and usage +## Installation This package is published on PyPI and can be installed with: ```$ pip install kociemba``` -It was tested under Python 2.7 and 3.5. +It was tested under Python 2.7 and 3.3+. -On some systems you might need to install libffi system library beforehand. For example, on Debian-based distributions (e.g. Raspbian) you would run `sudo apt-get install libffi-dev`. +### Unix-based systems + +You might need to install libffi system library beforehand. For example, on Debian-based distributions (e.g. Raspbian) you would run `sudo apt-get install libffi-dev`. + +### Windows + +Library should work on Windows, however it is not automatically tested at this moment: Travis CI [doesn't have windows support](https://github.com/travis-ci/travis-ci/issues/2104). + +Normal `pip install kociemba` (or `pip3 install kociemba` for Python 3.3+) should work, but you will need to install free build tools from Microsoft first: check the following links: + +- for Python 2.7: https://www.microsoft.com/en-us/download/details.aspx?id=44266 +- for Python 3: https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017 + +## Usage The package exposes just one function ```solve()```, which accepts a cube definition string and returns a solution string in standard notation (see below). Optional second argument allows solving to a specific pattern. @@ -69,7 +82,7 @@ So, for example, a definition of a solved cube would be `UUUUUUUUURRRRRRRRRFFFFF Solution string consists of space-separated parts, each of them represents a single move: * A single letter by itself means to turn that face clockwise 90 degrees. * A letter followed by an apostrophe means to turn that face counterclockwise 90 degrees. -* A letter with the number 2 after it means to turn that face 180 degrees. +* A letter with the number 2 after it means to turn that face 180 degrees. e.g. **R U R’ U R U2 R’ U** From f49a21a9129db436c74dfdbf818fd4e1280679ce Mon Sep 17 00:00:00 2001 From: Maxim Tsoy Date: Sun, 18 Mar 2018 23:23:52 +0100 Subject: [PATCH 7/8] fix punctuation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2cc727..e8d8088 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ You might need to install libffi system library beforehand. For example, on Debi Library should work on Windows, however it is not automatically tested at this moment: Travis CI [doesn't have windows support](https://github.com/travis-ci/travis-ci/issues/2104). -Normal `pip install kociemba` (or `pip3 install kociemba` for Python 3.3+) should work, but you will need to install free build tools from Microsoft first: check the following links: +Normal `pip install kociemba` (or `pip3 install kociemba` for Python 3.3+) should work, but you will need to install free build tools from Microsoft first. Check the following links: - for Python 2.7: https://www.microsoft.com/en-us/download/details.aspx?id=44266 - for Python 3: https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017 From bf3a4db6f1d06e019213905fee9910570d8ba32f Mon Sep 17 00:00:00 2001 From: Maxim Tsoy Date: Sun, 18 Mar 2018 23:29:06 +0100 Subject: [PATCH 8/8] add special thanks section --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index e8d8088..0dab02c 100644 --- a/README.md +++ b/README.md @@ -97,3 +97,7 @@ When possible, `kociemba` will use C implementation under the hood. If something To run the tests, clone the repository and run: ```$ python setup.py test``` + +## Thanks to + +- @jarheadjoe for his contribution to Windows support