# QWERTYcube - A keyboard operated and JavaScript based open source Rubik's Cube



## StevenElliott (Jul 3, 2015)

I've created a small web based Rubik's Cube that I've named QWERTYcube. As you might expect from the name the emphasis is on controlling it via the keyboard. A few highlights:

HTML5 And JavaScript - QWERTYcube should work in modern browsers without having to install anything.
Scrambler - By default the J key applies 30 random moves.
Timer With Inspection Period - Similar to actual contests scrambling the cube begins a 15 second (configurable) countdown, shown by the timer in red. During this time you may rotate the entire cube to inspect it, but making at actual move ends the inspection period causing the timer to turn green and start counting up. The moment the cube is solved the timer turns yellow and stops, giving you the solve time. Press T to toggle the timer.
No Advertisements Or Distractions - Just you and the cube with a minimalist interface.

Check out QWERTYcube's home page, which links to a live version of it, at:
http://selliott.org/puzzles/qwertycube

I've also created a GitHub page for it:
https://github.com/selliott512/qwertycube

I'd like to thank Siddhante Nangla for writing rubik_scrambler, which QWERTYcube is based on. You can find rubik_scrambler here:
https://github.com/XanderWraik/rubik_scrambler


----------



## samuelqwe (Jul 4, 2015)

Seem cool, i'll check it out!


----------



## Lucas Garron (Jul 4, 2015)

Requests:

- Please don't use a bad scrambler. There is random-state scrambling code available.
- Support Heise sim keys. They take longer to learn, but they're much faster once you get used to them, and several simulators already use them.


----------



## josh42732 (Jul 4, 2015)

Dang solving on any other color than white is freaking hard


----------



## YTCuber (Jul 4, 2015)

josh42732 said:


> Dang solving on any other color than white is freaking hard



i had a yellow 2-move-cross and couldn't turn the cube


----------



## StevenElliott (Jul 4, 2015)

Lucas Garron said:


> Requests:
> 
> - Please don't use a bad scrambler. There is random-state scrambling code available.
> - Support Heise sim keys. They take longer to learn, but they're much faster once you get used to them, and several simulators already use them.



Thanks for the feedback.

Regarding the scrambler - by default it picks 30 random moves using JavaScript's Math.random(). It has the typical check where it won't do multiple twists along the same axis (R L R, for example). The original scramble code would reject any move that produced the same cube that occurred earlier in the scramble (see dupCubeCheck in the code), but I found that that almost never helped, so it's disabled. Is there something that jumped out at you as being incorrect that I should work on?

I was thinking of making the key bindings configurable. Maybe Heise sim keys for the next version. Good suggestion.



YTCuber said:


> i had a yellow 2-move-cross and couldn't turn the cube



In some browsers the Alt key combined with a movement key will cause the browser to do something that then causes QWERTYcube to loose focus. For example, Alt-F in Chrome on Linux brings up a menu. In that case you should be able to click on the cube with the mouse to give it focus again. An alternative to Alt is pressing Esc prior to the movement key. You only have to do it for movement keys where you have this conflict.

If you're saying QWERTYcube hung for some other reason then maybe try another browser. If you can bring up the JavaScript console in the browser where it's not working and report any errors that would be helpful.


----------



## YTCuber (Jul 4, 2015)

StevenElliott said:


> In some browsers the Alt key combined with a movement key will cause the browser to do something that then causes QWERTYcube to loose focus. For example, Alt-F in Chrome on Linux brings up a menu. In that case you should be able to click on the cube with the mouse to give it focus again. An alternative to Alt is pressing Esc prior to the movement key. You only have to do it for movement keys where you have this conflict.



This helped


----------



## Lucas Garron (Jul 5, 2015)

StevenElliott said:


> Regarding the scrambler - by default it picks 30 random moves using JavaScript's Math.random(). It has the typical check where it won't do multiple twists along the same axis (R L R, for example). The original scramble code would reject any move that produced the same cube that occurred earlier in the scramble (see dupCubeCheck in the code), but I found that that almost never helped, so it's disabled. Is there something that jumped out at you as being incorrect that I should work on?.



Yes, such scrambles are going to have a significant bias in edge orientation.
If you're going to do random moves, do at least 100. It's easy for computers.

If you want to use something good, use JSSS.


----------



## StevenElliott (Jul 5, 2015)

