nissy-fmc

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

commit 5d536a65d75f7ee452a2164858342937e2332c6d
parent 9dd3e15297267c22ded9fbba064f54d64fad339c
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Sat, 15 Apr 2023 11:50:03 +0200

Changed solve interface

Diffstat:
Msrc/coord.c | 4++--
Msrc/main.c | 71++++++++++++++++++++++++++++-------------------------------------------
Msrc/solve.c | 165+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/solve.h | 7++-----
4 files changed, 138 insertions(+), 109 deletions(-)

diff --git a/src/coord.c b/src/coord.c @@ -590,7 +590,7 @@ write_coord_sd(Coordinate *coord) uint64_t M, N; bool r; - strcat(fname, "tables/sd_"); + strcpy(fname, "tables/sd_"); strcat(fname, coord->name); if ((f = fopen(fname, "wb")) == NULL) @@ -618,7 +618,7 @@ write_coord_ttable(Coordinate *coord) uint64_t M; bool r; - strcat(fname, "tables/tt_"); + strcpy(fname, "tables/tt_"); strcat(fname, coord->name); if ((f = fopen(fname, "wb")) == NULL) diff --git a/src/main.c b/src/main.c @@ -1,3 +1,7 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "cube.h" #include "solve.h" #define MAX_SOLS 999 @@ -5,55 +9,36 @@ int main(int argc, char *argv[]) { - int i, m, n; - long val; - Cube c; - SolutionType t; - Alg sols[999]; - - if (argc < 2) { - fprintf(stderr, "Not enough arguments given\n"); - return -1; - } - - m = 0; - t = NORMAL; + char sols[99999]; init_cube(); - for (i = 2; i < argc; i++) { - if (!strcmp(argv[i], "-m") && i+1 < argc) { - val = strtol(argv[++i], NULL, 10); - if (val < 0 || val > 100) { - fprintf(stderr, "Invalid number of moves\n"); - return 2; - } - m = val; - } else if (!strcmp(argv[i], "-I")) { - t = INVERSE; - } else if (!strcmp(argv[i], "-N")) { - t = NISS; - } else { - break; - } - } - - if (i == argc) { - fprintf(stderr, "No scramble given\n"); - return 4; + if (argc != 6) { + fprintf(stderr, "Not enough arguments given\n"); + return -1; } - make_solved(&c); - if (!apply_scramble(argv[i], &c)) { - fprintf(stderr, "Invalid scramble: %s\n", argv[i]); - return 5; - } + char *step = argv[1]; + char *trans = argv[2]; + int d = strtol(argv[3], NULL, 10); + char *type = argv[4]; + char *scramble = argv[5]; - n = solve(&c, argv[1], m, t, uf, sols); /* TODO: trans */ - for (i = 0; i < n; i++) { - char buf[66]; - int l = alg_string(&sols[i], buf); - printf("%s (%d)\n", buf, l); + switch (solve(step, trans, d, type, scramble, sols)) { + case 1: + fprintf(stderr, "Error parsing step: %s\n", step); + return -1; + case 2: + fprintf(stderr, "Error parsing trans: %s\n", trans); + return -1; + case 4: + fprintf(stderr, "Error parsing type: %s\n", type); + return -1; + case 5: + fprintf(stderr, "Error applying scramble: %s\n", scramble); + return -1; + default: + printf(sols); } return 0; diff --git a/src/solve.c b/src/solve.c @@ -1,9 +1,11 @@ #define SOLVE_C #include "solve.h" +#include "pruning.h" #define MAX_N_COORD 3 +typedef enum { NORMAL, INVERSE, NISS } SolutionType; typedef struct { uint64_t val; Trans t; } Movable; typedef struct { char * shortname; @@ -23,11 +25,9 @@ typedef struct { Step * s; Trans t; SolutionType st; - int * nsols; - Alg * sols; + char ** sol; int d; int bound; - bool can_niss; bool niss; bool has_nissed; Move last[2]; @@ -75,16 +75,20 @@ Step *steps[] = { &eofb_HTM, &drud_HTM, &drfin_drud, NULL }; static void append_sol(DfsArg *arg) { - int i; + Alg alg; + int i, n; - copy_alg(arg->current_alg, &arg->sols[*arg->nsols]); - transform_alg(inverse_trans(arg->t), &arg->sols[*arg->nsols]); + copy_alg(arg->current_alg, &alg); + transform_alg(inverse_trans(arg->t), &alg); if (arg->st == INVERSE) - for (i = 0; i < arg->sols[*arg->nsols].len; i++) - arg->sols[*arg->nsols].inv[i] = true; + for (i = 0; i < alg.len; i++) + alg.inv[i] = true; - (*arg->nsols)++; + n = alg_string(&alg, *arg->sol); + (*arg->sol)[n] = '\n'; + (*arg->sol)[n+1] = 0; + *arg->sol += (n+1); } static bool @@ -121,11 +125,9 @@ copy_dfsarg(DfsArg *src, DfsArg *dst) dst->st = src->st; dst->d = src->d; dst->bound = src->bound; /* In theory not needed */ - dst->can_niss = src->can_niss; dst->niss = src->niss; dst->has_nissed = src->has_nissed; - dst->nsols = src->nsols; - dst->sols = src->sols; + dst->sol = src->sol; dst->current_alg = src->current_alg; for (i = 0; i < 2; i++) { @@ -170,7 +172,7 @@ dfs(DfsArg *arg) if (arg->bound == 0) { len = arg->current_alg->len == arg->d; singlecw = singlecwend(arg->current_alg); - niss = !arg->can_niss || arg->has_nissed; + niss = !(arg->st == NISS) || arg->has_nissed; if (len && singlecw && niss) append_sol(arg); return; @@ -249,7 +251,7 @@ dfs_move_checkstop(DfsArg *arg) /* Computing bound for coordinates */ arg->bound = estimate_step(arg->s, arg->ind); - if (arg->can_niss && !arg->niss) + if (arg->st == NISS && !arg->niss) arg->bound = MIN(1, arg->bound); return arg->bound + arg->current_alg->len > arg->d ; @@ -261,7 +263,7 @@ niss_makes_sense(DfsArg *arg) Cube testcube; DfsArg aux; - if (arg->niss || !arg->can_niss || arg->current_alg->len == 0) + if (arg->niss || !(arg->st == NISS) || arg->current_alg->len == 0) return false; make_solved(&testcube); @@ -299,68 +301,113 @@ singlecwend(Alg *alg) /* Public functions **********************************************************/ +static bool +set_step(char *str, Step **step) +{ + int i; + + for (i = 0; steps[i] != NULL; i++) { + if (!strcmp(steps[i]->shortname, str)) { + *step = steps[i]; + return true; + } + } + + return false; +} + +static bool +set_solutiontype(char *str, SolutionType *st) +{ + if (!strcmp(str, "normal")) { + *st = NORMAL; + return true; + } + if (!strcmp(str, "inverse")) { + *st = INVERSE; + return true; + } + if (!strcmp(str, "niss")) { + *st = NISS; + return true; + } + + return false; +} + +static bool +set_trans(char *str, Trans *t) +{ + if (!strcmp(str, "uf")) { + *t = uf; + return true; + } + if (!strcmp(str, "fr")) { + *t = fr; + return true; + } + if (!strcmp(str, "rd")) { + *t = rd; + return true; + } + + return false; +} + int -solve(Cube *cube, char *stepstr, int m, SolutionType st, Trans t, Alg *sol) +solve(char *step, char *trans, int d, char *type, char *scramble, char *sol) { - int i, n; + int i; Alg alg; Cube c; DfsArg arg; - Step *step; + + arg.niss = false; + arg.has_nissed = false; + arg.last[0] = NULLMOVE; + arg.last[1] = NULLMOVE; + arg.lastinv[0] = NULLMOVE; + arg.lastinv[1] = NULLMOVE; + + alg.len = 0; + arg.current_alg = &alg; + + arg.d = d; + arg.sol = &sol; + + if (!set_step(step, &arg.s)) return 1; /* Prepare step TODO: remove all initialization! */ - step = NULL; - for (i = 0; steps[i] != NULL; i++) - if (!strcmp(steps[i]->shortname, stepstr)) - step = steps[i]; - if (step == NULL) { - fprintf(stderr, "No step to solve!\n"); - return 0; - } PDGenData pdg; - pdg.moveset = step->moveset; - for (i = 0; step->coord[i] != NULL; i++) { - gen_coord(step->coord[i]); - pdg.coord = step->coord[i]; - pdg.compact = step->compact_pd[i]; + pdg.moveset = arg.s->moveset; + for (i = 0; arg.s->coord[i] != NULL; i++) { + gen_coord(arg.s->coord[i]); + pdg.coord = arg.s->coord[i]; + pdg.compact = arg.s->compact_pd[i]; pdg.pd = NULL; - step->pd[i] = genptable(&pdg); - if (step->compact_pd[i]) { - gen_coord(step->fallback_coord[i]); - pdg.coord = step->fallback_coord[i]; + arg.s->pd[i] = genptable(&pdg); + if (arg.s->compact_pd[i]) { + gen_coord(arg.s->fallback_coord[i]); + pdg.coord = arg.s->fallback_coord[i]; pdg.compact = false; pdg.pd = NULL; - step->fallback_pd[i] = genptable(&pdg); + arg.s->fallback_pd[i] = genptable(&pdg); } } - alg.len = 0; - n = 0; + if (!set_trans(trans, &arg.t)) return 2; - /* Prepare cube for solve */ + if (!set_solutiontype(type, &arg.st)) return 4; + + make_solved(&c); + if (!apply_scramble(scramble, &c)) return 5; + if (arg.st == INVERSE) + invert_cube(&c); + apply_trans(arg.t, &c); arg.cube = &c; - copy_cube(cube, arg.cube); - if (st == INVERSE) - invert_cube(arg.cube); - apply_trans(t, arg.cube); - arg.s = step; compute_ind(&arg); - arg.t = t; - arg.st = st; - arg.can_niss = st == NISS; - arg.nsols = &n; - arg.sols = sol; - arg.d = m; - arg.niss = false; - arg.has_nissed = false; - arg.last[0] = NULLMOVE; - arg.last[1] = NULLMOVE; - arg.lastinv[0] = NULLMOVE; - arg.lastinv[1] = NULLMOVE; - arg.current_alg = &alg; dfs(&arg); - - return n; + return 0; } diff --git a/src/solve.h b/src/solve.h @@ -1,10 +1,7 @@ #ifndef SOLVE_H #define SOLVE_H -#include "pruning.h" - -typedef enum { NORMAL, INVERSE, NISS } SolutionType; - -int solve(Cube *cube, char *step, int m, SolutionType st, Trans t, Alg *sol); +/* Returns 0 on success, 1-based index of bad arg on failure */ +int solve(char *step, char *trans, int d, char *type, char *scr, char *sol); #endif