Letterscrambler
Last updated: Mar 10, 2020
…For lack of a better title.
This application takes some user input, checks letter validity against a pre-written array of characters (so that the worker doesn’t run forever), then summons a web worker to randomly cycle the letters until the user word/phrase is found. You can control the worker delay using the slider input.
On github.
See the Pen Letter Scrambler by Perry (@defsax) on CodePen.
The user enters their word or phrase into the text box, then presses go. The phrase is passed as a string into an input checking function which returns false if it cannot find the character in the pre-written array. I’d like to eventually generate an array or series of characters dynamically, since this array is essentially limited to letters, numbers and keyboard symbols.
var randChar = [
"a", "b", "c", "d", "e", "f", "g", "h",
"i", "j", "k", "l", "m", "n", "o", "p",
"q", "r", "s", "t", "u", "v", "w", "x",
"y", "z",
"A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P",
"Q", "R", "S", "T", "U", "V", "W", "X",
"Y", "Z",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"!", "@", "#", "$", "%", "^", "&", "*",
"(", ")", "_", "-", "+", "=", ":", ";",
//"<", open bracket will cause html to hide the rest of the line
">", ".", ",", "?", "/", "|", "{", "[", "]", "}",
" ", "\\", "\'", "\"", "å", "ß", "Ø", "Ö", "Õ"
];
However, the advantage of this approach is that the array is relatively short. If I was to encorporate UTF-8 or another standard, the application would attempt to pull a random char from the potential 1.1 million code points.
For each character inputted, I use the js string .indexOf() method to return its location in the array. If .indexOf() cannot find the character in the array, then it returns a -1. If this happens then I save the invalid characater for display and return false.
for(let i = 0; i < inputCharacters.length; i++){
search = randChar.indexOf(inputCharacters[i]);
//if indexOf() returns a -1, the character is invalid and will cause the worker to run forever!
if(search == -1){
invalidChar = inputCharacters[i];
return false;
}
}
Once the user phrase is checked and the worker is created, the worker is passed a start command, the input word, the current slider position, and the random character array. The worker sets up an event listener for messages from the main thread, and switches on the ‘cmd’ value. I pass in commands for starting, stopping, and updating the ‘speed’ slider, and the worker handles them accordingly. The worker’s start command then saves the correct word, the slider’s speed value, and the character array, then calls the main loop function, passing in the result of the createGuessWord function. The createGuessWord function just returns a dummy string of the same length as the correct word passed to the worker. Once the loop starts, it continues being called recursively until it passes the correct word/phrase back to the main thread. It achieves this by looping through each letter of the dummy ‘guess word’ and assigning it a random character from the array. Since the worker has the ‘correct word’, it first checks to see whether that particular character matches with the ‘guess word’ in that element. If it does, it skips ahead. I set the speed using input from the slider and the setTimeout() method, which takes a function and a time in milliseconds.
function loop(guessWord){
//loop should start with guessWord and correctWord being the same length thanks to createGuessWord function
for(var i = 0; i < guessWord.length; i++){
//if guess letter at current element matches name at current element, push it on array and continue loop
if(guessWord[i] == correctWord[i]){
guessWord[i] = correctWord[i];
continue;
}
else{
//if the char does not match, load a new, random char in that element of the array
guessWord[i] = charArray[Math.floor(Math.random() * charArray.length)];
}
}
postMessage(guessWord.join('')); //send guessword back
setTimeout(function(){loop(guessWord);}, speed);
}
I set the speed by raising the slider value to the power of 2 and multiplying by 10, since this yields a decent range of milliseconds between poles.