Lucas Garron said:


> Yes, such scrambles are going to have a significant bias in edge orientation.
> If you're going to do random moves, do at least 100. It's easy for computers.
> 
> If you want to use something good, use JSSS.



I thought about setting the default scramble length higher, but I was concerned that people who actually wanted to look at the list of scramble moves would be annoyed by it being too long.

My idea of an ideal scrambler is one that chooses one of the 4.3×10**19 permutations with equal probability and then provides the minimum number of moves to transform a solved cube into the chosen permutation. Would you agree that my scrambler approaches being perfect with regard to picking a permutation with equal probability as the number of moves approaches infinity? In fact, I think any scrambler, even if the moves it was able to generate was limited (such only choosing clock wise moves), would approach being perfect assuming the random number generator was adequate and as long as every permutation was reachable.

I've been curious at exactly what rate scramblers approach being perfect as a function of the number of scramble moves, but I haven't found any good information. I just know that a lot of places consider 25 to be adequate, so I rounded up to 30 to be on the safe side.

I've looked at the link you provided, but it seems to be over 1,700 lines of complicated and uncommented code. I may use it in some future version, but I'll have to think about it more. Thanks for the suggestion.


----------



## Innocence (Jul 5, 2015)

This is a nice sim in a way, but it has a bias toward a certain orientation (it literally tells the user which side should be "down" or "front" etc. as well as stopping the cube at 0 and 180 degrees on one axis) and has a colour scheme that hurts my face. And my heart.



StevenElliott said:


> I've looked at the link you provided, but it seems to be over 1,700 lines of complicated and uncommented code. I may use it in some future version, but I'll have to think about it more. Thanks for the suggestion.



I wouldn't call it undocumented. If you look at the github home page and also this file:

https://github.com/cubing/jsss/blob/master/example.htm

It's pretty straight forward to simply generate a random state scramble.

("Random state" being exactly what you said: The state is generated and THEN the moves to reach such a solution are found. Any other way of reaching a random state, such as performing random moves, *is* inadequate, no matter how you look at it)


----------



## molarmanful (Jul 5, 2015)

*USE RANDOM STATE SCRAMBLERS!!! It's in style right now.*

Anyway, nice sim. I'd recommend mobile support (dragging), more customization to color scheme (and other UI stuff), and saving the settings using cookies or (even better) localStorage.

If you want me to help you with the sim, just PM me or something.


----------



## StevenElliott (Jul 5, 2015)

Innocence said:


> This is a nice sim in a way, but it has a bias toward a certain orientation (it literally tells the user which side should be "down" or "front" etc. as well as stopping the cube at 0 and 180 degrees on one axis) and has a colour scheme that hurts my face. And my heart.
> 
> 
> 
> ...



I don't quite understand the objection about telling the user which side is which. It's possible to drag the cube with the mouse in order to change it's orientation.

The colors are a bit intense in a way that demands explanation - I chose each 0xRRGGBB color so that each of the three bytes was either 0xFF or 0x00 so that the contrast would be as high as possible. It's possible to produce each of the six cube colors other than orange this way. For orange I substituted 0xFF00FF which is fuchsia as that was one of the remaining possibilities. But maybe I can revisit it. Maybe I can just use the colors of existing cube programs.

Thanks for that example file. I was more referring to understanding how the code works, but the example is helpful in any case.


----------



## Lucas Garron (Jul 5, 2015)

StevenElliott said:


> My idea of an ideal scrambler is one that chooses one of the 4.3×10**19 permutations with equal probability and then provides the minimum number of moves to transform a solved cube into the chosen permutation.



This is a good goal. Our (uniform) random-state scramblers achieve it. 

