aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--TODO.txt25
-rw-r--r--cube.c59
-rw-r--r--cube.h41
3 files changed, 94 insertions, 31 deletions
diff --git a/TODO.txt b/TODO.txt
index 6e000ad..8add9cc 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,11 +1,12 @@
1## Generic solver 1## Solving
2
3### Generic solver
2 4
3* finish implementation
4* tests: solve full cube (max 7-8 moves?) 5* tests: solve full cube (max 7-8 moves?)
5* more tests: eo and other stuff 6* more tests: eo and other stuff
6* benchmarks 7* benchmarks
7 8
8## Coordinates 9### Coordinates
9 10
10* [done] eo 11* [done] eo
11* co 12* co
@@ -17,22 +18,10 @@
17 18
18What about symcoord? 19What about symcoord?
19 20
20## More I/O 21### More solvers
21
22
23## Solving
24
25All solving functions take a cube and some parameters as input.
26 22
27* Depth [uint, <= 20]: all solvers work at fixed depth. The caller 23* solve_light: first based on solve_generic, then optimize; benchmark
28 implementation can implement an A* search. 24 to see up to what length it works best (7 moves? 10 moves?)
29* max [int]: the maximum number of solutions to find. Set to a negative
30 value for all solutions.
31* sol [move_t *]: the array for returning the solutions. The caller
32 should make sure that it can hold at least max * depth values.
33* Table [uint8_t *]: table with all the necessare pre-computed info.
34 The table can be generated with a companion function, but reading
35 from and writing to file is delegated to the caller implementation.
36 25
37### Implement the following solvers: 26### Implement the following solvers:
38 27
diff --git a/cube.c b/cube.c
index 3ba3926..cd93d48 100644
--- a/cube.c
+++ b/cube.c
@@ -3688,19 +3688,51 @@ implementation of all the solving algorithms.
3688 3688
3689typedef struct { 3689typedef struct {
3690 cube_t cube; 3690 cube_t cube;
3691 int (*estimate)(cube_t);
3692 uint8_t depth; 3691 uint8_t depth;
3693 int maxsols; 3692 int maxsols;
3694 move_t *sols; 3693 move_t *sols;
3695 int nsols; 3694 int nsols;
3696 int nmoves; 3695 int nmoves;
3697 move_t moves[20]; 3696 move_t moves[20];
3697 int (*estimate)(cube_t);
3698} dfs_arg_t; 3698} dfs_arg_t;
3699 3699
3700int 3700static bool
3701allowednextmove(dfs_arg_t arg, move_t m)
3702{
3703 int n;
3704 move_t mbase, l1base, l2base, maxis, l1axis, l2axis;
3705
3706 n = arg.nmoves;
3707
3708 if (n == 0)
3709 return true;
3710
3711 mbase = m / 3;
3712 maxis = mbase / 2;
3713 l1base = arg.moves[n-1] / 3;
3714 l1axis = l1base / 2;
3715
3716 if (mbase == l1base || (maxis == l1axis && mbase < l1base))
3717 return false;
3718
3719 if (n == 1)
3720 return true;
3721
3722 l2base = arg.moves[n-2] / 3;
3723 l2axis = l1base / 2;
3724
3725 return l1axis != l2axis || mbase != l2base;
3726}
3727
3728static int
3701solve_generic_dfs(dfs_arg_t arg) 3729solve_generic_dfs(dfs_arg_t arg)
3702{ 3730{
3703 int bound = arg.estimate(arg.cube); 3731 dfs_arg_t nextarg;
3732 int bound, ret;
3733 move_t m;
3734
3735 bound = arg.estimate(arg.cube);
3704 3736
3705 if (arg.nsols == arg.maxsols || bound + arg.nmoves > arg.depth) 3737 if (arg.nsols == arg.maxsols || bound + arg.nmoves > arg.depth)
3706 return 0; 3738 return 0;
@@ -3714,36 +3746,43 @@ solve_generic_dfs(dfs_arg_t arg)
3714 return 1; 3746 return 1;
3715 } 3747 }
3716 3748
3717 /* TODO: loop over moves and recur */ 3749 memcpy(&nextarg, &arg, sizeof(dfs_arg_t));
3718 return 0; 3750 nextarg.nmoves = arg.nmoves + 1;
3751 for (m = 0, ret = 0; m < 18; m++) {
3752 if (allowednextmove(arg, m)) {
3753 nextarg.cube = move(arg.cube, m);
3754 nextarg.moves[arg.nmoves] = m;
3755 ret += solve_generic_dfs(nextarg);
3756 }
3757 }
3758
3759 return ret;
3719} 3760}
3720 3761
3721int 3762int
3722solve_generic( 3763solve_generic(
3723 cube_t cube, 3764 cube_t cube,
3724 int (*estimate)(cube_t),
3725 uint8_t depth, 3765 uint8_t depth,
3726 int maxsols, 3766 int maxsols,
3727 move_t *sols 3767 move_t *sols
3768 int (*estimate)(cube_t),
3728) 3769)
3729{ 3770{
3730 dfs_arg_t arg; 3771 dfs_arg_t arg;
3731 3772
3732 if (!issolvable(cube) || depth > 20) 3773 if (!issolvable(cube) || depth > 20 || estimate == NULL)
3733 return -1; 3774 return -1;
3734 3775
3735 arg = (dfs_arg_t) { 3776 arg = (dfs_arg_t) {
3736 .cube = cube, 3777 .cube = cube,
3737 .estimate = estimate,
3738 .depth = depth, 3778 .depth = depth,
3739 .maxsols = maxsols, 3779 .maxsols = maxsols,
3740 .sols = sols, 3780 .sols = sols,
3741 .nsols = 0, 3781 .nsols = 0,
3742 .nmoves = 0, 3782 .nmoves = 0,
3743 .moves = {0} 3783 .moves = {0}
3784 .estimate = estimate,
3744 }; 3785 };
3745 3786
3746 return solve_generic_dfs(arg); 3787 return solve_generic_dfs(arg);
3747
3748 return 0;
3749} 3788}
diff --git a/cube.h b/cube.h
index 3f9b509..889569f 100644
--- a/cube.h
+++ b/cube.h
@@ -169,9 +169,44 @@ int16_t coord_eo(cube_t); /* Edge orientation */
169/****************************************************************************** 169/******************************************************************************
170Solvers 170Solvers
171 171
172Solvers return -1 in case of error, the number of solutions otherwise 172All solvers work at fixed depth, i.e. they will only find solutions of the
173specified length. Iterating over the possible lengths, if desired, is left as
174an implementation detail for the user of this library.
173 175
174TODO 176The solutions are returned as a list of moves, which can then be converted to
177a string using writemoves().
178
179Unless specified otherwise, all the solutions are not trivially simplifiable.
180This means that sequences like U U2 or R L R will not appear in any solution.
181Moreover, two consecutive parallel moves are always going to be sorted in
182increasing order. For example, L R2 may never appear in a solution, but R2 L
183could.
184
185Solvers return -1 in case of error, the number of solutions found otherwise.
186
187TODO NISS / INVERSE / LINEAR as a mask?
188
189All solvers take at least the following parameters, satisfying the conditions
190in square brackets:
191 - cube_t cube [issolvable(cube)]: The cube to solve.
192 - uint8_t depth [depth <= 20]: The lenght of the solution.
193 - int maxsols: The maximum number of solutions to find. The solver
194 stops when the limit is reached. If set to a negative number, all
195 the solutions are found.
196 - move_t *ret: The array where the moves of the solutions are stored.
197 There is no separator between different solutions; to read the
198 solutions, use the fact that all solutions has the same length: the
199 i-th move of the j-th solution is ret[j*depth + i].
200
201Some solvers take other parameters. See below for details.
175******************************************************************************/ 202******************************************************************************/
176 203
177int solve_generic(cube_t, int (*)(cube_t), uint8_t, int, move_t *); 204int solve_generic(
205 cube_t cube,
206 uint8_t depth,
207 int maxsols,
208 move_t *ret
209 int (*estimate)(cube_t),
210);
211
212int solve_light(cube_t, int

Generated with cgit - Back to sebastiano.tronto.net