nissy-fmc

A Rubik's cube FMC assistant
git clone https://git.tronto.net/nissy-fmc
Download | Log | Files | Refs | README | LICENSE

commit 8cec37cb3e490b06639f2e05df8b947a9333d5d2
parent 975e3eafbae15b93a1a4f160dd781d359a6c717b
Author: Sebastiano Tronto <sebastiano.tronto@gmail.com>
Date:   Sun, 26 Dec 2021 22:42:37 +0100

Added scramble command

Diffstat:
MMakefile | 2+-
MTODO.md | 5++---
Mdoc/nissy.1 | 21++++++++++++++++++++-
Dnissy | 0
Anissy-2.0beta10.tar.gz | 0
Dnissy-2.0beta9.tar.gz | 0
Mnissy.exe | 0
Msrc/commands.c | 107++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/cube.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/cube.h | 6+++++-
Msrc/cubetypes.h | 2++
Msrc/solve.c | 2+-
12 files changed, 204 insertions(+), 36 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ # See LICENSE file for copyright and license details. -VERSION = 2.0beta9 +VERSION = 2.0beta10 PREFIX = /usr/local MANPREFIX = ${PREFIX}/share/man diff --git a/TODO.md b/TODO.md @@ -10,7 +10,6 @@ It's more of a personal reminder than anything else. ### Commands that are available in nissy 1.0, but not in this version (yet): * drcorners (solve corners after dr) * search and improve non-optimal subsequences -* **scramble [dr, corners only, edges only, htr, fmc(RUF)...]** * save and edit algs as "variables" (or just use a "logging system" to keep info about previously run commands, including e.g. solutions that were not shown because -c) @@ -21,7 +20,8 @@ including e.g. solutions that were not shown because -c) * Other common steps (LSE, ...) ### Improvements to currently implemented commands -* **solve should re-orient first if needed and not just give up if centers are off** +* solve should re-orient first if needed and not just give up if centers are off +* more scramble types (dr, htr, fmc(rufify)...) * solve should try up to a small bound without loading the large pruning table ### New features @@ -29,7 +29,6 @@ including e.g. solutions that were not shown because -c) * configurability: add an `alias` command, run config file at startup * configure max ram to be used (via config file and/or command line option) * transform alg, rufify etc... -* more scramble stuff (scramble FMC with rufify...) * command notation to list available moves * make multi-step solve much more general and create command diff --git a/doc/nissy.1 b/doc/nissy.1 @@ -71,7 +71,26 @@ Display a text-only description of the cube obtained after applying .It Nm quit Quit nissy. . -.It Nm solve Ar step Oo Ar options Oc Ar scramble +.It Nm scramble Oo Fl n Ar N Oc Oo Ar type Oc +Print a randomly-generated (random position) scramble +. +If +.Ar N +is given, it produces +.Ar N +scrambles. +.Ar type +can be specified to be one of the following: +.Bl -tag -width Ds +.It Ar eo +Scramble with solved EO on F/B axis. +.It Ar corners +Scramble with solved edges (only cornes are scrambled). +.It Ar edges +Scramble with solved corners (only edges are scrambled). +.El +. +.It Nm solve Ar step Oo Ar options Oc Ar scramble. Solve the given .Ar step on the given diff --git a/nissy b/nissy Binary files differ. diff --git a/nissy-2.0beta10.tar.gz b/nissy-2.0beta10.tar.gz Binary files differ. diff --git a/nissy-2.0beta9.tar.gz b/nissy-2.0beta9.tar.gz Binary files differ. diff --git a/nissy.exe b/nissy.exe Binary files differ. diff --git a/src/commands.c b/src/commands.c @@ -8,12 +8,14 @@ CommandArgs * print_parse_args(int c, char **v); CommandArgs * parse_only_scramble(int c, char **v); CommandArgs * parse_no_arg(int c, char **v); CommandArgs * solve_parse_args(int c, char **v); +CommandArgs * scramble_parse_args(int c, char **v); /* Exec functions ************************************************************/ static void gen_exec(CommandArgs *args); static void invert_exec(CommandArgs *args); static void solve_exec(CommandArgs *args); +static void scramble_exec(CommandArgs *args); static void steps_exec(CommandArgs *args); static void commands_exec(CommandArgs *args); static void print_exec(CommandArgs *args); @@ -26,6 +28,7 @@ static void version_exec(CommandArgs *args); /* Local functions ***********************************************************/ static bool read_step(CommandArgs *args, char *str); +static bool read_scrtype(CommandArgs *args, char *str); static bool read_scramble(int c, char **v, CommandArgs *args); /* Commands ******************************************************************/ @@ -40,6 +43,15 @@ solve_cmd = { }; Command +scramble_cmd = { + .name = "scramble", + .usage = "scramble [TYPE] [-n N]", + .description = "Get a random-position scramble", + .parse_args = scramble_parse_args, + .exec = scramble_exec, +}; + +Command gen_cmd = { .name = "gen", .usage = "gen [-t N]", @@ -137,6 +149,7 @@ Command *commands[NCOMMANDS] = { &print_cmd, &quit_cmd, &solve_cmd, + &scramble_cmd, &steps_cmd, &twophase_cmd, &unniss_cmd, @@ -243,6 +256,37 @@ solve_parse_args(int c, char **v) } CommandArgs * +scramble_parse_args(int c, char **v) +{ + int i; + long val; + + CommandArgs *a = new_args(); + + a->success = true; + a->n = 1; + a->scrt = -1; + + for (i = 0; i < c; i++) { + if (!strcmp(v[i], "-n") && i+1 < c) { + val = strtol(v[++i], NULL, 10); + if (val < 1 || val > 1000000) { + fprintf(stderr, + "Invalid number of scrambles.\n"); + a->success = false; + return a; + } + a->n = val; + } else if (!read_scrtype(a, v[i])) { + a->success = false; + return a; + } + } + + return a; +} + +CommandArgs * gen_parse_args(int c, char **v) { int val; @@ -342,6 +386,26 @@ solve_exec(CommandArgs *args) } static void +scramble_exec(CommandArgs *args) +{ + Cube cube; + Alg *scr; + int i; + + init_movesets(); + init_symcoord(); + + srand(time(NULL)); + + for (i = 0; i < args->n; i++) { + cube = random_cube(args->scrt); + scr = solve_2phase(cube, 1); + print_alg(scr, false); + free_alg(scr); + } +} + +static void gen_exec(CommandArgs *args) { int i; @@ -454,21 +518,6 @@ version_exec(CommandArgs *args) /* Local functions implementation ********************************************/ static bool -read_step(CommandArgs *args, char *str) -{ - int i; - - for (i = 0; i < NSTEPS; i++) { - if (steps[i] != NULL && !strcmp(steps[i]->shortname, str)) { - args->step = steps[i]; - return true; - } - } - - return false; -} - -static bool read_scramble(int c, char **v, CommandArgs *args) { int i, k, n; @@ -510,6 +559,34 @@ read_scramble(int c, char **v, CommandArgs *args) return args->scramble->len > 0; } +static bool +read_scrtype(CommandArgs *args, char *str) +{ + int i; + + args->scrt = -1; + for (i = 0; i < NSCRTYPES; i++) + if (!strcmp(scrtypes[i], str)) + args->scrt = i; + + return args->scrt != -1; +} + +static bool +read_step(CommandArgs *args, char *str) +{ + int i; + + for (i = 0; i < NSTEPS; i++) { + if (steps[i] != NULL && !strcmp(steps[i]->shortname, str)) { + args->step = steps[i]; + return true; + } + } + + return false; +} + /* Public functions implementation *******************************************/ void diff --git a/src/cube.c b/src/cube.c @@ -2,6 +2,9 @@ /* Local functions ***********************************************************/ +static void fix_eorleoud(CubeArray *arr); +static void fix_cofbcorl(CubeArray *arr); +static Cube fourval_to_cube(int eofb, int ep, int coud, int cp); static void init_inverse(); static bool read_invtables_file(); static bool write_invtables_file(); @@ -15,6 +18,8 @@ static uint16_t co_invtable[POW3TO7][FACTORIAL8]; static uint16_t cp_invtable[FACTORIAL8]; static uint16_t cpos_invtable[FACTORIAL6]; +char *scrtypes[NSCRTYPES] = { "eo", "corners", "edges" }; + /* Functions implementation **************************************************/ int @@ -139,6 +144,71 @@ epos_to_partial_ep(int epos, int *ep, int *ss) ep[i] = ss[eps[is++]]; } +static void +fix_eorleoud(CubeArray *arr) +{ + int i; + + for (i = 0; i < 12; i++) { + if ((edge_slice(i) == 0 && edge_slice(arr->ep[i]) != 0) || + (edge_slice(i) != 0 && edge_slice(arr->ep[i]) == 0)) { + arr->eorl[i] = 1 - arr->eofb[i]; + } else { + arr->eorl[i] = arr->eofb[i]; + } + + if ((edge_slice(i) == 2 && edge_slice(arr->ep[i]) != 2) || + (edge_slice(i) != 2 && edge_slice(arr->ep[i]) == 2)) { + arr->eoud[i] = 1 - arr->eofb[i]; + } else { + arr->eoud[i] = arr->eofb[i]; + } + } +} + +static void +fix_cofbcorl(CubeArray *arr) +{ + int i; + + for (i = 0; i < 8; i++) { + if (i % 2 == arr->cp[i] % 2) { + arr->cofb[i] = arr->coud[i]; + arr->corl[i] = arr->coud[i]; + } else { + if (arr->cp[i] % 2 == 0) { + arr->cofb[i] = (arr->coud[i]+1)%3; + arr->corl[i] = (arr->coud[i]+2)%3; + } else { + arr->cofb[i] = (arr->coud[i]+2)%3; + arr->corl[i] = (arr->coud[i]+1)%3; + } + } + } +} + +static Cube +fourval_to_cube(int eofb, int ep, int coud, int cp) +{ + CubeArray *arr; + + arr = new_cubearray((Cube){0}, pf_all); + + index_to_perm(ep, 12, arr->ep); + index_to_perm(cp, 8, arr->cp); + int_to_sum_zero_array(eofb, 2, 12, arr->eofb); + int_to_sum_zero_array(coud, 3, 8, arr->coud); + + /* fix parity */ + if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8)) + swap(&(arr->ep[0]), &(arr->ep[1])); + + fix_eorleoud(arr); + fix_cofbcorl(arr); + + return arrays_to_cube(arr, pf_all); +} + void free_cubearray(CubeArray *arr, PieceFilter f) { @@ -475,10 +545,8 @@ print_cube(Cube cube) } Cube -random_cube() +random_cube(int scrt) { - CubeArray *arr = new_cubearray((Cube){0}, pf_4val); - Cube ret; int ep, cp, eo, co; ep = rand() % FACTORIAL12; @@ -486,18 +554,17 @@ random_cube() eo = rand() % POW2TO11; co = rand() % POW3TO7; - index_to_perm(ep, 12, arr->ep); - index_to_perm(cp, 8, arr->cp); - int_to_sum_zero_array(eo, 2, 12, arr->eofb); - int_to_sum_zero_array(co, 3, 8, arr->coud); - - if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8)) - swap(&(arr->ep[0]), &(arr->ep[1])); - - ret = arrays_to_cube(arr, pf_4val); - free_cubearray(arr, pf_4val); + if (scrt == 0) { /* EO */ + eo = 0; + } else if (scrt == 1) { /* corners */ + eo = 0; + ep = 0; + } else if (scrt == 2) { /* edges */ + co = 0; + cp = 0; + } - return ret; + return fourval_to_cube(eo, ep, co, cp); } Center diff --git a/src/cube.h b/src/cube.h @@ -8,6 +8,10 @@ #include "pf.h" #include "utils.h" +#define NSCRTYPES 3 + +extern char *scrtypes[NSCRTYPES]; + Cube admissible_ep(Cube cube, PieceFilter f); int array_ep_to_epos(int *ep, int *eps_solved); Cube arrays_to_cube(CubeArray *arr, PieceFilter f); @@ -28,7 +32,7 @@ void free_cubearray(CubeArray *arr, PieceFilter f); Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf); CubeArray * new_cubearray(Cube cube, PieceFilter f); void print_cube(Cube cube); -Cube random_cube(); +Cube random_cube(int scrt); Center what_center_at(Cube cube, Center c); Corner what_corner_at(Cube cube, Corner c); Edge what_edge_at(Cube cube, Edge e); diff --git a/src/cubetypes.h b/src/cubetypes.h @@ -156,6 +156,8 @@ commandargs SolveOptions * opts; Step * step; Command * command; /* For help */ + int n; + int scrt; }; struct diff --git a/src/solve.c b/src/solve.c @@ -452,7 +452,7 @@ solve_2phase(Cube cube, int nthreads) opts1.min_moves = 0; opts1.max_moves = 13; - opts1.max_solutions = 100; + opts1.max_solutions = 20; opts1.nthreads = nthreads; opts1.optimal = 3; opts1.can_niss = false;