I made a cubing timer on Scratch... it's kinda good now (v2 update)

TheSpeedSkewber

Premium Member
Joined
Oct 26, 2022
Messages
1,468
Location
Tesco, buying a meal deal
WCA ID
2023HOWA02
SS Competition Results
YouTube
Visit Channel

Basically, hold for inspection. While in inspection HOLD UNTIL THE NUNBERS STOP COUNTING DOWN! It will break otherwise. Then short hold again to stop the timer

I am not familiar with scratch, so if anyone wants to remix it then feel free.

Also the scramble function is very minimalistic and broken.
 
Screenshot 2023-08-17 at 07.38.51.png
 
Last edited:
It’s been so so long since I’ve used scratch, so forgive me if I forgot a limitation of it.

To improve the scrambler (assuming it’s random move) you need to make sure you can’t get the same face twice in a row. You also need to make sure you can’t get the same face as two moves ago if the last move was on a parallel face. For example: L F L’ is fine, but L R L’ is not.

I’d also recommend making the scramble 25-30 moves to make the distribution of states much more even (although it won’t be perfectly equiprobable without random state).

Cool project!
 

Basically, hold for inspection. While in inspection HOLD UNTIL THE NUNBERS STOP COUNTING DOWN! It will break otherwise. Then short hold again to stop the timer

I am not familiar with scratch, so if anyone wants to remix it then feel free.

Also the scramble function is very minimalistic and broken.
Bro says he's not very familiar with scratch.
5+ projects on his account.
 
I can't help you with Scratch because my programming never progressed beyond QuickBASIC 4.5 (a structured version that allows you to avoid line numbers and spaghetti code). I have written my own scramble generator, though, so I can discuss methodology, I just can’t give examples in contemporary code. I also give more attention than probably necessary to minimizing runtime, but I started with a $100 Timex/Sinclair, and old habits die hard (you could speed that thing up by moving the most frequently called routines closer to the beginning of the program).

To generate a random scramble without cancellations, you need to avoid turning a face twice in a row and after turning the parallel face, so no UU or UDU. I will use t2 for the current turn (the one you are generating now), t1 for the previous one, and t0 for the one before that.

An easy but inefficient method would be to re-randomize if t2 = t1 for the first case, or if Parallel(t0,t1) AND Parallel(t1,t2) for the second, where Parallel is True if the two turns are parallel. However, generating a pseudorandom number is slower than a few conditionals and integer operators, so let’s only do it once per turn. This means you need to determine the number of allowable faces for each turn (:= n). This is 6 for the first turn and 5 for all subsequent turns unless the previous two turns were parallel, in which case it’s 4. You just need to generate a random number from 1 to n (or 0 to n-1 if you swing that way), then skip over the previous turn or axis (I’m assuming the face assignments group parallel faces together, for example U D F B R L). You could use conditionals:

r:= your randomly generated number; n, t0, t1, t2 as before. Axis(x):= (x+1)\2 (or x\2 if you index from 0) where \ denotes integer division.

Code:
IF n = 6 THEN t2 = r
IF n = 5 THEN IF r >= t1 then t2 = r + 1
IF n = 4 THEN IF Axis(r) >= Axis(t1) THEN t2 = r + 2

Example: t1=3 (F in my assignment above). If n=5, an r of 1 or 2 is unchanged, while 3-5 --> 4-6, so the possible outcomes are U D B R L. If n=4, Axis(t1)=2 and r=1,2 is again unchanged, and 3,4 --> 5,6, so the outcomes are U D R L.

QuickBASIC allows Boolean operations (False:=0, True:=-1) and has a CASE statement that allows you to specify code for different values of a variable without repetitive conditionals, so my version looks like this (the order of the CASEs is because it drops out of the SELECT block after a True case, do this minimizes the number of CASEs evaluated):

Code:
SELECT CASE n
  CASE 5: t2 = r - (r >= t1)
  CASE 4: t2 = r - 2 * (Axis(r) >= Axis(t1))
  CASE 6: t2 = r
END SELECT

That’s all you need for odd cubes. Even cubes have one more restriction – you can’t make two parallel turns if both are the maximum width. For example, on a 4x4, ud (or UwDw) has the same effect as u2/Uw2 and ud’/UwDw’ would just be y. On a 6x6, only three-wide turns would be restricted. You need a conditional like IF (c MOD 2 = 0) AND (n = 5) THEN IF Tmax(t1) = Tmax(t2) THEN n = 4 where c:= size of the cube, MOD is the remainder of integer division and Tmax(x):= (width(x)=c\2).

