Odilf / barbarosa

A rubik's cube library
GNU General Public License v3.0
1 stars 0 forks source link

Wide moves #13

Closed Odilf closed 1 year ago

Odilf commented 1 year ago

Wide moves are surprisingly not straightforward. What needs to get decided is:

Questions

To generic or not to generic

You could have WideAxisMove or WideAxisMove<N> where N is... something. Making it generic might seem a bit cumbersome but it is necessary to make the number of moves finite. Like, if I want to generate a random 4x4 alg I should be able to do Alg::<WideAxisMove<1>>::random() (or Alg::<Cube4::Move>::random()). Having a non-generic wide move type would imply that moves could be fallible, and I don't think I should make a big effort to have fallible moves.

If generic...

So, assuming we have a WideAxisMove<N>, what does the N represent? Basically there are two options. It either is the depth of the move or the max depth of the move. At a type level, it's easier to have it represent the exact depth since that would mean that every instance of WideAxisMove is disjoint from each other. Namely, this would make it nice because AxisMove would just be WideAxisMove<0> and would have no intereference.

However, it would be way less ergonomic because cubes bigger than 3x3 would not have a single primary concrete move type. For example, a 4x4 would be moved by WideAxisMove<1> and AxisMove. This makes it almost as bad as the non-generic WideAxisMove in that regard.

The problem with having N be the max depth is that each N is a superset of any smaller N. Then, it makes sense that any subset should be auto implemented if the superset is. However, this would have two different auto implementations for AxisMove (which is WideAxisMove<0>).

Oh shit I just realized that this way it seems you have an infinite number of ways to represent the same move.

Storage

Should we have an AxisMove and a WideAxisMove that has an axis_move and a depth field or should we have all the fields in WideAxisMove and have AxisMove be a type alias to WideAxisMove<0>? I'm leaning towards the second one. However, it is storing extra data because depth would always be 0.

Also I'm realizing that depth should be private because invalid states are representable but you shouldn't be able to construct them from outside the crate.

As requirements

Okay I'm more confused after writing all this so let me write this as a list of requirements. I want:

idk

Misc

Also as an idea you could have generic WingSet<N> and CenterSet<P, N> that are generic in depth which would make implementations for big cubes nicer and would decrease coupling.

Odilf commented 1 year ago

Random idea, maybe consider making a trait? I'm thinking it could be useful for the distinction between exactly N wide and at least N wide but it doesn't quite work yet

Odilf commented 1 year ago

It the end I just made it generic over max depth