(Well, they don't use the minimum number moves. But rather than spending a while finding an optimal scramble <=20-moves, they usually spend a few milliseconds finding solutions with 20 to 23 moves.)



StevenElliott said:


> Would you agree that my scrambler approaches being perfect with regard to picking a permutation with equal probability as the number of moves approaches infinity?



Yes. It's very convenient that for the Rubik's Cube and many similar puzzles "do lots of random turns" ends up giving every state equal weight.
However, you can't assume that "good when we go to infinity" means "it's okay if we do a (small) finite number of turns".



StevenElliott said:


> In fact, I think any scrambler, even if the moves it was able to generate was limited (such only choosing clock wise moves), would approach being perfect assuming the random number generator was adequate and as long as every permutation was reachable.


You have to be careful about which set of moves you choose. For example, if you only chose quarter turns, then the parity changes every turn, and half the states are unreachable after a given number of steps. (You can define the distribution as the "average" of distributions as you go to infinity to be careful.)



StevenElliott said:


> I've been curious at exactly what rate scramblers approach being perfect as a function of the number of scramble moves, but I haven't found any good information. I just know that a lot of places consider 25 to be adequate, so I rounded up to 30 to be on the safe side.



Ah, so here's the issue. 25 is not adequate. It was never adequate, but it's what official scrambles used to use. We didn't have an easy way to use random-state scrambles at the time, and needed the scrambles to be reasonably short so that we could run practical competitions.

The number 25 was never revised, because the correct solution was to switch to random-state instead.

If you look at Stefan's calculations, you'll see that the distribution of edge orientations is still atrociously skewed at 25 or 30 moves. At 30 moves, the chance of getting all oriented edges is 1/1400 rather than 1/2048. This may not seem like a lot, but many cubers do thousands of solves a year. If they are using a method that gets faster when all edges are oriented (e.g. ZZ, or certain BLD methods), they're getting quite a few more solves per year with a skip than they should. There's probably a decent increased chance that one of theses solves will be their PB.

It doesn't even get decent until 50 moves, but there is still a small but significant disparity with 50 moves. And this is just for edge orientation. I you look at other mathematical properties (distributions of cosets, which may also *roughly* correspond to the easiness of a scramble), you have to do *many* more moves for the distribution to settle down. Tom Rokicki knows more about this than I do, though.



StevenElliott said:


> I've looked at the link you provided, but it seems to be over 1,700 lines of complicated and uncommented code. I may use it in some future version, but I'll have to think about it more. Thanks for the suggestion.



The code may be complicated internally, but it should be easy to use:



> scramblers["333"].getRandomScramble().scramble_string





molarmanful said:


> *USE RANDOM STATE SCRAMBLERS!!! It's in style right now.*



Using random state scrambles is the right way to go, but you shouldn't do something just because it's in style.
Rather, it's a better idea because:

- It's much better than random turns. As I described above, there are tangible problems with random turns – and that's just looking at a single measure.
- There are simple-to-use tools available, so it doesn't take much effort to get the benefits.
- The solutions are close to optimal, so you actually *save* moves for 3x3x3. Even compared to 25 or 30 moves.


----------



## qqwref (Jul 5, 2015)

StevenElliott said:


> My idea of an ideal scrambler is one that chooses one of the 4.3×10**19 permutations with equal probability and then provides the minimum number of moves to transform a solved cube into the chosen permutation.


You are talking about random state scramblers. Since you are far from the first programmer to be interested in cubing, this has of course already been done, and in fact has been in use for years, both for official competition scramblers and for unofficial scrambling/timing programs. Many simulators already use this, and others use very large numbers of moves to provide scrambles that are just as good. Of course, to save computing time, random-state scrmablers usually use slightly sub-optimal solutions, but it only adds a few turns.



StevenElliott said:


> Would you agree that my scrambler approaches being perfect with regard to picking a permutation with equal probability as the number of moves approaches infinity?


Didn't you just say you don't want your number of moves to approach infinity? 25 or 30 moves is simply not good enough. The entire cubing community has been using better scramblers for many years now.


For what it's worth, I'm really not a fan of either the turning controls or the mouse rotations, but it doesn't really matter since this isn't designed for speedsolves anyway. I'm sure casual cubers will do just fine once they figure out the key setup.


----------



## molarmanful (Jul 6, 2015)

Lucas Garron said:


> Using random state scrambles is the right way to go, but you shouldn't do something just because it's in style.


Yeah, I was joking about that.


----------



## Innocence (Jul 6, 2015)

StevenElliott said:


> I don't quite understand the objection about telling the user which side is which. It's possible to drag the cube with the mouse in order to change it's orientation.



Yes, but try solving with say red on the bottom. If you try to rotate the cube so that you can see the orange more easily with yellow in front, the rotation of the cube stops once the yellow face is at 90 degrees. Additionally, dragging to the left will, instead of doing a Y rotation, do a Z rotation. 

This is, I believe, because certain dragging actions are programmed to rotate along a certain axis, which is not ideal when you're trying to solve the cube in more than 1 orientation (white bottom, yellow top).


----------



## StevenElliott (Jul 6, 2015)

I appreciate all the feedback, everyone. Here's my impression of the top concerns, at least in terms of ones that should be easy to implement:

Use a random state scrambler, such as JSSS.
Use a more standard and less garish color scheme.
Add mouse support for making moves.
Make the mouse support for rotating the entire cube more intuitive.

The first two seem relatively easy, so I'll work on those first, whereas the second two seem more challenging. In any case I'll be busy for a week or two before I'll have a chance to work on any of it.

Some other points that were raised:

Innocence,
I'll look into rotating the cube with the mouse at some point, but for now you probably only want to use the mouse to rotate the cube less than 90 degrees, just to change the perspective a bit, if you want to, and then use the axis keys (X, Y and Z) to rotate to the side you want to work on.

Lucas Garron,
Thanks for the information Stefan's calculations on how cube states (inadequately) become more random as a function of the number of random moves. It was clever of him to focus on edges to make the number of permutations manageable.

Someone kindly offered to work on QWERTYcube. To do that there's always it's github page 
https://github.com/selliott512/qwertycube 
where it's possible to submit bug reports or pull requests (or patches, if you don't feel like messing with that). But please keep in mind that I'd like to:

