I'm building a word game. One of the functions I need is a function that receives a word and replaces several words with (_) and gives the incomplete word as output. I want the number of words to be replaced and the location of those words to be chosen randomly. The code I wrote, although it uses for, is only able to replace one word. What changes should I make in the for part of the code that has the ability to move several words? for example : "laptop" => "l_pt_p"
function wordToIncomplete(word) {
let randomNumber = Math.floor(Math.random() * 3) + 1
let _randomNumber = Math.floor(Math.random() * word.length)
let _word = "";
for (let index = 0; index < randomNumber; index++) {
_word = word.replace(word[_randomNumber], '_');
}
return _word
}
The example returns an array of letters which is easier to work with, but if for some reason you want a string, do the following to the last line:
return chars.join('');
Note: this example actually adjusts dynamically the number of letters to be replaced which is from 30% to 60% of word.length.
Details are commented in example below
// Utility function
const log = data => console.log(JSON.stringify(data));
// Random integer range function
const randRng = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const fragWord = word => {
/*
The result of the following expressions is a random number that's
within the range of 30% to 60% of total length of >word<
>word< string is converted into an array of letters called >chars<
*/
const size = word.length;
const lo = Math.ceil(0.3 * size);
const hi = Math.ceil(0.6 * size);
let qty = randRng(lo, hi);
let chars = word.split('');
/*
At each iteration of >chars< a random index number is generated.
If there's a '_' at that index, the current iteration is skipped
and qty increases by 1 to compensate.
Otherwise the letter at that index is replaced with a '_'
*/
skip:
for (let i = 0; i < qty; i++) {
let index = randRng(0, size - 1);
let char = chars.at(index);
if (char === '_') {
qty = qty + 1;
continue skip;
}
chars[index] = '_';
}
return chars;
};
log(fragWord('fragment'));
log(fragWord('appearance'));
log(fragWord('institutionalization'));
log(fragWord('institutionalization'));
I think your problem is you did not put your _randomNumber in the loop to re-generate your removed character index
function wordToIncomplete(word) {
let randomNumber = Math.floor(Math.random() * 3) + 1
let _word = word;
for (let index = 0; index < randomNumber; index++) {
let _randomNumber = Math.floor(Math.random() * _word.length)
_word = _word.replace(_word[_randomNumber], '_');
}
return _word
}
const testingWords = "testing words"
console.log(wordToIncomplete(testingWords))
But with this solution, I think it will encounter another problem that it may check the same character which is already replaced earlier
Therefore, I modified your code a bit with while loop
function wordToIncomplete(word) {
let randomNumber = Math.floor(Math.random() * 3) + 1
let _word = word;
let index = 0;
while (index < randomNumber) {
let _randomNumber = Math.floor(Math.random() * _word.length)
if (_word[_randomNumber] === '_') { // we don't need to replace the checked words
continue;
}
_word = _word.replace(_word[_randomNumber], '_');
index++;
}
return _word
}
const testingWords = "testing words"
console.log(wordToIncomplete(testingWords))
By the way, you also did not assign value for _word, so I changed it to
let _word = word
Yes, as @Barmar mentioned, naming is important.
What changes should I make in the for part of the code that has the ability to move several words
The problem here is that _randomNumber is always same during the loop.
function wordToIncomplete(word) {
const randomNumberOfCharactersToBeReplaced =
Math.floor(Math.random() * word.length) + 1;
let result = word;
for (let i = 0; i < randomNumberOfCharactersToBeReplaced; i++) {
// suppose we don't care about whether the character is already replaced or not.
const randomIndexToBeReplaced = Math.floor(Math.random() * word.length);
result[randomIndexToBeReplaced] = "_";
}
return result;
}