Note: On a 2x2, the above would reduce to n=6 for the first turn and n=4 for all others, if you generate 6-face scrambles for 2x2. They are usually scrambled using only UFR, so you would use n=3/n=2, and wouldn’t need to worry about parallel axes.
 
I can't help you with Scratch because my programming never progressed beyond QuickBASIC 4.5 (a structured version that allows you to avoid line numbers and spaghetti code). I have written my own scramble generator, though, so I can discuss methodology, I just can’t give examples in contemporary code. I also give more attention than probably necessary to minimizing runtime, but I started with a $100 Timex/Sinclair, and old habits die hard (you could speed that thing up by moving the most frequently called routines closer to the beginning of the program).

To generate a random scramble without cancellations, you need to avoid turning a face twice in a row and after turning the parallel face, so no UU or UDU. I will use t2 for the current turn (the one you are generating now), t1 for the previous one, and t0 for the one before that.

An easy but inefficient method would be to re-randomize if t2 = t1 for the first case, or if Parallel(t0,t1) AND Parallel(t1,t2) for the second, where Parallel is True if the two turns are parallel. However, generating a pseudorandom number is slower than a few conditionals and integer operators, so let’s only do it once per turn. This means you need to determine the number of allowable faces for each turn :)= n). This is 6 for the first turn and 5 for all subsequent turns unless the previous two turns were parallel, in which case it’s 4. You just need to generate a random number from 1 to n (or 0 to n-1 if you swing that way), then skip over the previous turn or axis (I’m assuming the face assignments group parallel faces together, for example U D F B R L). You could use conditionals:

r:= your randomly generated number; n, t0, t1, t2 as before. Axis(x):= (x+1)\2 (or x\2 if you index from 0) where \ denotes integer division.

Code:
IF n = 6 THEN t2 = r
IF n = 5 THEN IF r >= t1 then t2 = r + 1
IF n = 4 THEN IF Axis(r) >= Axis(t1) THEN t2 = r + 2

Example: t1=3 (F in my assignment above). If n=5, an r of 1 or 2 is unchanged, while 3-5 --> 4-6, so the possible outcomes are U D B R L. If n=4, Axis(t1)=2 and r=1,2 is again unchanged, and 3,4 --> 5,6, so the outcomes are U D R L.

QuickBASIC allows Boolean operations (False:=0, True:=-1) and has a CASE statement that allows you to specify code for different values of a variable without repetitive conditionals, so my version looks like this (the order of the CASEs is because it drops out of the SELECT block after a True case, do this minimizes the number of CASEs evaluated):

Code:
SELECT CASE n
  CASE 5: t2 = r - (r >= t1)
  CASE 4: t2 = r - 2 * (Axis(r) >= Axis(t1))
  CASE 6: t2 = r
END SELECT

That’s all you need for odd cubes. Even cubes have one more restriction – you can’t make two parallel turns if both are the maximum width. For example, on a 4x4, ud (or UwDw) has the same effect as u2/Uw2 and ud’/UwDw’ would just be y. On a 6x6, only three-wide turns would be restricted. You need a conditional like IF (c MOD 2 = 0) AND (n = 5) THEN IF Tmax(t1) = Tmax(t2) THEN n = 4 where c:= size of the cube, MOD is the remainder of integer division and Tmax(x):= (width(x)=c\2).

Note: On a 2x2, the above would reduce to n=6 for the first turn and n=4 for all others, if you generate 6-face scrambles for 2x2. They are usually scrambled using only UFR, so you would use n=3/n=2, and wouldn’t need to worry about parallel axes.
I mean cool. But haven’t you put in a little too much effort into a post trying to improve a scratch timer that deletes your solves everytime you run it (adding cloud variables would just be a waste, but if the owner wants that I don’t mind helping)
 
I can't help you with Scratch because my programming never progressed beyond QuickBASIC 4.5 (a structured version that allows you to avoid line numbers and spaghetti code). I have written my own scramble generator, though, so I can discuss methodology, I just can’t give examples in contemporary code. I also give more attention than probably necessary to minimizing runtime, but I started with a $100 Timex/Sinclair, and old habits die hard (you could speed that thing up by moving the most frequently called routines closer to the beginning of the program).

