diff options
Diffstat (limited to 'cube.c')
| -rw-r--r-- | cube.c | 248 |
1 files changed, 85 insertions, 163 deletions
| @@ -1077,82 +1077,6 @@ previous sections, while some other operate directly on the cube. | |||
| 1077 | invertco_fast(compose_fast(compose_fast(_trans_cube_ ## T, c), \ | 1077 | invertco_fast(compose_fast(compose_fast(_trans_cube_ ## T, c), \ |
| 1078 | _trans_cube_ ## T ## _inverse)) | 1078 | _trans_cube_ ## T ## _inverse)) |
| 1079 | 1079 | ||
| 1080 | #ifdef MOVE_TRANS_LOOP_UNROLL | ||
| 1081 | #define _foreach_move(_m, _c, _d, instruction) \ | ||
| 1082 | _m = U; _d = _move(U, _c); instruction \ | ||
| 1083 | _m = U2; _d = _move(U2, _c); instruction \ | ||
| 1084 | _m = U3; _d = _move(U3, _c); instruction \ | ||
| 1085 | _m = D; _d = _move(D, _c); instruction \ | ||
| 1086 | _m = D2; _d = _move(D2, _c); instruction \ | ||
| 1087 | _m = D3; _d = _move(D3, _c); instruction \ | ||
| 1088 | _m = R; _d = _move(R, _c); instruction \ | ||
| 1089 | _m = R2; _d = _move(R2, _c); instruction \ | ||
| 1090 | _m = R3; _d = _move(R3, _c); instruction \ | ||
| 1091 | _m = L; _d = _move(L, _c); instruction \ | ||
| 1092 | _m = L2; _d = _move(L2, _c); instruction \ | ||
| 1093 | _m = L3; _d = _move(L3, _c); instruction \ | ||
| 1094 | _m = F; _d = _move(F, _c); instruction \ | ||
| 1095 | _m = F2; _d = _move(F2, _c); instruction \ | ||
| 1096 | _m = F3; _d = _move(F3, _c); instruction \ | ||
| 1097 | _m = B; _d = _move(B, _c); instruction \ | ||
| 1098 | _m = B2; _d = _move(B2, _c); instruction \ | ||
| 1099 | _m = B3; _d = _move(B3, _c); instruction | ||
| 1100 | #define _foreach_trans(_t, _c, _d, instruction) \ | ||
| 1101 | _t = UFr; _d = _trans_rotation(UFr, _c); instruction \ | ||
| 1102 | _t = ULr; _d = _trans_rotation(ULr, _c); instruction \ | ||
| 1103 | _t = UBr; _d = _trans_rotation(UBr, _c); instruction \ | ||
| 1104 | _t = URr; _d = _trans_rotation(URr, _c); instruction \ | ||
| 1105 | _t = DFr; _d = _trans_rotation(DFr, _c); instruction \ | ||
| 1106 | _t = DLr; _d = _trans_rotation(DLr, _c); instruction \ | ||
| 1107 | _t = DBr; _d = _trans_rotation(DBr, _c); instruction \ | ||
| 1108 | _t = DRr; _d = _trans_rotation(DRr, _c); instruction \ | ||
| 1109 | _t = RUr; _d = _trans_rotation(RUr, _c); instruction \ | ||
| 1110 | _t = RFr; _d = _trans_rotation(RFr, _c); instruction \ | ||
| 1111 | _t = RDr; _d = _trans_rotation(RDr, _c); instruction \ | ||
| 1112 | _t = RBr; _d = _trans_rotation(RBr, _c); instruction \ | ||
| 1113 | _t = LUr; _d = _trans_rotation(LUr, _c); instruction \ | ||
| 1114 | _t = LFr; _d = _trans_rotation(LFr, _c); instruction \ | ||
| 1115 | _t = LDr; _d = _trans_rotation(LDr, _c); instruction \ | ||
| 1116 | _t = LBr; _d = _trans_rotation(LBr, _c); instruction \ | ||
| 1117 | _t = FUr; _d = _trans_rotation(FUr, _c); instruction \ | ||
| 1118 | _t = FRr; _d = _trans_rotation(FRr, _c); instruction \ | ||
| 1119 | _t = FDr; _d = _trans_rotation(FDr, _c); instruction \ | ||
| 1120 | _t = FLr; _d = _trans_rotation(FLr, _c); instruction \ | ||
| 1121 | _t = BUr; _d = _trans_rotation(BUr, _c); instruction \ | ||
| 1122 | _t = BRr; _d = _trans_rotation(BRr, _c); instruction \ | ||
| 1123 | _t = BDr; _d = _trans_rotation(BDr, _c); instruction \ | ||
| 1124 | _t = BLr; _d = _trans_rotation(BLr, _c); instruction \ | ||
| 1125 | _t = UFm; _d = _trans_mirrored(UFm, _c); instruction \ | ||
| 1126 | _t = ULm; _d = _trans_mirrored(ULm, _c); instruction \ | ||
| 1127 | _t = UBm; _d = _trans_mirrored(UBm, _c); instruction \ | ||
| 1128 | _t = URm; _d = _trans_mirrored(URm, _c); instruction \ | ||
| 1129 | _t = DFm; _d = _trans_mirrored(DFm, _c); instruction \ | ||
| 1130 | _t = DLm; _d = _trans_mirrored(DLm, _c); instruction \ | ||
| 1131 | _t = DBm; _d = _trans_mirrored(DBm, _c); instruction \ | ||
| 1132 | _t = DRm; _d = _trans_mirrored(DRm, _c); instruction \ | ||
| 1133 | _t = RUm; _d = _trans_mirrored(RUm, _c); instruction \ | ||
| 1134 | _t = RFm; _d = _trans_mirrored(RFm, _c); instruction \ | ||
| 1135 | _t = RDm; _d = _trans_mirrored(RDm, _c); instruction \ | ||
| 1136 | _t = RBm; _d = _trans_mirrored(RBm, _c); instruction \ | ||
| 1137 | _t = LUm; _d = _trans_mirrored(LUm, _c); instruction \ | ||
| 1138 | _t = LFm; _d = _trans_mirrored(LFm, _c); instruction \ | ||
| 1139 | _t = LDm; _d = _trans_mirrored(LDm, _c); instruction \ | ||
| 1140 | _t = LBm; _d = _trans_mirrored(LBm, _c); instruction \ | ||
| 1141 | _t = FUm; _d = _trans_mirrored(FUm, _c); instruction \ | ||
| 1142 | _t = FRm; _d = _trans_mirrored(FRm, _c); instruction \ | ||
| 1143 | _t = FDm; _d = _trans_mirrored(FDm, _c); instruction \ | ||
| 1144 | _t = FLm; _d = _trans_mirrored(FLm, _c); instruction \ | ||
| 1145 | _t = BUm; _d = _trans_mirrored(BUm, _c); instruction \ | ||
| 1146 | _t = BRm; _d = _trans_mirrored(BRm, _c); instruction \ | ||
| 1147 | _t = BDm; _d = _trans_mirrored(BDm, _c); instruction \ | ||
| 1148 | _t = BLm; _d = _trans_mirrored(BLm, _c); instruction | ||
| 1149 | #else | ||
| 1150 | #define _foreach_move(_m, _c, _d, instruction) \ | ||
| 1151 | for (_m = 0; _m < 18; _m++) { _d = move(_c, _m); instruction } | ||
| 1152 | #define _foreach_trans(_t, _c, _d, instruction) \ | ||
| 1153 | for (_t = 0; _t < 48; _t++) { _d = transform(_c, _t); instruction } | ||
| 1154 | #endif | ||
| 1155 | |||
| 1156 | _static int permsign(uint8_t *, int); | 1080 | _static int permsign(uint8_t *, int); |
| 1157 | _static uint8_t readco(const char *); | 1081 | _static uint8_t readco(const char *); |
| 1158 | _static uint8_t readcp(const char *); | 1082 | _static uint8_t readcp(const char *); |
| @@ -1909,10 +1833,36 @@ This section contains methods to work with moves and arrays of moves. They | |||
| 1909 | do not rely on the cube structure. | 1833 | do not rely on the cube structure. |
| 1910 | ******************************************************************************/ | 1834 | ******************************************************************************/ |
| 1911 | 1835 | ||
| 1836 | _static_inline bool allowednextmove(uint8_t *, uint8_t); | ||
| 1912 | _static_inline uint8_t inverse_trans(uint8_t); | 1837 | _static_inline uint8_t inverse_trans(uint8_t); |
| 1913 | _static_inline uint8_t movebase(uint8_t); | 1838 | _static_inline uint8_t movebase(uint8_t); |
| 1914 | _static_inline uint8_t moveaxis(uint8_t); | 1839 | _static_inline uint8_t moveaxis(uint8_t); |
| 1915 | 1840 | ||
| 1841 | _static bool | ||
| 1842 | allowednextmove(uint8_t *moves, uint8_t n) | ||
| 1843 | { | ||
| 1844 | uint8_t base[3], axis[3]; | ||
| 1845 | |||
| 1846 | if (n < 2) | ||
| 1847 | return true; | ||
| 1848 | |||
| 1849 | base[0] = movebase(moves[n-1]); | ||
| 1850 | axis[0] = moveaxis(moves[n-1]); | ||
| 1851 | base[1] = movebase(moves[n-2]); | ||
| 1852 | axis[1] = moveaxis(moves[n-2]); | ||
| 1853 | |||
| 1854 | if (base[0] == base[1] || (axis[0] == axis[1] && base[0] < base[1])) | ||
| 1855 | return false; | ||
| 1856 | |||
| 1857 | if (n == 2) | ||
| 1858 | return true; | ||
| 1859 | |||
| 1860 | base[2] = movebase(moves[n-3]); | ||
| 1861 | axis[2] = moveaxis(moves[n-3]); | ||
| 1862 | |||
| 1863 | return axis[1] != axis[2] || base[0] != base[2]; | ||
| 1864 | } | ||
| 1865 | |||
| 1916 | _static_inline uint8_t | 1866 | _static_inline uint8_t |
| 1917 | inverse_trans(uint8_t t) | 1867 | inverse_trans(uint8_t t) |
| 1918 | { | 1868 | { |
| @@ -1937,6 +1887,7 @@ Section: auxiliary procedures for H48 optimal solver (temporary) | |||
| 1937 | 1887 | ||
| 1938 | typedef struct { | 1888 | typedef struct { |
| 1939 | cube_fast_t cube; | 1889 | cube_fast_t cube; |
| 1890 | uint8_t *moves; | ||
| 1940 | uint8_t nmoves; | 1891 | uint8_t nmoves; |
| 1941 | uint8_t depth; | 1892 | uint8_t depth; |
| 1942 | uint8_t h; | 1893 | uint8_t h; |
| @@ -1944,15 +1895,14 @@ typedef struct { | |||
| 1944 | uint16_t *nclasses; | 1895 | uint16_t *nclasses; |
| 1945 | uint32_t *cocsepdata; | 1896 | uint32_t *cocsepdata; |
| 1946 | uint32_t *buf32; | 1897 | uint32_t *buf32; |
| 1947 | bool *visited; | ||
| 1948 | } dfsarg_gendata_t; | 1898 | } dfsarg_gendata_t; |
| 1949 | 1899 | ||
| 1950 | _static size_t gendata_cocsep(void *); | 1900 | _static size_t gendata_cocsep(void *); |
| 1951 | _static uint32_t dfs_cocsep( /* TODO: use dfsarg */ | 1901 | _static uint32_t gendata_cocsep_dfs( /* TODO: use dfsarg */ |
| 1952 | cube_fast_t, uint8_t, uint8_t, uint16_t *, uint32_t *, bool *); | 1902 | cube_fast_t, uint8_t, uint8_t, uint16_t *, uint32_t *, bool *); |
| 1953 | 1903 | ||
| 1954 | _static size_t gendata_eoesep(uint8_t, uint8_t, const void *, void *); | 1904 | _static size_t gendata_eoesep(uint8_t, uint8_t, const void *, void *); |
| 1955 | _static uint32_t dfs_eoesep(dfsarg_gendata_t *); | 1905 | _static uint32_t gendata_eoesep_dfs(dfsarg_gendata_t *); |
| 1956 | 1906 | ||
| 1957 | _static_inline uint8_t get_h48_pval(const uint32_t *, int64_t, uint8_t); | 1907 | _static_inline uint8_t get_h48_pval(const uint32_t *, int64_t, uint8_t); |
| 1958 | _static_inline void set_h48_pval(uint32_t *, int64_t, uint8_t, uint8_t); | 1908 | _static_inline void set_h48_pval(uint32_t *, int64_t, uint8_t, uint8_t); |
| @@ -1989,7 +1939,7 @@ gendata_cocsep(void *buf) | |||
| 1989 | for (i = 0, n = 0, cc = 0; i < 10; i++) { | 1939 | for (i = 0, n = 0, cc = 0; i < 10; i++) { |
| 1990 | memset(visited, 0, tablesize * sizeof(bool)); | 1940 | memset(visited, 0, tablesize * sizeof(bool)); |
| 1991 | DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i); | 1941 | DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i); |
| 1992 | cc = dfs_cocsep(solved, 0, i, &n, buf32, visited); | 1942 | cc = gendata_cocsep_dfs(solved, 0, i, &n, buf32, visited); |
| 1993 | info[i+2] = cc; | 1943 | info[i+2] = cc; |
| 1994 | DBG_LOG("found %" PRIu32 "\n", cc); | 1944 | DBG_LOG("found %" PRIu32 "\n", cc); |
| 1995 | } | 1945 | } |
| @@ -2010,7 +1960,7 @@ gendata_cocsep(void *buf) | |||
| 2010 | } | 1960 | } |
| 2011 | 1961 | ||
| 2012 | _static uint32_t | 1962 | _static uint32_t |
| 2013 | dfs_cocsep( | 1963 | gendata_cocsep_dfs( |
| 2014 | cube_fast_t c, | 1964 | cube_fast_t c, |
| 2015 | uint8_t depth, | 1965 | uint8_t depth, |
| 2016 | uint8_t maxdepth, | 1966 | uint8_t maxdepth, |
| @@ -2035,22 +1985,23 @@ dfs_cocsep( | |||
| 2035 | return 0; | 1985 | return 0; |
| 2036 | 1986 | ||
| 2037 | cc = 0; | 1987 | cc = 0; |
| 2038 | _foreach_trans(t, c, d, | 1988 | for (t = 0; t < 48; t++) { |
| 1989 | d = transform(c, t); | ||
| 2039 | i = coord_fast_cocsep(d); | 1990 | i = coord_fast_cocsep(d); |
| 2040 | visited[i] = true; | 1991 | visited[i] = true; |
| 2041 | tinv = inverse_trans(t); | 1992 | tinv = inverse_trans(t); |
| 2042 | cc += (buf32[i] & 0xFFU) == 0xFFU; | 1993 | cc += (buf32[i] & 0xFFU) == 0xFFU; |
| 2043 | buf32[i] = (*n << 16U) | (tinv << 8U) | depth; | 1994 | buf32[i] = (*n << 16U) | (tinv << 8U) | depth; |
| 2044 | ) | 1995 | } |
| 2045 | (*n)++; | 1996 | (*n)++; |
| 2046 | 1997 | ||
| 2047 | return cc; | 1998 | return cc; |
| 2048 | } | 1999 | } |
| 2049 | 2000 | ||
| 2050 | cc = 0; | 2001 | for (m = 0, cc = 0; m < 18; m++) { |
| 2051 | _foreach_move(m, c, d, | 2002 | d = move(c, m); |
| 2052 | cc += dfs_cocsep(d, depth+1, maxdepth, n, buf32, visited); | 2003 | cc += gendata_cocsep_dfs(d, depth+1, maxdepth, n, buf32, visited); |
| 2053 | ) | 2004 | } |
| 2054 | 2005 | ||
| 2055 | return cc; | 2006 | return cc; |
| 2056 | } | 2007 | } |
| @@ -2069,25 +2020,27 @@ gendata_eoesep(uint8_t h, uint8_t k, const void *cocsepdata, void *buf) | |||
| 2069 | size_t infosize = 25; /* TODO unknown yet */ | 2020 | size_t infosize = 25; /* TODO unknown yet */ |
| 2070 | 2021 | ||
| 2071 | uint32_t *buf32, *info, cc; | 2022 | uint32_t *buf32, *info, cc; |
| 2072 | bool visited[tablesize]; /* TODO: change this, becomes too large */ | 2023 | uint8_t moves[20]; |
| 2073 | dfsarg_gendata_t arg; | 2024 | dfsarg_gendata_t arg; |
| 2074 | 2025 | ||
| 2075 | buf32 = (uint32_t *)buf; | 2026 | buf32 = (uint32_t *)buf; |
| 2076 | info = buf32 + tablesize; | 2027 | info = buf32 + tablesize; |
| 2028 | DBG_LOG("Allocating 4 * %zu bytes\n", tablesize); | ||
| 2077 | memset(buf32, 0xFFU, 4*tablesize); | 2029 | memset(buf32, 0xFFU, 4*tablesize); |
| 2078 | memset(info, 0, 4*infosize); | 2030 | memset(info, 0, 4*infosize); |
| 2079 | 2031 | ||
| 2080 | arg.cube = cubetofast(solvedcube()); | 2032 | arg.cube = cubetofast(solvedcube()); |
| 2033 | arg.moves = moves; | ||
| 2081 | arg.nmoves = 0; | 2034 | arg.nmoves = 0; |
| 2035 | arg.h = h; | ||
| 2036 | arg.k = k; | ||
| 2082 | arg.cocsepdata = (uint32_t *)cocsepdata; | 2037 | arg.cocsepdata = (uint32_t *)cocsepdata; |
| 2083 | arg.buf32 = buf32; | 2038 | arg.buf32 = buf32; |
| 2084 | arg.visited = visited; | ||
| 2085 | /* TODO loop until no more is done, not until 12! (or hardcode limits)*/ | 2039 | /* TODO loop until no more is done, not until 12! (or hardcode limits)*/ |
| 2086 | for (arg.depth = 0, cc = 0; arg.depth < 12; arg.depth++) { | 2040 | for (arg.depth = 0, cc = 0; arg.depth < 12; arg.depth++) { |
| 2087 | memset(visited, 0, tablesize * sizeof(bool)); | ||
| 2088 | DBG_LOG("gendata_eoesep: generating depth %" PRIu8 "\n", | 2041 | DBG_LOG("gendata_eoesep: generating depth %" PRIu8 "\n", |
| 2089 | arg.depth); | 2042 | arg.depth); |
| 2090 | cc = dfs_eoesep(&arg); | 2043 | cc = gendata_eoesep_dfs(&arg); |
| 2091 | info[arg.depth+1] = cc; | 2044 | info[arg.depth+1] = cc; |
| 2092 | DBG_LOG("found %" PRIu32 "\n", cc); | 2045 | DBG_LOG("found %" PRIu32 "\n", cc); |
| 2093 | } | 2046 | } |
| @@ -2124,18 +2077,23 @@ set_h48_pval(uint32_t *buf32, int64_t index, uint8_t k, uint8_t val) | |||
| 2124 | } | 2077 | } |
| 2125 | 2078 | ||
| 2126 | _static uint32_t | 2079 | _static uint32_t |
| 2127 | dfs_eoesep(dfsarg_gendata_t *arg) | 2080 | gendata_eoesep_dfs(dfsarg_gendata_t *arg) |
| 2128 | { | 2081 | { |
| 2129 | uint8_t m, olddepth; | 2082 | uint8_t m, olddepth; |
| 2130 | uint32_t cc; | 2083 | uint32_t cc; |
| 2131 | uint64_t i; | 2084 | uint64_t i; |
| 2132 | dfsarg_gendata_t newarg; | 2085 | dfsarg_gendata_t nextarg; |
| 2086 | |||
| 2087 | if (!allowednextmove(arg->moves, arg->nmoves)) | ||
| 2088 | return 0; | ||
| 2089 | |||
| 2090 | if (arg->nmoves > 0) | ||
| 2091 | arg->cube = move(arg->cube, arg->moves[arg->nmoves-1]); | ||
| 2133 | 2092 | ||
| 2134 | i = coord_fast_h48(arg->cube, arg->cocsepdata, arg->h); | 2093 | i = coord_fast_h48(arg->cube, arg->cocsepdata, arg->h); |
| 2135 | olddepth = get_h48_pval(arg->buf32, i, arg->k); | 2094 | olddepth = get_h48_pval(arg->buf32, i, arg->k); |
| 2136 | if (olddepth < arg->nmoves || arg->visited[i]) | 2095 | if (olddepth < arg->nmoves) |
| 2137 | return 0; | 2096 | return 0; |
| 2138 | arg->visited[i] = true; | ||
| 2139 | 2097 | ||
| 2140 | if (arg->nmoves == arg->depth) { | 2098 | if (arg->nmoves == arg->depth) { |
| 2141 | cc = olddepth == 0xFFU; | 2099 | cc = olddepth == 0xFFU; |
| @@ -2143,18 +2101,13 @@ dfs_eoesep(dfsarg_gendata_t *arg) | |||
| 2143 | return cc; | 2101 | return cc; |
| 2144 | } | 2102 | } |
| 2145 | 2103 | ||
| 2146 | cc = 0; | 2104 | nextarg = *arg; |
| 2147 | newarg = *arg; | 2105 | nextarg.nmoves = arg->nmoves + 1; |
| 2148 | newarg.nmoves = arg->nmoves + 1; | 2106 | for (m = 0, cc = 0; m < 18; m++) { |
| 2149 | /* | 2107 | nextarg.cube = arg->cube; |
| 2150 | newarg.nmoves = arg->nmoves + 1; | 2108 | nextarg.moves[arg->nmoves] = m; |
| 2151 | newarg.depth = arg->depth; | 2109 | cc += gendata_eoesep_dfs(&nextarg); |
| 2152 | newarg.h = arg->h; | 2110 | } |
| 2153 | newarg.k = arg->k; | ||
| 2154 | */ | ||
| 2155 | _foreach_move(m, arg->cube, newarg.cube, | ||
| 2156 | cc += dfs_eoesep(&newarg); | ||
| 2157 | ) | ||
| 2158 | 2111 | ||
| 2159 | return cc; | 2112 | return cc; |
| 2160 | } | 2113 | } |
| @@ -2176,9 +2129,8 @@ typedef struct { | |||
| 2176 | uint8_t (*estimate)(cube_fast_t); | 2129 | uint8_t (*estimate)(cube_fast_t); |
| 2177 | } dfsarg_generic_t; | 2130 | } dfsarg_generic_t; |
| 2178 | 2131 | ||
| 2179 | _static bool allowednextmove(uint8_t *, int, uint8_t); | 2132 | _static void solve_generic_appendsolution(dfsarg_generic_t *); |
| 2180 | _static void solve_generic_appendsolution(dfsarg_generic_t); | 2133 | _static int solve_generic_dfs(dfsarg_generic_t *); |
| 2181 | _static int solve_generic_dfs(dfsarg_generic_t); | ||
| 2182 | _static int64_t solve_generic(cube_t, const char *, int8_t, int8_t, int64_t, | 2134 | _static int64_t solve_generic(cube_t, const char *, int8_t, int8_t, int64_t, |
| 2183 | int8_t, char *, uint8_t (*)(cube_fast_t)); | 2135 | int8_t, char *, uint8_t (*)(cube_fast_t)); |
| 2184 | _static uint8_t estimate_simple(cube_fast_t); | 2136 | _static uint8_t estimate_simple(cube_fast_t); |
| @@ -2252,81 +2204,51 @@ gendata(const char *solver, void *data) | |||
| 2252 | return -1; | 2204 | return -1; |
| 2253 | } | 2205 | } |
| 2254 | 2206 | ||
| 2255 | _static bool | ||
| 2256 | allowednextmove(uint8_t *moves, int n, uint8_t m) | ||
| 2257 | { | ||
| 2258 | uint8_t mbase, l1base, l2base, maxis, l1axis, l2axis; | ||
| 2259 | |||
| 2260 | if (n == 0) | ||
| 2261 | return true; | ||
| 2262 | |||
| 2263 | mbase = movebase(m); | ||
| 2264 | maxis = moveaxis(m); | ||
| 2265 | l1base = movebase(moves[n-1]); | ||
| 2266 | l1axis = moveaxis(moves[n-1]); | ||
| 2267 | |||
| 2268 | if (mbase == l1base || (maxis == l1axis && mbase < l1base)) | ||
| 2269 | return false; | ||
| 2270 | |||
| 2271 | if (n == 1) | ||
| 2272 | return true; | ||
| 2273 | |||
| 2274 | l2base = movebase(moves[n-2]); | ||
| 2275 | l2axis = moveaxis(moves[n-2]); | ||
| 2276 | |||
| 2277 | return l1axis != l2axis || mbase != l2base; | ||
| 2278 | } | ||
| 2279 | |||
| 2280 | _static void | 2207 | _static void |
| 2281 | solve_generic_appendsolution(dfsarg_generic_t arg) | 2208 | solve_generic_appendsolution(dfsarg_generic_t *arg) |
| 2282 | { | 2209 | { |
| 2283 | int strl; | 2210 | int strl; |
| 2284 | 2211 | ||
| 2285 | strl = writemoves(arg.moves, arg.depth, *arg.nextsol); | 2212 | strl = writemoves(arg->moves, arg->depth, *arg->nextsol); |
| 2286 | DBG_LOG("Solution found: %s\n", *arg.nextsol); | 2213 | DBG_LOG("Solution found: %s\n", *arg->nextsol); |
| 2287 | *arg.nextsol += strl; | 2214 | *arg->nextsol += strl; |
| 2288 | **arg.nextsol = '\n'; | 2215 | **arg->nextsol = '\n'; |
| 2289 | (*arg.nextsol)++; | 2216 | (*arg->nextsol)++; |
| 2290 | (*arg.nsols)++; | 2217 | (*arg->nsols)++; |
| 2291 | } | 2218 | } |
| 2292 | 2219 | ||
| 2293 | _static int | 2220 | _static int |
| 2294 | solve_generic_dfs(dfsarg_generic_t arg) | 2221 | solve_generic_dfs(dfsarg_generic_t *arg) |
| 2295 | { | 2222 | { |
| 2296 | dfsarg_generic_t nextarg; | 2223 | dfsarg_generic_t nextarg; |
| 2297 | uint8_t m, bound; | 2224 | uint8_t m, bound; |
| 2298 | int64_t ret; | 2225 | int64_t ret; |
| 2299 | 2226 | ||
| 2300 | bound = arg.estimate(arg.cube); | 2227 | if (!allowednextmove(arg->moves, arg->nmoves)) |
| 2228 | return 0; | ||
| 2229 | |||
| 2230 | if (arg->nmoves > 0) | ||
| 2231 | arg->cube = move(arg->cube, arg->moves[arg->nmoves-1]); | ||
| 2301 | 2232 | ||
| 2302 | if (*arg.nsols == arg.maxsols || bound + arg.nmoves > arg.depth) | 2233 | bound = arg->estimate(arg->cube); |
| 2234 | if (*arg->nsols == arg->maxsols || bound + arg->nmoves > arg->depth) | ||
| 2303 | return 0; | 2235 | return 0; |
| 2304 | 2236 | ||
| 2305 | if (bound == 0) { | 2237 | if (bound == 0) { |
| 2306 | if (arg.nmoves != arg.depth) | 2238 | if (arg->nmoves != arg->depth) |
| 2307 | return 0; | 2239 | return 0; |
| 2308 | solve_generic_appendsolution(arg); | 2240 | solve_generic_appendsolution(arg); |
| 2309 | return 1; | 2241 | return 1; |
| 2310 | } | 2242 | } |
| 2311 | 2243 | ||
| 2312 | memcpy(&nextarg, &arg, sizeof(dfsarg_generic_t)); | 2244 | /* memcpy(&nextarg, arg, sizeof(dfsarg_generic_t)); */ |
| 2313 | nextarg.nmoves = arg.nmoves + 1; | 2245 | nextarg = *arg; |
| 2314 | /* | 2246 | nextarg.nmoves = arg->nmoves + 1; |
| 2315 | for (m = 0, ret = 0; m < 18; m++) { | 2247 | for (m = 0, ret = 0; m < 18; m++) { |
| 2316 | if (allowednextmove(arg.moves, arg.nmoves, m)) { | 2248 | nextarg.cube = arg->cube; |
| 2317 | nextarg.cube = move(arg.cube, m); | 2249 | nextarg.moves[arg->nmoves] = m; |
| 2318 | nextarg.moves[arg.nmoves] = m; | 2250 | ret += solve_generic_dfs(&nextarg); |
| 2319 | ret += solve_generic_dfs(nextarg); | ||
| 2320 | } | ||
| 2321 | } | 2251 | } |
| 2322 | */ | ||
| 2323 | ret = 0; | ||
| 2324 | _foreach_move(m, arg.cube, nextarg.cube, | ||
| 2325 | if (allowednextmove(arg.moves, arg.nmoves, m)) { | ||
| 2326 | nextarg.moves[arg.nmoves] = m; | ||
| 2327 | ret += solve_generic_dfs(nextarg); | ||
| 2328 | } | ||
| 2329 | ) | ||
| 2330 | 2252 | ||
| 2331 | return ret; | 2253 | return ret; |
| 2332 | } | 2254 | } |
| @@ -2408,7 +2330,7 @@ solve_generic( | |||
| 2408 | ret = 0; | 2330 | ret = 0; |
| 2409 | first = -1; | 2331 | first = -1; |
| 2410 | for (arg.depth = minmoves; arg.depth <= maxmoves; arg.depth++) { | 2332 | for (arg.depth = minmoves; arg.depth <= maxmoves; arg.depth++) { |
| 2411 | tmp = solve_generic_dfs(arg); | 2333 | tmp = solve_generic_dfs(&arg); |
| 2412 | if (tmp != 0) | 2334 | if (tmp != 0) |
| 2413 | first = arg.depth; | 2335 | first = arg.depth; |
| 2414 | 2336 | ||
