diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-04-02 14:33:21 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-04-02 14:33:21 +0200 |
| commit | c5a6ff0443fc9e5e890fe72cb13ea78d4fe2bbcb (patch) | |
| tree | 9a5710c2393a09078df72d95364b6af966d745bd /src/solvers/coord | |
| parent | 82e0a6bf454f5684b44bb0a24db619e9ba0567a0 (diff) | |
| download | nissy-core-c5a6ff0443fc9e5e890fe72cb13ea78d4fe2bbcb.tar.gz nissy-core-c5a6ff0443fc9e5e890fe72cb13ea78d4fe2bbcb.zip | |
Added dreo coordinate solver
Diffstat (limited to 'src/solvers/coord')
| -rw-r--r-- | src/solvers/coord/common.h | 2 | ||||
| -rw-r--r-- | src/solvers/coord/coord.h | 1 | ||||
| -rw-r--r-- | src/solvers/coord/dr.h | 22 | ||||
| -rw-r--r-- | src/solvers/coord/dreo.h | 102 | ||||
| -rw-r--r-- | src/solvers/coord/eo.h | 15 | ||||
| -rw-r--r-- | src/solvers/coord/gendata.h | 11 | ||||
| -rw-r--r-- | src/solvers/coord/list.h | 1 | ||||
| -rw-r--r-- | src/solvers/coord/solve.h | 27 | ||||
| -rw-r--r-- | src/solvers/coord/types_macros.h | 1 |
9 files changed, 168 insertions, 14 deletions
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h index 95c0e6c..2eb5ad0 100644 --- a/src/solvers/coord/common.h +++ b/src/solvers/coord/common.h | |||
| @@ -125,7 +125,7 @@ coord_gendata_generic( | |||
| 125 | 125 | ||
| 126 | writetableinfo(&info, coord_datasize, data); | 126 | writetableinfo(&info, coord_datasize, data); |
| 127 | 127 | ||
| 128 | DBG_ASSERT(n == coord->sym.classes, 0, | 128 | DBG_ASSERT(n == coord->sym.classes, SIZE_MAX, |
| 129 | "%s coordinate data: computed %" PRIu64 " classes, " | 129 | "%s coordinate data: computed %" PRIu64 " classes, " |
| 130 | "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes); | 130 | "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes); |
| 131 | 131 | ||
diff --git a/src/solvers/coord/coord.h b/src/solvers/coord/coord.h index 11d41bc..2f24035 100644 --- a/src/solvers/coord/coord.h +++ b/src/solvers/coord/coord.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include "common.h" | 2 | #include "common.h" |
| 3 | #include "eo.h" | 3 | #include "eo.h" |
| 4 | #include "dr.h" | 4 | #include "dr.h" |
| 5 | #include "dreo.h" | ||
| 5 | #include "list.h" | 6 | #include "list.h" |
| 6 | #include "utils.h" | 7 | #include "utils.h" |
| 7 | #include "gendata.h" | 8 | #include "gendata.h" |
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h index 314d4f1..3bc4c6d 100644 --- a/src/solvers/coord/dr.h +++ b/src/solvers/coord/dr.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #define DREOESEP_CLASSES UINT64_C(64430) | 1 | #define DREOESEP_CLASSES UINT64_C(64430) |
| 2 | #define DREOESEP_MAX (POW_2_11 * COMB_12_4) | 2 | #define DREOESEP_MAX (POW_2_11 * COMB_12_4) |
| 3 | 3 | ||
| 4 | STATIC uint64_t coord_dreoesep_nosym(cube_t); | 4 | STATIC uint64_t coord_dreoesep_nosym(cube_t); |
| 5 | STATIC cube_t invcoord_dreoesep_nosym(uint64_t); | 5 | STATIC cube_t invcoord_dreoesep_nosym(uint64_t); |
| @@ -10,6 +10,8 @@ STATIC cube_t coordinate_dr_cube(uint64_t, const void *); | |||
| 10 | STATIC bool coordinate_dr_isnasty(uint64_t, const void *); | 10 | STATIC bool coordinate_dr_isnasty(uint64_t, const void *); |
| 11 | STATIC size_t coordinate_dr_gendata(void *); | 11 | STATIC size_t coordinate_dr_gendata(void *); |
| 12 | 12 | ||
| 13 | STATIC bool is_eoco_solvable(cube_t); | ||
| 14 | |||
| 13 | /* TODO: remove the following two when all coordinates are converted to unsigned */ | 15 | /* TODO: remove the following two when all coordinates are converted to unsigned */ |
| 14 | STATIC uint64_t coord_co_u(cube_t c) { return (uint64_t)coord_co(c); } | 16 | STATIC uint64_t coord_co_u(cube_t c) { return (uint64_t)coord_co(c); } |
| 15 | STATIC cube_t invcoord_co_u(uint64_t i) { return invcoord_co((int64_t)i); } | 17 | STATIC cube_t invcoord_co_u(uint64_t i) { return invcoord_co((int64_t)i); } |
| @@ -29,6 +31,7 @@ STATIC coord_t coordinate_dr = { | |||
| 29 | [AXIS_FB] = TRANS_FDr, | 31 | [AXIS_FB] = TRANS_FDr, |
| 30 | }, | 32 | }, |
| 31 | .is_admissible = &solution_lastqt_cw, | 33 | .is_admissible = &solution_lastqt_cw, |
| 34 | .is_solvable = &is_eoco_solvable, | ||
| 32 | .sym = { | 35 | .sym = { |
| 33 | .classes = DREOESEP_CLASSES, | 36 | .classes = DREOESEP_CLASSES, |
| 34 | .max = DREOESEP_MAX, | 37 | .max = DREOESEP_MAX, |
| @@ -100,3 +103,18 @@ coordinate_dr_gendata(void *data) | |||
| 100 | { | 103 | { |
| 101 | return coord_gendata_generic(&coordinate_dr, data); | 104 | return coord_gendata_generic(&coordinate_dr, data); |
| 102 | } | 105 | } |
| 106 | |||
| 107 | STATIC bool | ||
| 108 | is_eoco_solvable(cube_t cube) { | ||
| 109 | uint8_t c[8], e[12], i, cocount, eocount; | ||
| 110 | |||
| 111 | pieces(&cube, c, e); | ||
| 112 | |||
| 113 | for (i = 0, cocount = 0; i < 8; i++) | ||
| 114 | cocount += (c[i] & COBITS_2) >> COSHIFT; | ||
| 115 | |||
| 116 | for (i = 0, eocount = 0; i < 12; i++) | ||
| 117 | eocount += (e[i] & EOBIT) >> EOSHIFT; | ||
| 118 | |||
| 119 | return cocount % 3 == 0 && eocount % 2 == 0; | ||
| 120 | } | ||
diff --git a/src/solvers/coord/dreo.h b/src/solvers/coord/dreo.h new file mode 100644 index 0000000..37de0d3 --- /dev/null +++ b/src/solvers/coord/dreo.h | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | #define DRESEP_CLASSES 81 | ||
| 2 | |||
| 3 | STATIC uint64_t coord_dresep_nosym(cube_t); | ||
| 4 | STATIC cube_t invcoord_dresep_nosym(uint64_t); | ||
| 5 | STATIC cube_t coordinate_dreo_merge(cube_t, cube_t); | ||
| 6 | |||
| 7 | STATIC uint64_t coordinate_dreo_coord(cube_t, const void *); | ||
| 8 | STATIC cube_t coordinate_dreo_cube(uint64_t, const void *); | ||
| 9 | STATIC bool coordinate_dreo_isnasty(uint64_t, const void *); | ||
| 10 | STATIC size_t coordinate_dreo_gendata(void *); | ||
| 11 | |||
| 12 | STATIC bool is_dreo_solvable(cube_t); | ||
| 13 | |||
| 14 | STATIC coord_t coordinate_dreo = { | ||
| 15 | .name = "DREO", | ||
| 16 | .coord = &coordinate_dreo_coord, | ||
| 17 | .cube = &coordinate_dreo_cube, | ||
| 18 | .isnasty = &coordinate_dreo_isnasty, | ||
| 19 | .gendata = coordinate_dreo_gendata, | ||
| 20 | .max = DRESEP_CLASSES * POW_3_7, | ||
| 21 | .trans_mask = TM_UDRLFIX, | ||
| 22 | .moves_mask = MM_EO, | ||
| 23 | .axistrans = { | ||
| 24 | [AXIS_UD] = TRANS_UFr, | ||
| 25 | [AXIS_RL] = TRANS_RFr, | ||
| 26 | [AXIS_FB] = TRANS_FDr, | ||
| 27 | }, | ||
| 28 | .is_admissible = &solution_lastqt_cw, | ||
| 29 | .is_solvable = &is_dreo_solvable, | ||
| 30 | .sym = { | ||
| 31 | .classes = DRESEP_CLASSES, | ||
| 32 | .max = COMB_12_4, | ||
| 33 | .coord = &coord_dresep_nosym, | ||
| 34 | .cube = &invcoord_dresep_nosym, | ||
| 35 | .max2 = POW_3_7, | ||
| 36 | .coord2 = &coord_co_u, | ||
| 37 | .cube2 = &invcoord_co_u, | ||
| 38 | .merge = &coordinate_dreo_merge, | ||
| 39 | }, | ||
| 40 | }; | ||
| 41 | |||
| 42 | STATIC uint64_t | ||
| 43 | coord_dresep_nosym(cube_t cube) | ||
| 44 | { | ||
| 45 | return (uint64_t)coord_esep(cube) / COMB_8_4; | ||
| 46 | } | ||
| 47 | |||
| 48 | STATIC cube_t | ||
| 49 | invcoord_dresep_nosym(uint64_t coord) | ||
| 50 | { | ||
| 51 | return invcoord_esep(coord * COMB_8_4); | ||
| 52 | } | ||
| 53 | |||
| 54 | STATIC cube_t | ||
| 55 | coordinate_dreo_merge(cube_t c1, cube_t c2) | ||
| 56 | { | ||
| 57 | cube_t merged; | ||
| 58 | |||
| 59 | merged = c1; | ||
| 60 | copy_corners(&merged, c2); | ||
| 61 | |||
| 62 | return merged; | ||
| 63 | } | ||
| 64 | |||
| 65 | STATIC uint64_t | ||
| 66 | coordinate_dreo_coord(cube_t cube, const void *data) | ||
| 67 | { | ||
| 68 | return coord_coord_generic(&coordinate_dreo, cube, data); | ||
| 69 | } | ||
| 70 | |||
| 71 | STATIC cube_t | ||
| 72 | coordinate_dreo_cube(uint64_t i, const void *data) | ||
| 73 | { | ||
| 74 | return coord_cube_generic(&coordinate_dreo, i, data); | ||
| 75 | } | ||
| 76 | |||
| 77 | STATIC bool | ||
| 78 | coordinate_dreo_isnasty(uint64_t i, const void *data) | ||
| 79 | { | ||
| 80 | return coord_isnasty_generic(&coordinate_dreo, i, data); | ||
| 81 | } | ||
| 82 | |||
| 83 | STATIC size_t | ||
| 84 | coordinate_dreo_gendata(void *data) | ||
| 85 | { | ||
| 86 | return coord_gendata_generic(&coordinate_dreo, data); | ||
| 87 | } | ||
| 88 | |||
| 89 | STATIC bool | ||
| 90 | is_dreo_solvable(cube_t cube) { | ||
| 91 | uint8_t c[8], e[12], i, cocount; | ||
| 92 | |||
| 93 | if (coord_eo(cube) != 0) | ||
| 94 | return false; | ||
| 95 | |||
| 96 | pieces(&cube, c, e); | ||
| 97 | |||
| 98 | for (i = 0, cocount = 0; i < 8; i++) | ||
| 99 | cocount += (c[i] & COBITS_2) >> COSHIFT; | ||
| 100 | |||
| 101 | return cocount % 3 == 0; | ||
| 102 | } | ||
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h index b83be01..a0685c4 100644 --- a/src/solvers/coord/eo.h +++ b/src/solvers/coord/eo.h | |||
| @@ -2,6 +2,7 @@ STATIC uint64_t coordinate_eo_coord(cube_t, const void *); | |||
| 2 | STATIC cube_t coordinate_eo_cube(uint64_t, const void *); | 2 | STATIC cube_t coordinate_eo_cube(uint64_t, const void *); |
| 3 | STATIC bool coordinate_eo_isnasty(uint64_t, const void *); | 3 | STATIC bool coordinate_eo_isnasty(uint64_t, const void *); |
| 4 | STATIC size_t coordinate_eo_gendata(void *); | 4 | STATIC size_t coordinate_eo_gendata(void *); |
| 5 | STATIC bool is_eo_even(cube_t); | ||
| 5 | 6 | ||
| 6 | STATIC coord_t coordinate_eo = { | 7 | STATIC coord_t coordinate_eo = { |
| 7 | .name = "EO", | 8 | .name = "EO", |
| @@ -18,6 +19,7 @@ STATIC coord_t coordinate_eo = { | |||
| 18 | [AXIS_FB] = TRANS_UFr, | 19 | [AXIS_FB] = TRANS_UFr, |
| 19 | }, | 20 | }, |
| 20 | .is_admissible = &solution_lastqt_cw, | 21 | .is_admissible = &solution_lastqt_cw, |
| 22 | .is_solvable = &is_eo_even, | ||
| 21 | .sym = {0}, | 23 | .sym = {0}, |
| 22 | }; | 24 | }; |
| 23 | 25 | ||
| @@ -46,3 +48,16 @@ coordinate_eo_gendata(void *data) | |||
| 46 | { | 48 | { |
| 47 | return 0; | 49 | return 0; |
| 48 | } | 50 | } |
| 51 | |||
| 52 | STATIC bool | ||
| 53 | is_eo_even(cube_t cube) | ||
| 54 | { | ||
| 55 | uint8_t c[8], e[12], i, count; | ||
| 56 | |||
| 57 | pieces(&cube, c, e); | ||
| 58 | |||
| 59 | for (i = 0, count = 0; i < 12; i++) | ||
| 60 | count += (e[i] & EOBIT) >> EOSHIFT; | ||
| 61 | |||
| 62 | return count % 2 == 0; | ||
| 63 | } | ||
diff --git a/src/solvers/coord/gendata.h b/src/solvers/coord/gendata.h index 423dad1..63e1631 100644 --- a/src/solvers/coord/gendata.h +++ b/src/solvers/coord/gendata.h | |||
| @@ -39,6 +39,9 @@ gendata_coord(const coord_t coord[static 1], void *buf) | |||
| 39 | 39 | ||
| 40 | coord_data = buf == NULL ? NULL : ((uint8_t *)buf) + INFOSIZE; | 40 | coord_data = buf == NULL ? NULL : ((uint8_t *)buf) + INFOSIZE; |
| 41 | coord_dsize = coord->gendata(coord_data); | 41 | coord_dsize = coord->gendata(coord_data); |
| 42 | if (coord_dsize == SIZE_MAX) | ||
| 43 | goto gendata_coord_error; | ||
| 44 | |||
| 42 | ninfo = coord_dsize == 0 ? 1 : 2; | 45 | ninfo = coord_dsize == 0 ? 1 : 2; |
| 43 | tablesize = DIV_ROUND_UP(coord->max, 2); | 46 | tablesize = DIV_ROUND_UP(coord->max, 2); |
| 44 | 47 | ||
| @@ -77,6 +80,10 @@ gendata_coord(const coord_t coord[static 1], void *buf) | |||
| 77 | 80 | ||
| 78 | gendata_coord_return_size: | 81 | gendata_coord_return_size: |
| 79 | return ninfo * INFOSIZE + coord_dsize + tablesize; | 82 | return ninfo * INFOSIZE + coord_dsize + tablesize; |
| 83 | |||
| 84 | gendata_coord_error: | ||
| 85 | LOG("An unexpected error occurred when generating the data.\n"); | ||
| 86 | return 0; | ||
| 80 | } | 87 | } |
| 81 | 88 | ||
| 82 | STATIC tableinfo_t | 89 | STATIC tableinfo_t |
| @@ -167,6 +174,8 @@ genptable_coord_fillneighbors( | |||
| 167 | c = coord->cube(i, data); | 174 | c = coord->cube(i, data); |
| 168 | tot = 0; | 175 | tot = 0; |
| 169 | for (m = 0; m < NMOVES; m++) { | 176 | for (m = 0; m < NMOVES; m++) { |
| 177 | if (!((UINT32_C(1) << (uint32_t)m) & coord->moves_mask)) | ||
| 178 | continue; | ||
| 170 | moved = move(c, m); | 179 | moved = move(c, m); |
| 171 | ii = coord->coord(moved, data); | 180 | ii = coord->coord(moved, data); |
| 172 | isnasty = coord->isnasty(ii, data); | 181 | isnasty = coord->isnasty(ii, data); |
| @@ -216,6 +225,8 @@ genptable_coord_fillfromnew( | |||
| 216 | for (j = 0, found = false; j < nsim && !found; j++) { | 225 | for (j = 0, found = false; j < nsim && !found; j++) { |
| 217 | c = coord->cube(sim[j], data); | 226 | c = coord->cube(sim[j], data); |
| 218 | for (m = 0; m < NMOVES; m++) { | 227 | for (m = 0; m < NMOVES; m++) { |
| 228 | if (!((UINT32_C(1) << (uint32_t)m) & coord->moves_mask)) | ||
| 229 | continue; | ||
| 219 | ii = coord->coord(move(c, m), data); | 230 | ii = coord->coord(move(c, m), data); |
| 220 | if (get_coord_pval(coord, table, ii) < d) { | 231 | if (get_coord_pval(coord, table, ii) < d) { |
| 221 | found = true; | 232 | found = true; |
diff --git a/src/solvers/coord/list.h b/src/solvers/coord/list.h index 7d43d45..9409bb6 100644 --- a/src/solvers/coord/list.h +++ b/src/solvers/coord/list.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | coord_t *all_coordinates[] = { | 1 | coord_t *all_coordinates[] = { |
| 2 | &coordinate_eo, | 2 | &coordinate_eo, |
| 3 | &coordinate_dr, | 3 | &coordinate_dr, |
| 4 | &coordinate_dreo, | ||
| 4 | NULL | 5 | NULL |
| 5 | }; | 6 | }; |
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h index fa4134a..8806d17 100644 --- a/src/solvers/coord/solve.h +++ b/src/solvers/coord/solve.h | |||
| @@ -135,11 +135,10 @@ solve_coord_dfs(dfsarg_solve_coord_t arg[static 1]) | |||
| 135 | ret = 0; | 135 | ret = 0; |
| 136 | if (coord_continue_onnormal(arg)) { | 136 | if (coord_continue_onnormal(arg)) { |
| 137 | l = arg->solution_moves->nmoves; | 137 | l = arg->solution_moves->nmoves; |
| 138 | if (l == 0) { | 138 | mm = arg->coord->moves_mask; |
| 139 | mm = MM_ALLMOVES; | 139 | if (l != 0) { |
| 140 | } else { | ||
| 141 | m = arg->solution_moves->moves[l-1]; | 140 | m = arg->solution_moves->moves[l-1]; |
| 142 | mm = allowedmask[movebase(m)]; | 141 | mm &= allowedmask[movebase(m)]; |
| 143 | } | 142 | } |
| 144 | arg->solution_moves->nmoves++; | 143 | arg->solution_moves->nmoves++; |
| 145 | arg->lastisnormal = true; | 144 | arg->lastisnormal = true; |
| @@ -165,11 +164,10 @@ solve_coord_dfs(dfsarg_solve_coord_t arg[static 1]) | |||
| 165 | 164 | ||
| 166 | if (coord_continue_oninverse(arg)) { | 165 | if (coord_continue_oninverse(arg)) { |
| 167 | l = arg->solution_moves->npremoves; | 166 | l = arg->solution_moves->npremoves; |
| 168 | if (l == 0) { | 167 | mm = arg->coord->moves_mask; |
| 169 | mm = MM_ALLMOVES; | 168 | if (l != 0) { |
| 170 | } else { | ||
| 171 | m = arg->solution_moves->premoves[l-1]; | 169 | m = arg->solution_moves->premoves[l-1]; |
| 172 | mm = allowedmask[movebase(m)]; | 170 | mm &= allowedmask[movebase(m)]; |
| 173 | } | 171 | } |
| 174 | arg->solution_moves->npremoves++; | 172 | arg->solution_moves->npremoves++; |
| 175 | arg->lastisnormal = false; | 173 | arg->lastisnormal = false; |
| @@ -264,6 +262,12 @@ solve_coord( | |||
| 264 | solution_settings_t solution_settings; | 262 | solution_settings_t solution_settings; |
| 265 | solution_list_t solution_list; | 263 | solution_list_t solution_list; |
| 266 | 264 | ||
| 265 | t = coord->axistrans[axis]; | ||
| 266 | c = transform(cube, t); | ||
| 267 | |||
| 268 | if (!coord->is_solvable(c)) | ||
| 269 | goto solve_coord_error_unsolvable; | ||
| 270 | |||
| 267 | if (!solution_list_init(&solution_list, solutions_size, sols)) | 271 | if (!solution_list_init(&solution_list, solutions_size, sols)) |
| 268 | goto solve_coord_error_buffer; | 272 | goto solve_coord_error_buffer; |
| 269 | 273 | ||
| @@ -280,9 +284,6 @@ solve_coord( | |||
| 280 | ptable = (uint8_t *)data + info.next + INFOSIZE; | 284 | ptable = (uint8_t *)data + info.next + INFOSIZE; |
| 281 | } | 285 | } |
| 282 | 286 | ||
| 283 | t = coord->axistrans[axis]; | ||
| 284 | c = transform(cube, t); | ||
| 285 | |||
| 286 | solution_moves_reset(&solution_moves); | 287 | solution_moves_reset(&solution_moves); |
| 287 | 288 | ||
| 288 | solution_settings = (solution_settings_t) { | 289 | solution_settings = (solution_settings_t) { |
| @@ -351,4 +352,8 @@ solve_coord_error_data: | |||
| 351 | solve_coord_error_buffer: | 352 | solve_coord_error_buffer: |
| 352 | LOG("Could not append solution to buffer: size too small\n"); | 353 | LOG("Could not append solution to buffer: size too small\n"); |
| 353 | return NISSY_ERROR_BUFFER_SIZE; | 354 | return NISSY_ERROR_BUFFER_SIZE; |
| 355 | |||
| 356 | solve_coord_error_unsolvable: | ||
| 357 | LOG("Cube not ready for solving %s\n", coord->name); | ||
| 358 | return NISSY_ERROR_UNSOLVABLE_CUBE; | ||
| 354 | } | 359 | } |
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h index a2eaefe..84ed8eb 100644 --- a/src/solvers/coord/types_macros.h +++ b/src/solvers/coord/types_macros.h | |||
| @@ -25,6 +25,7 @@ typedef struct { | |||
| 25 | uint64_t trans_mask; | 25 | uint64_t trans_mask; |
| 26 | uint8_t axistrans[3]; | 26 | uint8_t axistrans[3]; |
| 27 | bool (*is_admissible)(const solution_moves_t[static 1]); | 27 | bool (*is_admissible)(const solution_moves_t[static 1]); |
| 28 | bool (*is_solvable)(cube_t); | ||
| 28 | struct { | 29 | struct { |
| 29 | size_t classes; | 30 | size_t classes; |
| 30 | uint64_t max; | 31 | uint64_t max; |