Keep it light weight with relatively few tool kits, etc.
Continue to support most modern browsers that support WebGL.
Keep it (mostly) MIT licensed


----------



## StachuK1992 (Jul 6, 2015)

Lucas,

Thank you for going into why random state scrambles were important.
Before that (especially the ZZ stuff), I was a nonbeliever.


Another idea is to utilize github pages.

Simply create a branch of name 'gh-pages' with an index.html and voila!

Example:
http://stachuk1992.github.io/zzTimer hosted automagically by https://github.com/stachuk1992/zzTimer/tree/gh-pages

You could simply work directly off of that branch.


----------



## StevenElliott (Jul 29, 2015)

I've released a new version of QWERTYcube (0.9.1). It has a lot of new features and bug fixes. Some highlights:

A random state scrambler (JSSS) is now used by default. Thanks to Lucas Garron for this suggestion.
The colors have been both improved and made more configurable.
There is now full mouse support - you can make moves as well as rotate the cube.
Settings now persist from one page load to the next via HTML 5's local storage. Thanks to molarmanful for this suggestion.
It's possible to specify the initial cube state via a facelets string.
The keys may be remapped. Hopefully this is sufficient to implement Heise sim keys as suggested by Lucas Garron.
Hosted via gh-pages in addition to my website. Thanks to StachuK1992 for this suggestion.

Check out it's updated home page at http://selliott.org/puzzles/qwertycube . I've added a lot of screenshots as well as other information.

Thanks again for all the feedback. I currently don't have plans to do much more with QWERTYcube, but those interested are welcome to submit patches.


----------



## molarmanful (Jul 29, 2015)

Nice! Much better. This is awesome!


----------



## StevenElliott (Nov 14, 2015)

Hello again.

I hope it's ok to post in such an old thread, but I've released version 0.9.2 of QWERTYcube and this seemed like the perfect place. The big new feature is mobile support. Some highlights:

Full Mobile Support - Touch is now supported in the same way the mouse is on desktops. Tested on Nexus 6 and iPhone 6s.
Button Bar - There is now a bar of buttons at the bottom of the screen.
Rotation Lock - Clicking Lock or K prevents the cube from rotating when the grey background is clicked.
Improved Help - The help is now more detailed.
Improved Sizing - Now the maximum sized cube is used that does not exceed the canvas that it's on regardless of the cube orientation or screen dimensions.

Check out it's (slightly) updated home page at http://selliott.org/puzzles/qwertycube . I've added a new screenshot of it on a mobile device.

I've subjected some of my friends to it and part of the feedback I've received is that the algorithm I'm using to convert mouse gestures into cube moves is sometimes difficult and unintuitive, but it works once you get used to it. It helps to keep swipes between and parallel to the black gaps that separate the cubies. I don't know if I want to rework the algorithm, but I'll happily evaluate any pull requests.

I'm looking forward to your feedback.


----------



## AlexMaass (Nov 14, 2015)

Seems good, but there's some issues,

I can't really do z rotations when the top face is yellow or white.

Mouse controls could be improved, sometimes when you try to do a wide turn you do a slice or face move instead.