To generate a random scramble without cancellations, you need to avoid turning a face twice in a row and after turning the parallel face, so no UU or UDU. I will use t2 for the current turn (the one you are generating now), t1 for the previous one, and t0 for the one before that.

An easy but inefficient method would be to re-randomize if t2 = t1 for the first case, or if Parallel(t0,t1) AND Parallel(t1,t2) for the second, where Parallel is True if the two turns are parallel. However, generating a pseudorandom number is slower than a few conditionals and integer operators, so let’s only do it once per turn. This means you need to determine the number of allowable faces for each turn :)= n). This is 6 for the first turn and 5 for all subsequent turns unless the previous two turns were parallel, in which case it’s 4. You just need to generate a random number from 1 to n (or 0 to n-1 if you swing that way), then skip over the previous turn or axis (I’m assuming the face assignments group parallel faces together, for example U D F B R L). You could use conditionals:

r:= your randomly generated number; n, t0, t1, t2 as before. Axis(x):= (x+1)\2 (or x\2 if you index from 0) where \ denotes integer division.

Code:
IF n = 6 THEN t2 = r
IF n = 5 THEN IF r >= t1 then t2 = r + 1
IF n = 4 THEN IF Axis(r) >= Axis(t1) THEN t2 = r + 2

Example: t1=3 (F in my assignment above). If n=5, an r of 1 or 2 is unchanged, while 3-5 --> 4-6, so the possible outcomes are U D B R L. If n=4, Axis(t1)=2 and r=1,2 is again unchanged, and 3,4 --> 5,6, so the outcomes are U D R L.

QuickBASIC allows Boolean operations (False:=0, True:=-1) and has a CASE statement that allows you to specify code for different values of a variable without repetitive conditionals, so my version looks like this (the order of the CASEs is because it drops out of the SELECT block after a True case, do this minimizes the number of CASEs evaluated):

Code:
SELECT CASE n
  CASE 5: t2 = r - (r >= t1)
  CASE 4: t2 = r - 2 * (Axis(r) >= Axis(t1))
  CASE 6: t2 = r
END SELECT

That’s all you need for odd cubes. Even cubes have one more restriction – you can’t make two parallel turns if both are the maximum width. For example, on a 4x4, ud (or UwDw) has the same effect as u2/Uw2 and ud’/UwDw’ would just be y. On a 6x6, only three-wide turns would be restricted. You need a conditional like IF (c MOD 2 = 0) AND (n = 5) THEN IF Tmax(t1) = Tmax(t2) THEN n = 4 where c:= size of the cube, MOD is the remainder of integer division and Tmax(x):= (width(x)=c\2).

Note: On a 2x2, the above would reduce to n=6 for the first turn and n=4 for all others, if you generate 6-face scrambles for 2x2. They are usually scrambled using only UFR, so you would use n=3/n=2, and wouldn’t need to worry about parallel axes.
Thank you! I will try implement all your suggestions.
 
To be honest, I used to have a Scratch account before being a speedcuber, but as a Block/Python Coder myself, I think ik how to solve the scrambler problem.

You see, most scrambles are randomly generated, as you all know. This means that there might be two lists, one for the scramble, which will be deleted after each solve, and one for the notation. The notation list will have every single move, like R2, D2, F' etc. Once that has been made, you can make a loop that goes on 30 times, with the notation list being extracted for the scramble. I don't know if it's possible to do it in Scratch, but it is possible in Python, as I made it work there.
 
To be honest, I used to have a Scratch account before being a speedcuber, but as a Block/Python Coder myself, I think ik how to solve the scrambler problem.

You see, most scrambles are randomly generated, as you all know. This means that there might be two lists, one for the scramble, which will be deleted after each solve, and one for the notation. The notation list will have every single move, like R2, D2, F' etc. Once that has been made, you can make a loop that goes on 30 times, with the notation list being extracted for the scramble. I don't know if it's possible to do it in Scratch, but it is possible in Python, as I made it work there.
Yes, my problem was that i used a list with all the notation, and i used a variable that chose one of them as long as it wasnt the same as the last one, except i detected it incorrectly. When i have the time I will improve it
 
Scramble function works perfectly now 💪 thanks guys!
View attachment 25951
Ok so i made literally everything better. 2x2 scramble function, scramble is fixed, next scramble option, inspection no longer breaks, next step is to add codes to save your times and also add sessions.
 
Last edited:
Back
Top