0

I am currently working on a web-timer, and I have some issues with my scrambling-algorithm algorithm. As it is the first version, I only want the scrambler to be random move and not random state, as it is too much complicated to make, and it will come in a future update. I have an algorithm that basically makes an array of random moves that it chooses from the possibilities, and then checks if two of the same letters (or moves) are not next to one another. That all works fine, But I have no clue how to add something that would avoid cases as follow: "D U D" for example. Two same moves separated by another move are acceptable For example "D R D", but not "D U D", as it would be equal to "D2 U", and thus, be a wasted move.

Information fro non-cubers:

each letter represents its face that gets moved when the letter is read. For example: "L U L": "L" would mean to rotate the left face clockwise once, then "U" would mean to rotate the Upper face clockwise, and finally "L" again would mean to rotate the left face again. if a letter is followed by an apostrophe, then it means that the face should be rotated counter-clockwise. If it is followed by a "2", it means that the face should be rotated two times in a row. L is left, R is right, F is front, B is back, D is down, U is Up

Here's the code:

  function generate_scramble() {
   var scramble_length = 20;
   var scramble = new Array();

   var possible_letters = new Array(" D", " U", " B", " F", " R", " L");
   var possible_switches = new Array("", "2", "'");

   var array_of_randoms = new Array();

   for (var i = 0; i < scramble_length; i++) {
    var random_letters = Math.floor(Math.random() * possible_letters.length);
    var random_switches = Math.floor(Math.random() * possible_switches.length);

    array_of_randoms.push(random_letters);

    if (array_of_randoms[array_of_randoms.length - 1] == array_of_randoms[array_of_randoms.length - 2]) {
     if (array_of_randoms[array_of_randoms.length - 1]  < 5) {
      array_of_randoms[array_of_randoms.length - 1]++;
     } else { 
      array_of_randoms[array_of_randoms.length - 1]--;
     }
    }
   random_letters = array_of_randoms[array_of_randoms.length - 1];
   scramble.push(possible_letters[random_letters] + possible_switches[random_switches])
   }
   document.getElementById("scramble").innerHTML = "Scramble: " + scramble.join("");
  }

  generate_scramble();
 <p id="scramble">
  Scramble: 
 </p>
 <button onclick="generate_scramble()">
  New Scramble
 </button>
Jakub Chaloupka
  • 177
  • 1
  • 3
  • 12
  • Could you list more false cases? Its hard to get when to fail – Jonas Wilms Dec 09 '17 at 21:14
  • Cases that should be avoided: D U D, U D U, L R L, R L R, F B F, B F B – Jakub Chaloupka Dec 09 '17 at 21:15
  • I wrote it without the apostrophes and without the twos. But they can be there basically wherever, it wouldn't change a thing – Jakub Chaloupka Dec 09 '17 at 21:16
  • So B F B2 or B F2 B would be okay, but B2 F B2 not? – Jonas Wilms Dec 09 '17 at 21:18
  • well, none of them would be ok. It is true that B2 F B2 would completely cancel the B moves, so it would be the worst, but for example B F B2 would be equal to B' F, or B F2 B would be equal to B2 F2, so it would waste a move. What I mean by "Waste a move" is that a scamble algorithm is usually just 20 moves long, if I do something with 3 moves but it can be done with 2, it would just waste a slot, a space or so, in these 20 moves – Jakub Chaloupka Dec 09 '17 at 21:22

1 Answers1

1
 const directions = [
   ["D", "U"],
   ["L","R"],
   ["F","B"]
 ];

 const times = ["", "'", "2"];

 const random = (array, exclude) => {
   do {
      var n = Math.floor( Math.random() * array.length );
   } while(array[n] === exclude)
   return array[n];
}

const scramble = new Array(20);
var direction;
for(var i = 0; i < scramble.length; i++){
  direction = random(directions, direction);
  scramble[i] = random(direction) + random(times);
 }

You could reduce many false moves by always changing the direction it moves. So D U D wouldnt appear cause D and U go into the same direction.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151