diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-08-07 15:09:46 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-08-07 15:28:01 +0200 |
| commit | 5355de2921126e2b75e24abd57e17556e22a6ed0 (patch) | |
| tree | 0df679e152ffb2798248982ac58ff123c6859114 /src | |
| parent | 57a7520545134ab95f7bb0397dcbe991c906a3e9 (diff) | |
| download | nissy-core-5355de2921126e2b75e24abd57e17556e22a6ed0.tar.gz nissy-core-5355de2921126e2b75e24abd57e17556e22a6ed0.zip | |
Added API function for solution variations
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/constants.h | 66 | ||||
| -rw-r--r-- | src/core/core_types.h | 6 | ||||
| -rw-r--r-- | src/core/moves.h | 222 | ||||
| -rw-r--r-- | src/nissy.c | 26 | ||||
| -rw-r--r-- | src/nissy.h | 41 | ||||
| -rw-r--r-- | src/solvers/solutions.h | 4 | ||||
| -rw-r--r-- | src/solvers/solutions_types_macros.h | 6 |
7 files changed, 356 insertions, 15 deletions
diff --git a/src/core/constants.h b/src/core/constants.h index 26f6916..d8f2471 100644 --- a/src/core/constants.h +++ b/src/core/constants.h | |||
| @@ -845,3 +845,69 @@ STATIC equivalent_moves_t equivalent_moves_table[] = { | |||
| 845 | [MOVE_z2] = {{UINT8_MAX}, {2, 2, UINT8_MAX}}, | 845 | [MOVE_z2] = {{UINT8_MAX}, {2, 2, UINT8_MAX}}, |
| 846 | [MOVE_z3] = {{UINT8_MAX}, {2, 2, 2, UINT8_MAX}}, | 846 | [MOVE_z3] = {{UINT8_MAX}, {2, 2, 2, UINT8_MAX}}, |
| 847 | }; | 847 | }; |
| 848 | |||
| 849 | STATIC uint8_t slice_to_basic[] = { | ||
| 850 | [MOVE_M] = MOVE_L, | ||
| 851 | [MOVE_M2] = MOVE_L2, | ||
| 852 | [MOVE_M3] = MOVE_L3, | ||
| 853 | [MOVE_S] = MOVE_F, | ||
| 854 | [MOVE_S2] = MOVE_F2, | ||
| 855 | [MOVE_S3] = MOVE_F3, | ||
| 856 | [MOVE_E] = MOVE_D, | ||
| 857 | [MOVE_E2] = MOVE_D2, | ||
| 858 | [MOVE_E3] = MOVE_D3, | ||
| 859 | }; | ||
| 860 | |||
| 861 | STATIC uint8_t basic_to_slice[] = { | ||
| 862 | [MOVE_U] = MOVE_E3, | ||
| 863 | [MOVE_U2] = MOVE_E2, | ||
| 864 | [MOVE_U3] = MOVE_E, | ||
| 865 | [MOVE_D] = MOVE_E, | ||
| 866 | [MOVE_D2] = MOVE_E2, | ||
| 867 | [MOVE_D3] = MOVE_E3, | ||
| 868 | [MOVE_R] = MOVE_M3, | ||
| 869 | [MOVE_R2] = MOVE_M2, | ||
| 870 | [MOVE_R3] = MOVE_M, | ||
| 871 | [MOVE_L] = MOVE_M, | ||
| 872 | [MOVE_L2] = MOVE_M2, | ||
| 873 | [MOVE_L3] = MOVE_M3, | ||
| 874 | [MOVE_F] = MOVE_S, | ||
| 875 | [MOVE_F2] = MOVE_S2, | ||
| 876 | [MOVE_F3] = MOVE_S3, | ||
| 877 | [MOVE_B] = MOVE_S3, | ||
| 878 | [MOVE_B2] = MOVE_S2, | ||
| 879 | [MOVE_B3] = MOVE_S, | ||
| 880 | }; | ||
| 881 | |||
| 882 | STATIC uint8_t rotation_to_basic[] = { | ||
| 883 | [MOVE_x] = MOVE_R, | ||
| 884 | [MOVE_x2] = MOVE_R2, | ||
| 885 | [MOVE_x3] = MOVE_R3, | ||
| 886 | [MOVE_y] = MOVE_U, | ||
| 887 | [MOVE_y2] = MOVE_U2, | ||
| 888 | [MOVE_y3] = MOVE_U3, | ||
| 889 | [MOVE_z] = MOVE_F, | ||
| 890 | [MOVE_z2] = MOVE_F2, | ||
| 891 | [MOVE_z3] = MOVE_F3, | ||
| 892 | }; | ||
| 893 | |||
| 894 | STATIC uint8_t basic_to_rotation[] = { | ||
| 895 | [MOVE_U] = MOVE_y, | ||
| 896 | [MOVE_U2] = MOVE_y2, | ||
| 897 | [MOVE_U3] = MOVE_y3, | ||
| 898 | [MOVE_D] = MOVE_y3, | ||
| 899 | [MOVE_D2] = MOVE_y2, | ||
| 900 | [MOVE_D3] = MOVE_y, | ||
| 901 | [MOVE_R] = MOVE_x, | ||
| 902 | [MOVE_R2] = MOVE_x2, | ||
| 903 | [MOVE_R3] = MOVE_x3, | ||
| 904 | [MOVE_L] = MOVE_x3, | ||
| 905 | [MOVE_L2] = MOVE_x2, | ||
| 906 | [MOVE_L3] = MOVE_x, | ||
| 907 | [MOVE_F] = MOVE_z, | ||
| 908 | [MOVE_F2] = MOVE_z2, | ||
| 909 | [MOVE_F3] = MOVE_z3, | ||
| 910 | [MOVE_B] = MOVE_z3, | ||
| 911 | [MOVE_B2] = MOVE_z2, | ||
| 912 | [MOVE_B3] = MOVE_z, | ||
| 913 | }; | ||
diff --git a/src/core/core_types.h b/src/core/core_types.h index 19a9f42..53cc95e 100644 --- a/src/core/core_types.h +++ b/src/core/core_types.h | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | #define MOVES_STRUCT_MAXLEN 1000 | ||
| 2 | |||
| 3 | typedef struct { | 1 | typedef struct { |
| 4 | cube_t cube; | 2 | cube_t cube; |
| 5 | uint8_t orientation; | 3 | uint8_t orientation; |
| @@ -8,6 +6,6 @@ typedef struct { | |||
| 8 | typedef struct { | 6 | typedef struct { |
| 9 | size_t nnormal; | 7 | size_t nnormal; |
| 10 | size_t ninverse; | 8 | size_t ninverse; |
| 11 | uint8_t normal[MOVES_STRUCT_MAXLEN]; | 9 | uint8_t normal[NISSY_SIZE_MOVES]; |
| 12 | uint8_t inverse[MOVES_STRUCT_MAXLEN]; | 10 | uint8_t inverse[NISSY_SIZE_MOVES]; |
| 13 | } moves_struct_t; | 11 | } moves_struct_t; |
diff --git a/src/core/moves.h b/src/core/moves.h index 9c8cc90..6169c6e 100644 --- a/src/core/moves.h +++ b/src/core/moves.h | |||
| @@ -11,6 +11,8 @@ STATIC bool moves_struct_equal( | |||
| 11 | STATIC long long comparemoves(const char *, const char *); | 11 | STATIC long long comparemoves(const char *, const char *); |
| 12 | STATIC uint8_t readmodifier(char); | 12 | STATIC uint8_t readmodifier(char); |
| 13 | STATIC int64_t writemoves(size_t, const uint8_t *, size_t, char *); | 13 | STATIC int64_t writemoves(size_t, const uint8_t *, size_t, char *); |
| 14 | STATIC int64_t writemoves_struct( | ||
| 15 | const moves_struct_t [static 1], size_t, char *); | ||
| 14 | 16 | ||
| 15 | STATIC_INLINE bool allowednextmove(uint8_t, uint8_t); | 17 | STATIC_INLINE bool allowednextmove(uint8_t, uint8_t); |
| 16 | STATIC bool allowedmoves(size_t, const uint8_t *); | 18 | STATIC bool allowedmoves(size_t, const uint8_t *); |
| @@ -23,6 +25,7 @@ STATIC_INLINE uint8_t moveopposite(uint8_t); | |||
| 23 | STATIC_INLINE uint8_t reorient_move(uint8_t, uint8_t); | 25 | STATIC_INLINE uint8_t reorient_move(uint8_t, uint8_t); |
| 24 | STATIC_INLINE uint8_t inverse_reorient_move(uint8_t, uint8_t); | 26 | STATIC_INLINE uint8_t inverse_reorient_move(uint8_t, uint8_t); |
| 25 | STATIC_INLINE uint8_t movefollow(uint8_t); | 27 | STATIC_INLINE uint8_t movefollow(uint8_t); |
| 28 | STATIC uint8_t transform_move_basic(uint8_t, uint8_t); | ||
| 26 | STATIC uint8_t transform_move(uint8_t, uint8_t); | 29 | STATIC uint8_t transform_move(uint8_t, uint8_t); |
| 27 | 30 | ||
| 28 | STATIC cube_t move(cube_t, uint8_t); | 31 | STATIC cube_t move(cube_t, uint8_t); |
| @@ -31,6 +34,12 @@ STATIC uint8_t inverse_move(uint8_t); | |||
| 31 | STATIC void sortparallel_moves(size_t, uint8_t*); | 34 | STATIC void sortparallel_moves(size_t, uint8_t*); |
| 32 | STATIC bool are_lastmoves_singlecw(size_t, const uint8_t*); | 35 | STATIC bool are_lastmoves_singlecw(size_t, const uint8_t*); |
| 33 | 36 | ||
| 37 | STATIC int64_t move_variations(const char *, const char *, size_t, char *); | ||
| 38 | STATIC int64_t move_variations_lastqt( | ||
| 39 | const moves_struct_t [static 1], size_t, char *); | ||
| 40 | STATIC int64_t move_variations_unniss( | ||
| 41 | const moves_struct_t [static 1], size_t, char *); | ||
| 42 | |||
| 34 | #define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ | 43 | #define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ |
| 35 | RET_ERROR, ARG_ACTION) \ | 44 | RET_ERROR, ARG_ACTION) \ |
| 36 | const char *VAR_B; \ | 45 | const char *VAR_B; \ |
| @@ -160,7 +169,7 @@ readmoves( | |||
| 160 | STATIC int64_t | 169 | STATIC int64_t |
| 161 | readmoves_struct(const char *moves, moves_struct_t ret[static 1]) | 170 | readmoves_struct(const char *moves, moves_struct_t ret[static 1]) |
| 162 | { | 171 | { |
| 163 | return readmoves(moves, MOVES_STRUCT_MAXLEN, MOVES_STRUCT_MAXLEN, | 172 | return readmoves(moves, NISSY_SIZE_MOVES, NISSY_SIZE_MOVES, |
| 164 | &ret->nnormal, &ret->ninverse, ret->normal, ret->inverse); | 173 | &ret->nnormal, &ret->ninverse, ret->normal, ret->inverse); |
| 165 | } | 174 | } |
| 166 | 175 | ||
| @@ -270,6 +279,51 @@ writemoves_error: | |||
| 270 | return NISSY_ERROR_BUFFER_SIZE; | 279 | return NISSY_ERROR_BUFFER_SIZE; |
| 271 | } | 280 | } |
| 272 | 281 | ||
| 282 | STATIC int64_t | ||
| 283 | writemoves_struct( | ||
| 284 | const moves_struct_t moves[static 1], | ||
| 285 | size_t buf_size, | ||
| 286 | char *buf | ||
| 287 | ) | ||
| 288 | { | ||
| 289 | int64_t w, u; | ||
| 290 | |||
| 291 | w = 0; | ||
| 292 | if (moves->nnormal > 0) { | ||
| 293 | w = writemoves(moves->nnormal, moves->normal, buf_size, buf); | ||
| 294 | if (w < 0) | ||
| 295 | goto writemoves_struct_error; | ||
| 296 | } | ||
| 297 | |||
| 298 | u = 0; | ||
| 299 | if (moves->ninverse > 0) { | ||
| 300 | if (moves->nnormal > 0) { | ||
| 301 | if ((size_t)w >= buf_size) | ||
| 302 | goto writemoves_struct_error; | ||
| 303 | buf[w++] = ' '; | ||
| 304 | } | ||
| 305 | if ((size_t)w >= buf_size) | ||
| 306 | goto writemoves_struct_error; | ||
| 307 | buf[w++] = '('; | ||
| 308 | |||
| 309 | u = writemoves(moves->ninverse, moves->inverse, | ||
| 310 | buf_size-w, buf+w); | ||
| 311 | if (u < 0) | ||
| 312 | goto writemoves_struct_error; | ||
| 313 | |||
| 314 | if ((size_t)w >= buf_size) | ||
| 315 | goto writemoves_struct_error; | ||
| 316 | buf[w + (u++)] = ')'; | ||
| 317 | } | ||
| 318 | |||
| 319 | buf[u+w] = '\0'; | ||
| 320 | return u+w; | ||
| 321 | |||
| 322 | writemoves_struct_error: | ||
| 323 | buf[w] = '\0'; | ||
| 324 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 325 | } | ||
| 326 | |||
| 273 | STATIC_INLINE bool | 327 | STATIC_INLINE bool |
| 274 | allowednextmove(uint8_t m1, uint8_t m2) | 328 | allowednextmove(uint8_t m1, uint8_t m2) |
| 275 | { | 329 | { |
| @@ -408,14 +462,12 @@ move(cube_t c, uint8_t m) | |||
| 408 | } | 462 | } |
| 409 | 463 | ||
| 410 | STATIC uint8_t | 464 | STATIC uint8_t |
| 411 | transform_move(uint8_t m, uint8_t t) | 465 | transform_move_basic(uint8_t m, uint8_t t) |
| 412 | { | 466 | { |
| 413 | uint8_t a, base, modifier; | 467 | uint8_t a, base, modifier; |
| 414 | 468 | ||
| 415 | if (m > MOVE_B3) { | 469 | if (t > 47) { |
| 416 | LOG("transform_move: attempting to transform %s, but " | 470 | LOG("transform_move: invalid trans %" PRIu8 "\n", t); |
| 417 | "transofrmations are only supported for basic moves\n", | ||
| 418 | movestr[m]); | ||
| 419 | return UINT8_ERROR; | 471 | return UINT8_ERROR; |
| 420 | } | 472 | } |
| 421 | 473 | ||
| @@ -431,6 +483,27 @@ transform_move(uint8_t m, uint8_t t) | |||
| 431 | return base + modifier; | 483 | return base + modifier; |
| 432 | } | 484 | } |
| 433 | 485 | ||
| 486 | STATIC uint8_t | ||
| 487 | transform_move(uint8_t m, uint8_t t) | ||
| 488 | { | ||
| 489 | if (m <= MOVE_B3) | ||
| 490 | return transform_move_basic(m, t); | ||
| 491 | |||
| 492 | if (m >= MOVE_Uw && m <= MOVE_Bw3) | ||
| 493 | return 18+transform_move_basic(m-18, t); | ||
| 494 | |||
| 495 | if (m >= MOVE_M && m <= MOVE_E3) | ||
| 496 | return basic_to_slice[ | ||
| 497 | transform_move_basic(slice_to_basic[m], t)]; | ||
| 498 | |||
| 499 | if (m >= MOVE_x && m <= MOVE_z3) | ||
| 500 | return basic_to_rotation[ | ||
| 501 | transform_move_basic(rotation_to_basic[m], t)]; | ||
| 502 | |||
| 503 | LOG("transform_move: invalid move %" PRIu8 "\n", m); | ||
| 504 | return UINT8_ERROR; | ||
| 505 | } | ||
| 506 | |||
| 434 | /* Applies the INVERSE of m BEFORE the scramble corresponding to c */ | 507 | /* Applies the INVERSE of m BEFORE the scramble corresponding to c */ |
| 435 | STATIC cube_t | 508 | STATIC cube_t |
| 436 | premove(cube_t c, uint8_t m) | 509 | premove(cube_t c, uint8_t m) |
| @@ -509,3 +582,140 @@ are_lastmoves_singlecw(size_t n, const uint8_t *moves) | |||
| 509 | 582 | ||
| 510 | return isbase(moves[n-1]) && (!two || isbase(moves[n-2])); | 583 | return isbase(moves[n-1]) && (!two || isbase(moves[n-2])); |
| 511 | } | 584 | } |
| 585 | |||
| 586 | STATIC int64_t | ||
| 587 | move_variations( | ||
| 588 | const char *moves, | ||
| 589 | const char *variation, | ||
| 590 | size_t result_size, | ||
| 591 | char *result | ||
| 592 | ) | ||
| 593 | { | ||
| 594 | moves_struct_t m; | ||
| 595 | int64_t err; | ||
| 596 | |||
| 597 | err = readmoves_struct(moves, &m); | ||
| 598 | if (err < 0) { | ||
| 599 | LOG("[variations] Error reading moves.\n"); | ||
| 600 | return err; | ||
| 601 | } | ||
| 602 | |||
| 603 | if (!strcmp(variation, "lastqt")) { | ||
| 604 | return move_variations_lastqt(&m, result_size, result); | ||
| 605 | } else if (!strcmp(variation, "unniss")) { | ||
| 606 | return move_variations_unniss(&m, result_size, result); | ||
| 607 | } else { | ||
| 608 | LOG("[variations] Error: unknown variation '%s'\n", variation); | ||
| 609 | return NISSY_ERROR_INVALID_VARIATION; | ||
| 610 | } | ||
| 611 | } | ||
| 612 | |||
| 613 | STATIC int64_t | ||
| 614 | move_variations_lastqt( | ||
| 615 | const moves_struct_t s[static 1], | ||
| 616 | size_t result_size, | ||
| 617 | char *result | ||
| 618 | ) | ||
| 619 | { | ||
| 620 | uint8_t n1, n2, i1, i2, swapn1, swapn2, swapi1, swapi2, i, j, k, l; | ||
| 621 | int8_t in1, in2, ii1, ii2; | ||
| 622 | int64_t err, count; | ||
| 623 | size_t u; | ||
| 624 | moves_struct_t ss; | ||
| 625 | |||
| 626 | in1 = s->nnormal-1; | ||
| 627 | in2 = s->nnormal-2; | ||
| 628 | ii1 = s->ninverse-1; | ||
| 629 | ii2 = s->ninverse-2; | ||
| 630 | |||
| 631 | n1 = in1 >= 0 ? s->normal[in1] : UINT8_ERROR; | ||
| 632 | n2 = in2 >= 0 ? s->normal[in2] : UINT8_ERROR; | ||
| 633 | i1 = ii1 >= 0 ? s->inverse[ii1] : UINT8_ERROR; | ||
| 634 | i2 = ii2 >= 0 ? s->inverse[ii2] : UINT8_ERROR; | ||
| 635 | |||
| 636 | swapn1 = in1 >= 0 && n1 % 3 != 1 ? 1 : 0; | ||
| 637 | swapn2 = swapn1 && in2 >= 0 && n2 % 3 != 1 && parallel(n1, n2) ? 1 : 0; | ||
| 638 | swapi1 = ii1 >= 0 && i1 % 3 != 1 ? 1 : 0; | ||
| 639 | swapi2 = swapi1 && ii2 >= 0 && i2 % 3 != 1 && parallel(i1, i2) ? 1 : 0; | ||
| 640 | |||
| 641 | /* Reset ending qt to base so that they are sorted */ | ||
| 642 | ss = *s; | ||
| 643 | if (swapn1 == 1) ss.normal[in1] = 3*movebase(n1); | ||
| 644 | if (swapn2 == 1) ss.normal[in2] = 3*movebase(n2); | ||
| 645 | if (swapi1 == 1) ss.inverse[ii1] = 3*movebase(i1); | ||
| 646 | if (swapi2 == 1) ss.inverse[ii2] = 3*movebase(i2); | ||
| 647 | |||
| 648 | u = 0; | ||
| 649 | count = 0; | ||
| 650 | for (i = 0; i <= swapn2; i++) { | ||
| 651 | if (i == 1) ss.normal[in2] += 2; | ||
| 652 | for (j = 0; j <= swapn1; j++) { | ||
| 653 | if (j == 1) ss.normal[in1] += 2; | ||
| 654 | for (k = 0; k <= swapi2; k++) { | ||
| 655 | if (k == 1) ss.inverse[ii2] += 2; | ||
| 656 | for (l = 0; l <= swapi1; l++) { | ||
| 657 | if (l == 1) ss.inverse[ii1] += 2; | ||
| 658 | |||
| 659 | err = writemoves_struct( | ||
| 660 | &ss, result_size-u, result+u); | ||
| 661 | if (err < 0) | ||
| 662 | goto lastqt_error; | ||
| 663 | u += err; | ||
| 664 | count++; | ||
| 665 | |||
| 666 | if (u >= result_size) | ||
| 667 | goto lastqt_error; | ||
| 668 | result[u++] = '\n'; | ||
| 669 | result[u] = '\0'; | ||
| 670 | |||
| 671 | if (l == 1) ss.inverse[ii1] -= 2; | ||
| 672 | } | ||
| 673 | if (k == 1) ss.inverse[ii2] -= 2; | ||
| 674 | } | ||
| 675 | if (j == 1) ss.normal[in1] -= 2; | ||
| 676 | } | ||
| 677 | if (i == 1) ss.normal[in2] -= 2; | ||
| 678 | } | ||
| 679 | |||
| 680 | return count; | ||
| 681 | |||
| 682 | lastqt_error: | ||
| 683 | LOG("[variations] Error writing result.\n"); | ||
| 684 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 685 | } | ||
| 686 | |||
| 687 | STATIC int64_t | ||
| 688 | move_variations_unniss( | ||
| 689 | const moves_struct_t s[static 1], | ||
| 690 | size_t result_size, | ||
| 691 | char *result | ||
| 692 | ) | ||
| 693 | { | ||
| 694 | size_t i, tot; | ||
| 695 | uint8_t res[NISSY_SIZE_MOVES]; | ||
| 696 | int64_t err; | ||
| 697 | |||
| 698 | tot = s->nnormal + s->ninverse; | ||
| 699 | if (tot > NISSY_SIZE_MOVES) { | ||
| 700 | LOG("[variations] Error: %zu total moves, more than maximum " | ||
| 701 | "allowed %zu", tot, NISSY_SIZE_MOVES); | ||
| 702 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 703 | } | ||
| 704 | |||
| 705 | for (i = 0; i < s->nnormal; i++) | ||
| 706 | res[i] = s->normal[i]; | ||
| 707 | for (i = 0; i < s->ninverse; i++) | ||
| 708 | res[i+s->nnormal] = inverse_move(s->inverse[s->ninverse-i-1]); | ||
| 709 | |||
| 710 | err = writemoves(tot, res, result_size, result); | ||
| 711 | if (err < 0 || (size_t)err > result_size) | ||
| 712 | goto unniss_error; | ||
| 713 | |||
| 714 | result[err++] = '\n'; | ||
| 715 | result[err] = '\0'; | ||
| 716 | return 1; | ||
| 717 | |||
| 718 | unniss_error: | ||
| 719 | LOG("[variations] Error writing result.\n"); | ||
| 720 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 721 | } | ||
diff --git a/src/nissy.c b/src/nissy.c index 4b5d476..17ef960 100644 --- a/src/nissy.c +++ b/src/nissy.c | |||
| @@ -149,6 +149,32 @@ nissy_applytrans_error: | |||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | long long | 151 | long long |
| 152 | nissy_variations( | ||
| 153 | const char *moves, | ||
| 154 | const char *variation, | ||
| 155 | unsigned long long result_size, | ||
| 156 | char *result | ||
| 157 | ) | ||
| 158 | { | ||
| 159 | if (moves == NULL) { | ||
| 160 | LOG("[variations] Error: 'moves' argument is NULL\n"); | ||
| 161 | return NISSY_ERROR_NULL_POINTER; | ||
| 162 | } | ||
| 163 | |||
| 164 | if (variation == NULL) { | ||
| 165 | LOG("[variations] Error: 'variation' argument is NULL\n"); | ||
| 166 | return NISSY_ERROR_NULL_POINTER; | ||
| 167 | } | ||
| 168 | |||
| 169 | if (result == NULL) { | ||
| 170 | LOG("[variations] Error: 'result' argument is NULL\n"); | ||
| 171 | return NISSY_ERROR_NULL_POINTER; | ||
| 172 | } | ||
| 173 | |||
| 174 | return move_variations(moves, variation, result_size, result); | ||
| 175 | } | ||
| 176 | |||
| 177 | long long | ||
| 152 | nissy_getcube( | 178 | nissy_getcube( |
| 153 | long long ep, | 179 | long long ep, |
| 154 | long long eo, | 180 | long long eo, |
diff --git a/src/nissy.h b/src/nissy.h index 38fe656..959b2d8 100644 --- a/src/nissy.h +++ b/src/nissy.h | |||
| @@ -27,6 +27,7 @@ for example 'rotation UF' or 'mirrored BL'. | |||
| 27 | #define NISSY_SIZE_TRANSFORMATION 12U | 27 | #define NISSY_SIZE_TRANSFORMATION 12U |
| 28 | #define NISSY_SIZE_SOLVE_STATS 10U | 28 | #define NISSY_SIZE_SOLVE_STATS 10U |
| 29 | #define NISSY_SIZE_DATAID 255U | 29 | #define NISSY_SIZE_DATAID 255U |
| 30 | #define NISSY_SIZE_MOVES 1000U | ||
| 30 | 31 | ||
| 31 | /* Flags for NISS options */ | 32 | /* Flags for NISS options */ |
| 32 | #define NISSY_NISSFLAG_NORMAL 1U | 33 | #define NISSY_NISSFLAG_NORMAL 1U |
| @@ -99,6 +100,12 @@ not known. | |||
| 99 | #define NISSY_ERROR_INVALID_SOLVER -50LL | 100 | #define NISSY_ERROR_INVALID_SOLVER -50LL |
| 100 | 101 | ||
| 101 | /* | 102 | /* |
| 103 | The value NISSY_ERROR_INVALID_VARIATION means that the given method of | ||
| 104 | finding variations for a solution is not known. | ||
| 105 | */ | ||
| 106 | #define NISSY_ERROR_INVALID_VARIATION -51LL | ||
| 107 | |||
| 108 | /* | ||
| 102 | The value NISSY_ERROR_NULL_POINTER means that one of the provided pointer | 109 | The value NISSY_ERROR_NULL_POINTER means that one of the provided pointer |
| 103 | arguments is NULL. For example, it may be returned by solve when called | 110 | arguments is NULL. For example, it may be returned by solve when called |
| 104 | with a solver that requires some pre-computed data, but the provided | 111 | with a solver that requires some pre-computed data, but the provided |
| @@ -205,6 +212,36 @@ nissy_applytrans( | |||
| 205 | ); | 212 | ); |
| 206 | 213 | ||
| 207 | /* | 214 | /* |
| 215 | Find variations of a given move sequence, for example by changing | ||
| 216 | the direction of the last quarter turn(s), or linearizing a NISS move | ||
| 217 | sequence. The result consists of one or more move sequences, one per line, | ||
| 218 | and it always ends in a newline character. | ||
| 219 | |||
| 220 | Parameters: | ||
| 221 | moves - The moves of which to find the variation. Must be at most | ||
| 222 | NISSY_SIZE_MOVES long. | ||
| 223 | variations - Specify which kind of variations to find, e.g. "lastqt". | ||
| 224 | result_size - The size of the result buffer. | ||
| 225 | result - The result buffer. | ||
| 226 | |||
| 227 | Return values: | ||
| 228 | NISSY_ERROR_NULL_POINTER - One of the provided pointers is NULL. | ||
| 229 | NISSY_ERROR_INVALID_MOVES - The given moves are invalid. | ||
| 230 | NISSY_ERROR_INVALID_VARIATION - The given transformer is not known. | ||
| 231 | NISSY_ERROR_BUFFER_SIZE - Either the result buffer is too small or the | ||
| 232 | given move sequence is longer than | ||
| 233 | NISSY_SIZE_MOVES. | ||
| 234 | Any value >= 0 - The number of variations found. | ||
| 235 | */ | ||
| 236 | long long | ||
| 237 | nissy_variations( | ||
| 238 | const char *moves, | ||
| 239 | const char *variation, | ||
| 240 | unsigned long long result_size, | ||
| 241 | char *result | ||
| 242 | ); | ||
| 243 | |||
| 244 | /* | ||
| 208 | Get the cube with the given ep, eo, cp and co values. The values must be in the | 245 | Get the cube with the given ep, eo, cp and co values. The values must be in the |
| 209 | ranges specified below, but if the option "fix" is given any values outside its | 246 | ranges specified below, but if the option "fix" is given any values outside its |
| 210 | range will be adjusted before using it. The option "fix" also fixes parity and | 247 | range will be adjusted before using it. The option "fix" also fixes parity and |
| @@ -365,6 +402,8 @@ nissy_solve( | |||
| 365 | ); | 402 | ); |
| 366 | 403 | ||
| 367 | /* | 404 | /* |
| 405 | Count the given moves. | ||
| 406 | |||
| 368 | Parameters: | 407 | Parameters: |
| 369 | moves - The moves to be counted. | 408 | moves - The moves to be counted. |
| 370 | 409 | ||
| @@ -379,6 +418,8 @@ nissy_countmoves( | |||
| 379 | ); | 418 | ); |
| 380 | 419 | ||
| 381 | /* | 420 | /* |
| 421 | Compare the two moves sequences. Both must be at most NISSY_SIZE_MOVES long. | ||
| 422 | |||
| 382 | Parameters: | 423 | Parameters: |
| 383 | moves1 - The first sequence of moves to compare. | 424 | moves1 - The first sequence of moves to compare. |
| 384 | moves2 - The second sequence of moves to compare. | 425 | moves2 - The second sequence of moves to compare. |
diff --git a/src/solvers/solutions.h b/src/solvers/solutions.h index 00ed84c..9f209d1 100644 --- a/src/solvers/solutions.h +++ b/src/solvers/solutions.h | |||
| @@ -55,7 +55,7 @@ solution_list_init(solution_list_t sols[static 1], size_t n, char *buf) | |||
| 55 | return false; | 55 | return false; |
| 56 | 56 | ||
| 57 | sols->nsols = 0; | 57 | sols->nsols = 0; |
| 58 | sols->shortest_sol = MAXLEN + 1; | 58 | sols->shortest_sol = SOLUTION_MAXLEN + 1; |
| 59 | sols->size = n; | 59 | sols->size = n; |
| 60 | sols->used = 0; | 60 | sols->used = 0; |
| 61 | sols->buf = buf; | 61 | sols->buf = buf; |
| @@ -162,7 +162,7 @@ appendsolution( | |||
| 162 | uint8_t t; | 162 | uint8_t t; |
| 163 | solution_moves_t tsol[NTRANS]; | 163 | solution_moves_t tsol[NTRANS]; |
| 164 | 164 | ||
| 165 | if (moves->nmoves + moves->npremoves > MAXLEN) | 165 | if (moves->nmoves + moves->npremoves > SOLUTION_MAXLEN) |
| 166 | goto appendsolution_error_solution_length; | 166 | goto appendsolution_error_solution_length; |
| 167 | 167 | ||
| 168 | for ( | 168 | for ( |
diff --git a/src/solvers/solutions_types_macros.h b/src/solvers/solutions_types_macros.h index f1cb517..e57e039 100644 --- a/src/solvers/solutions_types_macros.h +++ b/src/solvers/solutions_types_macros.h | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | #define MAXLEN 20 | 1 | #define SOLUTION_MAXLEN 20 |
| 2 | 2 | ||
| 3 | typedef struct { | 3 | typedef struct { |
| 4 | uint8_t nmoves; | 4 | uint8_t nmoves; |
| 5 | uint8_t moves[MAXLEN]; | 5 | uint8_t moves[SOLUTION_MAXLEN]; |
| 6 | uint8_t npremoves; | 6 | uint8_t npremoves; |
| 7 | uint8_t premoves[MAXLEN]; | 7 | uint8_t premoves[SOLUTION_MAXLEN]; |
| 8 | } solution_moves_t; | 8 | } solution_moves_t; |
| 9 | 9 | ||
| 10 | typedef struct { | 10 | typedef struct { |
