I'm developing a website for fun that adds a random character to a div element on every key press. I have that part working, but what I need is for the program to check if an English word has been created out of the random characters and highlight that word. I've tried many things, and none have worked. Preferably this would highlight it regardless of whether or not there are spaces surrounding the word, but I will be very happy with really any working code.
This is my current JS for random character generation and autoscrolling, also with some code that doesn't work that is meant to search the code.
var letter = 1
var number = 1
const alphabet = ['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', '\u0020']
function typingfunction() {
number = Math.floor(Math.random() * 27)
letter = alphabet[number]
document.getElementById("typing").innerHTML = `${document.getElementById("typing").innerHTML}${letter}`
window.scrollTo(0, document.body.scrollHeight * document.body.scrollHeight);
var input = document.getElementById("typing").innerHTML;
var fs = require('fs');
fs.readFile("words_alpha.txt", function(words) {
var words = words.toString().split('\n').filter(function(word) {
return word.length >= 4;
})});
var output = [];
words.forEach(word); {
if (input.match(word)) {
output.push(word);
}
};
console.log(output);
}
window.addEventListener('keydown', typingfunction)
The code for testing a word basically is OK but there was a syntax error in your code (incorrect format for an anonymous function) and also the words array was only declared inside a function but you tried to use it outside the function.
This code slightly reorganises things to take account of this.
I have no way of testing the nodejs filereading (assuming it is nodejs) so if that causes a problem add the tag to your question to get more help in that area.
The code listens for a click on the window and sets the input HTML empty so several trials can be run.
var letter = 1
var number = 1
const alphabet = ['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', '\u0020']
function typingfunction() {
number = Math.floor(Math.random() * 27)
letter = alphabet[number]
document.getElementById("typing").innerHTML = `${document.getElementById("typing").innerHTML}${letter}`
window.scrollTo(0, document.body.scrollHeight * document.body.scrollHeight);
var input = document.getElementById("typing").innerHTML;
var output = [];
words.forEach(word => {
if (input.match(word)) {
output.push(word);
}
});
console.log(output);
}
// first set up the array of words from the file containing them
let words; //declare words here so it can be used later on
let fs = require('fs');
fs.readFile("words_alpha.txt", function(allWords) {
words = allWords.toString().split('\n').filter(function(word) {
return word.length >= 4;
})});
window.addEventListener('keydown', typingfunction);
window.addEventListener('click', function () {document.getElementById("typing").innerHTML = '';});
Related
I am new to javaScript and having a terrible time with understanding loops.
Currently I have a random text generator function. I have gotten it to generate random characters from a string but only one character each time the function is ran. I would like to build a string of 20 random characters from the output of the function.
This is what I have so far:
function passGen() {
let text = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWYXZ()!##$%&*/?+-%".split("");
let randomIndex = Math.floor(Math.random() * text.length);
return text[randomIndex];
}
let randomPass = passGen();
I would like to let the function produce the random character and then use a for loop to out put 20 of these random characters in a string.
I can't get
for (let i = 0; i <= 20; i++){
console.log(randomPass)
to work.
Any help is appreciated.
You need to define a string variable and then use a loop to append characters to it, like this:
function passGen () {
const text = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWYXZ()!##$%&*/?+-%'.split('')
let res = ''
for (let i = 0; i < 20; i++) {
res += text[Math.floor(Math.random() * text.length)]
}
return res
}
const randomPass = passGen();
You need to specify for yourself what characters you want to support, for example:
function getRandomCharacter(supportedCharacters) {
return supportedCharacters[parseInt(Math.random() * supportedCharacters.length)];
}
function getRandomString(supportedCharacters, length) {
let output = "";
while (length--) output += getRandomCharacter(supportedCharacters);
return output;
}
console.log(getRandomString([
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'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',
], 20));
getRandomCharacter randomizes a character
Math.random() generates a real number which is greater or equal than 0 but smaller than 1
multiplying Math.random() with the number of supported characters scales the value to the interval between [0, length)
parseInt rounds the result down
the result of parseInt can be used as an index
getRandomString generates all the characters using a while loop
length-- evaluates length and then decreases it by 1
+= concatenates the resulting character to output
return output; clarifies that the result of the function is the string
the test sample defines an array (you could do it with a string as well if you want) of the characters you want to support and the length of the string you desire
For example say you have the string 'ab?d?f' and you must grab the string and replace it with any random letters in the '?' like 'abcdef' or 'abjdlf' but it cannot be 'abbdef' or 'abcdff'.
I have attempted this below:
const letters = ['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'];
const randomLeter = () => letters[Math.floor(Math.random() * 26)];
const riddle = 'ab?d?f';
let pickedLetter;
let solvedRiddle;
function solve(riddle) {
for (let i = 0; i < riddle.length; i++) {
if (riddle[i] === '?' && !(riddle[i-1] === randomLeter) && !(riddle[i+1] === randomLeter)){
console.log('Changing to letter');
solvedRiddle = riddle.replace('?', pickedLetter);
}
pickedLetter = randomLeter();
console.log(i, riddle[i], pickedLetter);
}
return solvedRiddle;
}
// The above only returns the first '?' changed but leaves the second one unchanged ... ??? Why can I not change the value of solvedRiddle a second time inside the loop? I can see by my log that it reads at true, but the value won't be re-written.
console.log(solve(riddle));
function solve(riddle) {
for (let i = 0; i < riddle.length; i++) {
if (riddle[i] === '?'){
console.log('Changing to letter');
let pickedLetter = randomLeter();
while (riddle[i-1] === pickedLetter || riddle[i+1] === pickedLetter) {
pickedLetter = randomLeter();
}
riddle = riddle.replace('?', pickedLetter);
}
}
return riddle;
}
Also, it's because u update and return solvedRiddle. Your original riddle string is not updated, so in the second run, it is still changing the first ?
I modified your code so that it suits the needs, however there may be some bugs or exceptions not handled yet, but it can give you a hint that how you are going to solve the problem.
const letters = ['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'];
let randomLeter = (excluded) =>
{
let letter = false;
do
{
letter = letters[Math.floor(Math.random() * 26)];
}
while(excluded.includes(letter));
return letter;
}
let getIndices = (s, t) => {
return [...s].flatMap((char, i) => (char === t ? i : []));
};
let Solve = (riddle) =>
{
riddle = [...riddle];
//get the locations of all ? in the string
let all = getIndices(riddle, '?');
for(let i = 0; i < all.length; i++)
{
//exluding characters before and after the ?
let excluded = [riddle[all[i] - 1], riddle[all[i] + 1]];
riddle[all[i]] = randomLeter(excluded);
}
return riddle.join("");
};
let riddle = 'ab?d?f';
document.getElementById('riddle').innerHTML = 'The Riddle ' + riddle;
document.getElementById('solution').innerHTML = "Solution " + Solve(riddle);
<h2 id="riddle"></h2>
<h4 id="solution"></h4>
I am very new to Javascript so excuse me if I am using the incorrect terminology.
For my class, I have to create a game where the user has to guess which letter the computer is "thinking."
What I am struggling with is how to get the "computer" to choose ONE letter from the array and keeping it static rather than choosing a new letter each time the user makes a guess. Here is my code-
var alphabet = ['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'];
document.onkeyup = function() {
var userguess =
String.fromCharCode(event.keyCode).toLowerCase();
console.log(userguess);
var computerGuess =
alphabet[Math.floor(Math.random() * alphabet.length)]
console.log(computerGuess);
}
Take your computerGuessoutside the event handler. You're generating a new value on each keyup:
var alphabet = ['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'];
var computerGuess = alphabet[Math.floor(Math.random() * alphabet.length)];
document.onkeyup = function() {
var userguess = String.fromCharCode(event.keyCode).toLowerCase();
console.log(`userguess: ${userguess}, computerGuess: ${computerGuess}`);
}
I'd like to write a function that generates the corresponding column name for a specific number, for example A for 1 or AA for 127. I know this has been answered quite a lot already, but I'd like to do it in a functional way.
Sure, you should be able to convert the existing (imperative) answers pretty easily, but I find myself getting stuck every time I try to.
Any good ideas / functional implementations?
Here's a working implementation.
var letters = ['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'];
function toLetter(number) {
if (!number || number <= 0) {
return 0;
}
var code = "";
for (var i = 0; i < Math.floor(number / 26); i++) {
code += letters[i];
}
code += letters[(number % 26) - 1];
return code;
}
console.log(toLetter(27)); // returns AA;
Good evening everyone,
I am trying to generate a string of 8 characters, which are randomly chosen from an array. This is what I am using:
var myArrayPismo = ['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'];
while(myArrayPismo.length < 9){
var randomletter = Math.ceil(Math.random()*myArrayPismo.length)
if(myArrayPismo.indexOf(randomletter) > -1) continue;
myArrayPismo[myArrayPismo.length] = randomletter;
}
Which just prints out all of the letters, for some reason.
And this is my number generating function:
var kodCisla = [];
while(kodCisla.length < 9){
var randomnumber = Math.ceil(Math.random()*9)
if(kodCisla.indexOf(randomnumber) > -1) continue;
kodCisla[kodCisla.length] = randomnumber;
}
Which is working fine. Except I want it to be able to generate 2 or more same numbers, not just different each time.
My goal is to get a random string of letters like this: KODlkSmQW
and a random string of numbers that can also repeat like this: 887562327
Any help on either of these problems would be appreciated.
A function that can pluck a random element from an array would be useful here. Notice the use of Math.floor rather than Math.ceil, and the array access that comes before the return statement.
function randomElement (array) {
return array[Math.floor(Math.random() * array.length)]
}
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),
result = '';
for (var i = 0; i < 8; i++) {
result += randomElement(characters)
}
console.log(result) //=> (random 8-character string)
For random numbers, you can use a similar randomInRange function:
function randomInRange (a, b) {
a |= 0
b |= 0
return Math.floor(Math.random() * (b - a + 1)) + a
}
var result = []
for (var i = 0; i < 8; i++) {
result.push(randomInRange(0, 9))
}
console.log(result) //=> (eight random digits)
Your first while loop is never running because it is based on the condition that myArrayPismo.length < 9, which is already false because you just set it to contain all 26 letters. So, when you go to look at it later, you get all the original values. What you need is an additional array to put the generated randoms into.
Also, stay away from a while loop in this case because you know exactly how many times you want to loop, so use a regular for loop instead.
Your second array (with numbers) does this and can certainly come up with the same random twice in a row.
But, both arrays don't need to do any if/then checking before pushing the random into the array.
Finally, as I mentioned, don't use Math.ceil because you'll never get the first element back as a random, use Math.floor instead.
var myArrayPismo = ['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'];
var resultArray = [];
for(var i = 0; i < 8; ++i){
resultArray.push(myArrayPismo[Math.floor(Math.random()*myArrayPismo.length)]);
}
console.log(resultArray.join(""));