I am creating Hangman game. I want when the button is clicked to be checked whether some of the hidden letters matches the clicked button
for(let i = 0; i < letters.length; i++){
let letter = letters[i]
let hiddenLetters = document.querySelectorAll('.hidden')
hiddenLetters = Array.from(hiddenLetters)
letter.addEventListener('click', ()=>{
let check = hiddenLetters.some((hiddenLetter)=>{hiddenLetter.textContent == letter.textContent})
if(check){
console.log('works')
} else{
console.log('doesnt')
}
})
}
I think you have your hiddenLetters in a string. I would suggest you store individual letters in an array that way its easier to compare/check if the letters exist.
Something like this should get you going.
const checkIfLettersExist = (hiddenLetters, letters) => {
return hiddenLetters.some(hdnLetter => letters.includes(hdnLetter));
}
const hiddenText = "name";
const hiddenLetters = hiddenText.split('');
let letters = ['a','b'];
const check = checkIfLettersExist(hiddenLetters, letters);
(check ? console.log("works") : console.log("doesn't"));
Related
Here is my code can someone just explain why I am getting undefined?? I have split the words and then reverse them and after reversing I tried to store them in a different array.
Thank you
const text = document.querySelector("#text");
const reverseText = document.querySelector("#reverseText");
let words = text.innerHTML.split("").reverse();
console.log(words);
let reversedWords = [];
let counter = 0;
for (var i = 0; i <= words.length - 1; i++) {
if (words[i] != " ") {
reversedWords[counter] += words[i];
} else {
counter++;
}
}
console.log(reversedWords);
<p id="text">hello nixit</p>
<p id="reverseText"></p>
Your issue is that the first time you try and access reversedWords[counter], it is undefined because you've initialised reversedWords to be an empty array.
Without changing much of your code (because you said you're doing it this way as a challenge), you could try initialising reversedWords to have the appropriate number of elements, initialised to empty strings
const content = text.textContent;
const words = content.split("").reverse();
const reversedWords = Array.from({ length: content.split(" ").length }, () => "");
You're using an array so you need to push things into it, and then join it up into a new string once the iteration is done.
const text = document.querySelector('#text');
const reverseText = document.querySelector('#reverseText');
function reverse(str) {
// `split` the string on the spaces
const words = str.split(' ');
const reversedWords = [];
for (let i = 0; i < words.length; i++) {
// For each word split, reverse, and then rejoin it
const word = words[i].split('').reverse().join('');
// And then add the word to the array
reversedWords.unshift(word);
}
// Return the completed array
return reversedWords;
}
const str = text.textContent;
reverseText.textContent = JSON.stringify(reverse(str));
<p id="text">hello nixit</p>
<p id="reverseText"></p>
Additional documentation
unshift
I suggest using a string instead of an array. Then you can split it to turn it into an array.
const reversedChars = 'hello nixit'.split("").reverse()
const reversedWords = ''
reversedChars.forEach(char => {
reversedWords += char
})
const reversedWordsArray = reversedWords.split(' ')
console.log(reversedWords)
// Output: tixin olleh
console.log(reversedWordsArray)
// Output: [ 'tixin', 'olleh' ]
Thanks to #phil and #Andy,
I am new learner who will learn and read all the use of Array.from() and than use it, but till than I have made something like this.
const text = document.querySelector("#text");
const reverseText = document.querySelector("#reverseText");
let words = text.innerHTML.split("").reverse();
let reversedWords = new Array();
let counter = 0;
let firstChar = 0;
for (var i = 0; i <= words.length - 1; i++) {
if (words[i] != " ") {
if (firstChar === 0) {
reversedWords[counter] = words[i];
firstChar++;
} else {
reversedWords[counter] += words[i];
}
} else {
firstChar = 0;
counter++;
}
}
reversedWords.forEach(word => reverseText.textContent += word + " ");
<p id="text">hello nixit
<p>
<p id="reverseText">
<p>
I'm trying to find the longest sequence of "broken"(different from letter, digit, space) characters in this sentence:
'Tempera####&&#^ na ##$ata 23 grad#%&.'
I really want to do it using Regex, but I'm not that familiar with the usage of Regex in JS. This is the description of the problem: https://pastebin.com/U6Uukc4b
I watched a lot of tutorials, also read bunch of articles and this is what I came up with:
let input = [
'Tempera####&&#^ na ##$ata 23 grad#%&.'
];
let print = this.print || console.log;
let gets = this.gets || ((arr, index) => () => arr[index++])(input, 0);
let message = gets();
//different from letter, digit, space
let counter = 1;
let allWords = /[a-z1-9\s]/gi;
for (let i = 0; i < message.length; i++) {
let current = message[i];
// allWords.lastIndex = 0;
let isExisting = allWords.test(current);
if (current === '.') {
break;
}
if (isExisting) {
counter = 1;
} else {
counter++;
}
}
print(counter)
Here the answer should be 8 , because we have 8 consecutive symbols inside the word "Tempera####&&#^" , which are not letter, digit or space.
Unfortunately this doesn't work. I'm still trying to understand where is my mistake, so I'll be very thankful if someone can "show me the way".
Use a regular expression that matches the opposite ([^.....]) and as many times as possible (+). Then check the size of all matches and pick the longest length. As there is a special role for the point (which apparently is always at the end), consider it as not broken.
let allWords = /[^a-z1-9\s.]+/gi;
let input = [
'Tempera####&&#^ na ##$ata 23 grad#%&.'
];
for (let message of input) {
let results = message.match(allWords) ?? [];
let counter = Math.max(0, ...results.map(({length}) => length));
console.log("longest", counter);
}
const input = 'Tempera####&&#^ na ##$ata 23 grad#%&.';
function findLongestSubstring(input) {
let longest = '';
let current = '';
for (let i = 0; i < input.length; i++) {
if (input[i].match(/[^a-zA-Z\d\s]/)) {
current += input[i];
} else {
if (current.length > longest.length) {
longest = current;
}
current = '';
}
}
return longest.length;
}
console.log(findLongestSubstring(input));
I'm a newbie messing around with event listener/handlers and generally just getting to grips with some JS (first post on StackOverflow!)
I'm making a simple webpage that changes backgroundColor based on user input (alpha characters only). The user presses a letter key and the page will update to a color with a match on the first letter. It will also print the name of the color to the page.
I have a large array storing names of CSS colors, most keys have multiple colors that match the keystroke/first letter of the color, and some keys have no matches.
My code below hopefully explains my intentions, however I can't quite get it to work.
const colors = ["Aquamarine", "Alice Blue", "Antiquewhite", "Aqua", "Azure"] etc etc...
// Returns a random colour from the colour arrays
const randomiser = colorArr => {
return colorArr[Math.floor(Math.random()*colorArr.length)];
}
// Event listener
window.addEventListener("keypress", e => {
let colorsMatchingKeyName = [];
function colorFinder(arr) {
let keyName = e.key;
for (let i = 0; i < arr.length; i++) {
if (arr[i].charAt(0) !== keyName) {
document.getElementById('currentColor').innerHTML = `Sorry! No colours match up with the ${keyName} key!`;
} else if (arr[i].charAt(0) == keyName) {
colorsMatchingKeyName.push(arr[i]);
}
}
}
colorFinder(colors);
// Logging colors to console to test.
console.log(colorsMatchingKeyName) // outputs an empty array
// Once it is working i'll use the randomiser() function to pick a
// random colour from the colorMatchingKeyName array and set the document.style.backgroundColor
})
At present, each key event only prints the 'Sorry! No colours...' message shown in the if statement.
I'd be hugely grateful if someone could please direct me to the issue in my code!
You might want to check this out:
const colors = ["Aquamarine", "Alice Blue", "Antiquewhite", "Aqua", "Azure"]
// Returns a random colour from the colour arrays
const randomiser = colorArr => {
return colorArr[Math.floor(Math.random()*colorArr.length)];
}
// Event listener
window.addEventListener("keypress", e => {
let colorsMatchingKeyName = [];
function colorFinder(arr) {
let keyName = e.key;
document.getElementById('currentColor').innerHTML = '';
for (let i = 0; i < arr.length; i++) {
const c = arr[i].charAt(0).toLowerCase();
if (c !== keyName.toLowerCase()) {
document.getElementById('currentColor').innerText = `Sorry! No colours match up with the ${keyName} key!`;
} else if (c == keyName) {
colorsMatchingKeyName.push(arr[i]);
}
}
}
colorFinder(colors);
const color = randomiser(colorsMatchingKeyName);
console.log(color)
document.body.style.backgroundColor = color;
})
<div id="currentColor"></div>
I'm a JS learner and want to create an app that will calculate the average from input values. So far I've managed to push the entered input values into an array. However, when I want to display them, the previous value is repeated. So I'm near the end. But now I'm stuck. Can you lend me hand with that?
Enter
</button>
<p id="numbersEntered"></p>
<button id="avg" type="button">Average</button>
<p id="average"></p>
let numbersEntered = document.querySelector("#numbersEntered");
let inputEl = document.querySelector("#input");
// buttons
let enter = document.querySelector("#enter");
let numArr = [];
enter.addEventListener("click", displayNums);
function displayNums() {
let newNumber = inputEl.value;
numArr.push(newNumber);
console.log(numArr);
for (let i = 0; i < numArr.length; i++) {
numbersEntered.innerHTML += numArr[i] + ",";
}
}
You can just clear the innerHTML before appending;
function displayNums() {
let newNumber = inputEl.value;
numArr.push(newNumber);
numbersEntered.innerHTML = ""; //Clear the innerHTML
for (let i = 0; i < numArr.length; i++) {
numbersEntered.innerHTML += numArr[i] + ",";
}
}
https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
Instead of appending numArr to innerHTML, simply overwrite it instead. Also, since you're only writing plain text, it is recommended to use textContent instead of innerHTML:
function displayNums() {
let newNumber = inputEl.value;
numArr.push(newNumber);
console.log(numArr);
numbersEntered.textContent = numArr.join(', ');
}
There is no need to use a for loop when you can use Array.prototype.join to print the array out.
I have my word guessing game setup so that when the user presses the correct letter, the corresponding underscore is replaced with the letter. However, I can't seem to get the same letter to populate multiple times. Example: the word "Pennywise" has two of the letter 'n', but when the letter is pressed only one 'n' will populate no matter how many times I press the letter.
// Global Variables
// ================================================================================================================================================
// Create an array of words
var word = [
"michael myers",
"freddy krueger",
"jason voorhees",
"xenomorph",
"pinhead",
"ghostface",
"hannibal lector",
"pennywise",
"leatherface",
"chucky",
"jack torrance"
]
var rightLetter = [];
var wrongLetter = [];
var underScore = [];
// Choose word randomly
var randNum = Math.floor(Math.random() * word.length);
var randWord = word[randNum];
console.log(randWord);
// DOM manipulation
var docUnderScore = document.getElementsByClassName("underscore");
var docRightGuess = document.getElementsByClassName("rightGuess");
var docWrongGuess = document.getElementsByClassName("wrongGuess");
// ================================================================================================================================================
// Main
// ================================================================================================================================================
// Create underscore based on length of word
var generateUnderscore = () => {
for ( var i = 0; i < randWord.length; i++) {
underScore.push("_");
}
return underScore;
}
// Get user guess
document.addEventListener("keypress", (event) => {
var keyWord = String.fromCharCode(event.keyCode);
// if user's guess is correct
if (randWord.indexOf(keyWord) === -1) {
// replace underscore with correct letter
underScore[randWord.indexOf(keyWord)] = keyWord;
docUnderScore[0].innerHTML = underScore.join(" ");
// check to see if user word matches guess
if (underScore.join("") === randWord) {
alert("You Survived!");
}
}
// if user's guess is incorrect
else {
wrongLetter.push(keyWord);
docWrongGuess[0].innerHTML = wrongLetter;
}
});
docUnderScore[0].innerHTML = generateUnderscore().join(" ");
The issue is that you won't proceed further using randWord.indexOf(keyWord) as each time it fetches the first occurence of the letter you want to find, instead you could maintain a counter and match letter each time keydown event is fired, if it doe match then increment it to proceed:
// Create an array of words
var word = [
"michael myers",
"freddy krueger",
"jason voorhees",
"xenomorph",
"pinhead",
"ghostface",
"hannibal lector",
"pennywise",
"leatherface",
"chucky",
"jack torrance"
];
var rightLetter = [];
var wrongLetter = [];
var underScore = [];
var counter = 0;
// Choose word randomly
var randNum = Math.floor(Math.random() * word.length);
var randWord = word[7];
console.log(randWord);
// DOM manipulation
var docUnderScore = document.getElementsByClassName("underscore");
var docRightGuess = document.getElementsByClassName("rightGuess");
var docWrongGuess = document.getElementsByClassName("wrongGuess");
// Create underscore based on length of word
var generateUnderscore = () => {
for (var i = 0; i < randWord.length; i++) {
underScore.push("_");
}
return underScore;
}
// Get user guess
document.addEventListener("keypress", (event) => {
var keyWord = String.fromCharCode(event.keyCode);
// if user's guess is correct
if (randWord[counter] == keyWord) {
// replace underscore with correct letter
underScore[counter] = keyWord;
docUnderScore[0].innerHTML = underScore.join(" ");
// check to see if user word matches guess
if (underScore.join("") === randWord) {
console.log("You Survived!");
}
counter++;
}
// if user's guess is incorrect
else {
wrongLetter.push(keyWord);
docWrongGuess[0].innerHTML = wrongLetter;
}
});
docUnderScore[0].innerHTML = generateUnderscore().join(" ");
<div class="underscore"></div>
<div class="rightGuess"></div>
<div class="wrongGuess"></div>