commit 8cec37cb3e490b06639f2e05df8b947a9333d5d2
parent 975e3eafbae15b93a1a4f160dd781d359a6c717b
Author: Sebastiano Tronto <sebastiano.tronto@gmail.com>
Date: Sun, 26 Dec 2021 22:42:37 +0100
Added scramble command
Diffstat:
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;