nissy-nx

A Rubik's cube optimal solver
git clone https://git.tronto.net/nissy-nx
Download | Log | Files | Refs | README | LICENSE

commit 48cd8b6b1779f34ba0507cb697492de83c4e9da8
parent de0352a2926b0708400a9629c1da813455a6f442
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Sun, 27 Feb 2022 15:36:02 +0100

Moved random_cube() from cube.c to commands.c and fixed a bug in corners only and edges
only scrambles. Added fmc scrambles (with R'U'F). Updated manpage for scramble and cleanup.

Diffstat:
MTODO.md | 3+--
Mdoc/nissy.1 | 16+++++++++++++---
Msrc/commands.c | 71++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/commands.h | 2++
Msrc/cube.c | 28+---------------------------
Msrc/cube.h | 7+------
Msrc/cubetypes.h | 2+-
7 files changed, 81 insertions(+), 48 deletions(-)

diff --git a/TODO.md b/TODO.md @@ -6,7 +6,6 @@ It's more of a personal reminder than anything else. ## For version 2.1 ### Scrambles * dr and htr scrambles -* rufify ### Memory management * Free large tables from memory before exit (this is not strictly necessary, but can help with WSL bugs) @@ -37,7 +36,6 @@ including e.g. solutions that were not shown because -c) ### Improvements to currently implemented commands * 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 * silent batch mode without >>> @@ -88,6 +86,7 @@ including e.g. solutions that were not shown because -c) ### Cleanup * Remove khuge from everywhere +* Arrays (commands, steps...): end with NULL and remove size constant * sort again functions alphabetically in their files * more stuff to load at start (or when suitable command is called) rather than when called directly, to avoid nasty problems with threading diff --git a/doc/nissy.1 b/doc/nissy.1 @@ -43,6 +43,13 @@ are the following: . .Bl -tag -width Ds . +.It Nm cleanup Ar scramble +Rewrites the given scramble using only the 18 base (HTM) moves and at most two +rotations at the end. If +Ar scramble +uses NISS, all moves done on normal scramble are written first, followed by +all moves done on inverse. +. .It Nm commands List all available commands. . @@ -83,15 +90,18 @@ 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). +.It Ar eo +Scramble with solved EO on F/B axis. +.It Ar fmc +Scramble the full cube and the resulting scramble starts and ends with +the moves R\(aq U\(aq F. .El . -.It Nm solve Ar step Oo Ar options Oc Ar scramble. +.It Nm solve Ar step Oo Ar options Oc Ar scramble Solve the given .Ar step on the given diff --git a/src/commands.c b/src/commands.c @@ -166,6 +166,10 @@ Command *commands[NCOMMANDS] = { &version_cmd, }; +/* Other constants ***********************************************************/ + +char *scrtypes[20] = { "eo", "corners", "edges", "fmc", NULL }; + /* Arg parsing functions implementation **************************************/ CommandArgs * @@ -277,7 +281,6 @@ scramble_parse_args(int c, char **v) a->success = true; a->n = 1; - a->scrt = -1; for (i = 0; i < c; i++) { if (!strcmp(v[i], "-n") && i+1 < c) { @@ -396,8 +399,8 @@ static void scramble_exec(CommandArgs *args) { Cube cube; - Alg *scr; - int i; + Alg *scr, *ruf, *aux; + int i, j, eo, ep, co, cp, a[12]; init_all_movesets(); init_symcoord(); @@ -405,8 +408,56 @@ scramble_exec(CommandArgs *args) srand(time(NULL)); for (i = 0; i < args->n; i++) { - cube = random_cube(args->scrt); + eo = rand() % POW2TO11; + ep = rand() % FACTORIAL12; + co = rand() % POW3TO7; + cp = rand() % FACTORIAL8; + + if (!strcmp(args->scrtype, "eo")) { + eo = 0; + } else if (!strcmp(args->scrtype, "corners")) { + eo = 0; + ep = 0; + index_to_perm(cp, 8, a); + if (perm_sign(a, 8) == 1) { + swap(&a[0], &a[1]); + cp = perm_to_index(a, 8); + } + } else if (!strcmp(args->scrtype, "edges")) { + co = 0; + cp = 0; + index_to_perm(ep, 12, a); + if (perm_sign(a, 12) == 1) { + swap(&a[0], &a[1]); + ep = perm_to_index(a, 12); + } + } + + cube = fourval_to_cube(eo, ep, co, cp); scr = solve_2phase(cube, 1); + + if (!strcmp(args->scrtype, "fmc")) { + aux = new_alg(""); + copy_alg(scr, aux); + /* Trick to rufify for free: rotate the scramble * + * so that it does not start with F or end with R */ + for (j = 0; j < NROTATIONS; j++) { + if (base_move(scr->move[0]) != F && + base_move(scr->move[0]) != B && + base_move(scr->move[scr->len-1]) != R && + base_move(scr->move[scr->len-1]) != L) + break; + copy_alg(aux, scr); + transform_alg(j, scr); + } + copy_alg(scr, aux); + ruf = new_alg("R' U' F"); + copy_alg(ruf, scr); + compose_alg(scr, aux); + compose_alg(scr, ruf); + free_alg(aux); + free_alg(ruf); + } print_alg(scr, false); free_alg(scr); } @@ -576,12 +627,14 @@ 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; + for (i = 0; scrtypes[i] != NULL; i++) { + if (!strcmp(scrtypes[i], str)) { + strcpy(args->scrtype, scrtypes[i]); + return true; + } + } - return args->scrt != -1; + return false; } static bool diff --git a/src/commands.h b/src/commands.h @@ -1,6 +1,8 @@ #ifndef COMMANDS_H #define COMMANDS_H +#include <time.h> + #include "solve.h" #include "steps.h" diff --git a/src/cube.c b/src/cube.c @@ -4,7 +4,6 @@ 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(); @@ -18,8 +17,6 @@ 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 @@ -187,7 +184,7 @@ fix_cofbcorl(CubeArray *arr) } } -static Cube +Cube fourval_to_cube(int eofb, int ep, int coud, int cp) { CubeArray *arr; @@ -544,29 +541,6 @@ print_cube(Cube cube) printf("\n"); } -Cube -random_cube(int scrt) -{ - int ep, cp, eo, co; - - ep = rand() % FACTORIAL12; - cp = rand() % FACTORIAL8; - eo = rand() % POW2TO11; - co = rand() % POW3TO7; - - 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 fourval_to_cube(eo, ep, co, cp); -} - Center what_center_at(Cube cube, Center c) { diff --git a/src/cube.h b/src/cube.h @@ -2,16 +2,11 @@ #define CUBE_H #include <stdio.h> -#include <time.h> #include "env.h" #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,11 +23,11 @@ bool is_solved_center(Cube cube, Center c); bool is_solved_corner(Cube cube, Corner c); bool is_solved_edge(Cube cube, Edge e); void epos_to_partial_ep(int epos, int *ep, int *ss); +Cube fourval_to_cube(int eofb, int ep, int coud, int cp); 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(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 @@ -157,7 +157,7 @@ commandargs Step * step; Command * command; /* For help */ int n; - int scrt; + char scrtype[20]; bool scrstdin; bool header; };