Computer science at TUDelft.
odilf / barbarosa Goto Github PK
View Code? Open in Web Editor NEWA rubik's cube library
License: GNU General Public License v3.0
A rubik's cube library
License: GNU General Public License v3.0
Computer science at TUDelft.
To make it more convenient to start doing stuff without importing a thousand traits
Buncha stuff. General roadmap:
Renderable
that gives collection of points and colors directly to be renderedAlso dependant on #1
Wings are the "edges" in 4x4 and the last missing piece to implement any NxNxN cube
Edge is all over the place. Right now, IDAsolve
has a safe
keyword argument which disables checking if the cube is solved.
Doing R after R is redundant. Just do R2. The thing is that it's not super straightforward how to do that.
Related to #11
What I want eventually is:
Fancier moves that can be applied to an orientable cube, such as slice moves, rotations, arbitrarily wide wide moves, and i think that's it
It seems that mus-cache
gets generated at the root but the tests try to read it from /barbarosa
. Investigate what's up with that
Sounds fun and also it would be nice to be able to solve an arbitrary 3x3 (but not even close to optimally).
To do this I need to detect the various phases of CFOP and also it would be just a solver, not a searcher; so I should create a Solver
trait and make Searcher
a subtrait of Solver
New type that wraps an NxN cube and keeps track of orientation. This allows fancier moves like slice moves and moves wider than N/2.
I think that's something almost necessary, but I don't know how it works. Basically, search from both the start and the end
Hi!
Thanks for this crate, looks quite promising. :-)
If I want to solve a cube where I know the previous moves from the solved solution, I can do something like:
use barbarosa::cube3::heuristics::mus;
fn main() {
let cube = Cube3::solved();
let mov = AxisMove::parse("F").unwrap();
let moved = cube.clone().moved(&mov.clone().into());
let heuristic = mus;
let solution = moved.solve_with_heuristic(&heuristic);
}
This works, but in case I just have the state of a real world cube, then I have a state, not a list of moves. Is it possible to use your solver to figure out such a state? If not, then this issue would be a feature request for that. :-)
Thanks again.
Dependant on #1 (corner orientation)
Currently I'm just using an off the shelf A* implementation. It'd be better to use iterative deepening and use my own implementation to be able to reduce redundant moves, which is only possible if the previous move is know
To do this we need a good way of avoiding repeated states
I want to try out glam
and from what I've heard it seems more in line with what I'm doing
I think it can actually be done with declarative macros, not procedural ones. Not necessary, but seems fun and it's useful to learn more about Rust macros
Wide moves are surprisingly not straightforward. What needs to get decided is:
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.
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.
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.
Okay I'm more confused after writing all this so let me write this as a list of requirements. I want:
Cube4::Move
, Cube5::Move
)idk
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.
Alg<Cube>
should be the same as Alg<Cube::Move>
. This would basically replace the current Cube::Alg
. I don't think it's possible to do that in rust but hey might as well try.
Actually it would be possible I think, just kind of cumbersome. Instead of having Alg<M: Move>
you would need Alg<M: IntoMove>
or something and IntoMove
has one associated type which is Move
and is implemented for every move and every cube. idk
kinda hard
Right now I'm using the axes that feel the most "mathematically natural", but it's confusing to have to be aware of changing certain things when looking at online info made by the cubing community at large
Be able to somehow use quarter turn metric in addition to half turn metric in NxN cubes.
Should consider creating a "metric" concept for moves, but I think it's easier to just create a QuarterAxisMove
and implement movable by quarter moves for any type that implements half moves.
A reduction solver for 4x4 and up. Reduces the cube to 3x3 and then takes any arbitrary 3x3 solver to finish it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.