Might want to add better keyboard controls, http://www.ryanheise.com/cube/speed.html the controls listed there is what a lot of good cube sims use.

Also, it said that you used random moves to scramble it, random state scrambling is much better, you should use that.


----------



## StevenElliott (Nov 15, 2015)

AlexMaass said:


> Seems good, but there's some issues,
> 
> I can't really do z rotations when the top face is yellow or white.



Do you mean rotating the cube about the Z-axis by moving the mouse in the grey background? Yellow is on top by default, and it seems to work for me, but I take your word it that there's an issue. An alternative to moving the moue on the grey background is to use Z or Shift-Z or a mouse gesture that crosses all three layers.



AlexMaass said:


> Mouse controls could be improved, sometimes when you try to do a wide turn you do a slice or face move instead..



Fair enough. It is a bit odd and unintuitive, so I've been told by my friends. As to exactly what it's doing, in case it's helpful - when the mouse is pressed the program determines where on the surface of the cube the mouse was clicked. Moving the mouse and then releasing it produces a vector. That vector is then crossed with each of the three axis to determine which axis would produce the most torque, if the vector was force. Layers are then rotated about that axis. Whichever layers are touched between mouse down and mouse release are rotated.

But I'm open to better ways of doing it.



AlexMaass said:


> Might want to add better keyboard controls, http://www.ryanheise.com/cube/speed.html the controls listed there is what a lot of good cube sims use.



QWERTYcube is flexible enough in that it allows the keys to be remapped, but admittedly it's not possible to fully simulate the cube that you linked to. That cube depends on being able to do certain keystrokes simultaneously. As it's written QWERTYcube places each keystroke in a queue as soon as it's pressed - there's no provision for doing more than one move simultaneously.

Also, I have a lot of keys that do non-move things, so I'd have to figure out how to remap those.



AlexMaass said:


> Also, it said that you used random moves to scramble it, random state scrambling is much better, you should use that.



You may have seen the discussion about that earlier in this thread. Actually, by default it is using a random state scrambler named "jsss" now.


----------



## StevenElliott (Nov 29, 2015)

I've just released version 0.9.3 with various enhancements some of which were inspired by AlexMaass' feedback - Heise key mapping is now just a click of a button away. Also, it's now possible to make moves by single clicking, which may be preferable to click and drag in some cases. Enhancements since 0.9.2:

Heise Key Map - Heise key bindings can now be turned on by clicking a button.
Multi-touch Support - It's possible to do two compatible moves simultaneous with two simultaneous touches.
Single Click Moves - In addition to clicking and dragging it's now possible single click on a sticker to trigger a move.
Improved Help - The help is now more detailed.
Faster Replay - Large numbers of moves are now replayed more quickly.
Color Button - Easily cycle through the color schemes.
Check out it's (slightly) updated home page at http://selliott.org/puzzles/qwertycube . I've updated the screenshot of it on a mobile device.

As always I'm looking forward to your feedback.


----------



## qq280833822 (Nov 30, 2015)

StevenElliott said:


> [*]Heise Key Map - Heise key bindings can now be turned on by clicking a button.



It seems that the Heise Key Map is not fully supported. For example, ";" key should be a "y" rotation. A full key-map table used in csTimer is listed here:


Spoiler



I => R
K => R'
W => B
O => B'
S => D
L => D'
D => L
E => L'
J => U
F => U'
H => F
G => F'
; => y
A => y'
U => r
R => l'
M => r'
V => l
T => x
Y => x
N => x'
B => x'
. => M'
P => z
Q => z'
Z => d
C => u'
, => u
/ => d'


----------



## StevenElliott (Nov 30, 2015)

Silly of me to not try punctuation keys when examining the existing Heise Java applet (see http://www.ryanheise.com/cube/speed.html). I'll work on that and come up with a new version very soon. Thanks for the feedback, qq280833822.


----------



## StevenElliott (Dec 1, 2015)

I've just released version 0.9.4 with the Heise fix mentioned in the previous comments. The Heise key bindings now match those listed in qq280833822's comment. As far as I can tell the Heise keybindings are now a super set of the key bindings in Ryan Heise's Java applet - there are four key bindings listed that are not exhibited by the applet, but that's fine.

Check out it's (slightly) updated home page at http://selliott.org/puzzles/qwertycube .


----------

