AddEventListener running twice - javascript

I'm writing a simply game in javascript, which consists of colored squares and you have to choose the square with the rgb displayed in the screen.
What happens is that when I click in a square, and then I click play again to get a new color, addEventListener runs twice, the first time it says that the answer is equals the previous rgb value, the second time it says the answer is equals the new rgb value. The problem is that entering with the wrong answer, makes you points = 0 even though you got it right.
Any suggests what might be happening?
That's my code:
window.onload = function() {
var buttonNewColor = document.getElementById("buttonNewColor");
var squares = document.querySelectorAll(".square");
buttonNewColor.onclick = getColors;
}
function getColors() {
answer = colors[getRandomInt(6) - 1];
colorChoice.innerHTML = answer;
console.log("answer top: " + answer);
for (var i = 0; i < squares.length; i ++) {
squares[i].style.backgroundColor = colors[i];
squares[i].addEventListener("click", function(){
console.log("Square Clicked");
clickedColor = this.style.backgroundColor;
console.log("clickedColor: " + clickedColor);
console.log("answer: " + answer);
if (clickedColor === answer) {
console.log("points: " + points);
message.textContent = "Correct";
buttonNewColor.textContent = "Play Again";
points = points + 1;
score.innerHTML = "Score: " + points;
changeColors(answer);
answer = " ";
} else {
console.log("Entering on else")
points = 0;
score.textContent = "Score: " + points;
message.textContent = "Try Again";
}
});
}
}

Related

hide button at end of array

so here is the code i have so far, now i want to remove the button whenever the color is at the end of the array but i dont get it to work i tried different things with an if statement like this:
if(color.length){
document.getElementById("button").remove();
}
and with "removechild" but none of these works does anyone have an solution?
var color = ["green", "red", "black"];
function page() {
document.body.style.backgroundColor = "grey";
//style page
createButtons(10);
}
page();
function onbuttonclicked(a) {
var Amount = document.getElementById("button" + a);
var click = Amount.getAttribute('Color');
var change = color.indexOf(click);
Amount.setAttribute('style', 'background-color:' + color[change + 1]);
Amount.setAttribute('Color', color[change + 1]);
if(color.length){
document.getElementById("button").remove();
}
}
function set_onclick(amount) {
for (var a = 1; a < (amount + 1); a++) {
document.getElementById("button" + a).setAttribute("onclick", "onbuttonclicked(" + a + ")");
}
}
function createButtons(amount) {
for (var a = 1; a <(amount + 1); a++) {
var button = document.createElement("button");
button.id = "button" + a;
button.innerHTML = "button " + a;
button.setAttribute('Color', color[0]);
button.setAttribute('style', 'background-color:' + color[0]);
container.appendChild(button);
}
set_onclick(amount);
}
so for example i have a few green buttons when you click on the buttons the color changes a few times, the last color is black if the button is black and you click on it then i want to hide the buttons so you dont see it anymore
In order to check if the background color is the same as the last color, simply compare the elements (you named it Amount) background color with the last element in the array. And you also have to put the if statement BEFORE changing the color.
if (Amount.style.backgroundColor == color[color.length-1]) {
Amount.remove();
However you should re-think about your naming since it can get a little confusing.
For example: Amount is definetly the wrong name since it refers to the clicked element. The parameter you pass (a) is the amount.
If you have any questions feel free to ask them.
let color = ["green", "red", "purple", "blue", "black"];
function page() {
document.body.style.backgroundColor = "grey";
//style page
createButtons(30);
}
page();
function onbuttonclicked(a) {
var Amount = document.getElementById("button" + a);
var click = Amount.getAttribute('Color');
var change = color.indexOf(click);
if (Amount.style.backgroundColor == color[color.length - 1]) {
Amount.remove();
} else {
Amount.setAttribute('style', 'background-color:' + color[change + 1]);
Amount.setAttribute('Color', color[change + 1]);
}
}
function set_onclick(amount) {
for (var a = 1; a < (amount + 1); a++) {
document.getElementById("button" + a).setAttribute("onclick", "onbuttonclicked(" + a + ")");
}
}
function createButtons(amount) {
for (var a = 1; a < (amount + 1); a++) {
var button = document.createElement("button");
button.id = "button" + a;
button.innerHTML = "button " + a;
button.setAttribute('Color', color[0]);
button.setAttribute('style', 'background-color:' + color[0]);
document.getElementById("container").appendChild(button);
}
set_onclick(amount);
}
<div id="container">
</div>

Outputting an image in JavaScript onto a hangman game

I am creating a hangman game and I have to output images, when the users lives get down from 7-0.
I have put this code into my javascript , however it only outputs the if(lives ==8) image.
Unfortunality it does not seem to work at all ?
I am very new to javascript and when I have read the other answers, I have found them hard to understand.
The fact that it doesn't output , does this mean I have an error in my code somewhere. ?
function setup() {
alphabet = "abcdefghijklmnopqrstuvwxyz";
lives = 8;
var words = ["ayeupmeducks", "pieceofcake", "bullinachinashop", "hangfire","greeneyedmonster", "hairraising","bringhomethebacon","adiamondintherough","onceinabluemoon","afootinthedoor","bitethebullet"];
messages = {
win: 'Congratulations you have won the game of Hangman!',
lose: 'You have been Hanged !!',
guessed: ' already guessed, please try again...',
validLetter: 'Please enter a letter from A-Z'
};
var getHint = document.getElementById("hint");
var showClue = document.getElementById("clue");
getHint.onclick = function() {
hints =
["Stoke Greeting","Saying Something is Easy", "Very Clumsy","delaying something for a minute", "When you are jealous of something","Something is frightening", "Earn Money", "Rough Exterior however has some potential", "When something rarely happens", "When you have succeeded/ getting yourself known by a company","accepting something , when you do not want to"];
var hintIndex = words
showClue.innerHTML = "Clue: - " + hints [idx];
};
gussedLetter = matchedLetter = '';
numberofMatchedLetters = 0;
/* This chooses the word which will be displayed on the page */
idx = Math.floor(Math.random() * words.length);
currentWord = words[idx];
output = document.getElementById("output");
message = document.getElementById("message");
guessInput = document.getElementById("letter");
message.innerHTML = 'You have ' + lives + ' lives remaining';
output.innerHTML = '';
document.getElementById("letter").value = '';
guessButton = document.getElementById("guess");
guessInput.style.display = 'inline';
guessButton.style.display = 'inline';
letters = document.getElementById("letters");
letters.innerHTML = '<li class="current-word">Current word:</li>';
var letter, i;
for (i = 0; i < currentWord.length; i++) {
/* returns the character at the specified index in a string.*/
letter = '<li class="letter letter' + currentWord.charAt(i).toUpperCase() + '">' + currentWord.charAt(i).toUpperCase() + '</li>';
/* inserts the results node into Dom at the correct place, The BeforeEnd- inside the element, after its last child.*/
letters.insertAdjacentHTML('beforeend', letter);
}
}
function gameOver(win) {
if (win) {
output.innerHTML = messages.win;
output.classList.add('win');
} else {
output.innerHTML = messages.lose;
output.classList.add('error');
}
guessInput.style.display = guessButton.style.display = 'none';
guessInput.value = '';
}
window.onload = setup();
document.getElementById("restart").onclick = setup;
guessInput.onclick = function () {
this.value = '';
};
document.getElementById('hangman').onsubmit = function (e) {
if (e.preventDefault) e.preventDefault();
output.innerHTML = '';
output.classList.remove('error', 'warning');
guess = guessInput.value;
if (guess) {
if (alphabet.indexOf(guess) > -1) {
if ((matchedLetter && matchedLetter.indexOf(guess) > -1) || (gussedLetter && gussedLetter.indexOf(guess) > -1)) {
output.innerHTML = '"' + guess.toUpperCase() + '"' + messages.guessed;
output.classList.add("warning");
}
else if (currentWord.indexOf(guess) > -1) {
var lettersToShow;
lettersToShow = document.querySelectorAll(".letter" + guess.toUpperCase());
for (var i = 0; i < lettersToShow.length; i++) {
lettersToShow[i].classList.add("correct");
}
for (var j = 0; j < currentWord.length; j++) {
if (currentWord.charAt(j) === guess) {
numberofMatchedLetters += 1;
}
}
matchedLetter += guess;
if (numberofMatchedLetters === currentWord.length) {
gameOver(true);
}
}
else {
gussedLetter += guess;
lives--;
message.innerHTML = 'You have ' + lives + ' lives remaining';
if (lives === 0) gameOver();
}
}
else {
output.classList.add('error');
output.innerHTML = messages.validLetter;
}
}
else {
output.classList.add('error');
output.innerHTML = messages.validLetter;
}
return false;
};
var x = document.createElement("IMG");
if (lives==8){
x.setAttribute("src", "Hangman-0.png");
x.setAttribute("width", "304");
x.setAttribute("height", "228");
x.setAttribute("alt", "Hangman");
document.body.appendChild(x);}
if (lives==7){
x.setAttribute("src", "Hangman-1.png");
x.setAttribute("width", "304");
x.setAttribute("height", "228");
x.setAttribute("alt", "Hangman");
document.body.appendChild(x);}
From looking at you code, you can simplify a lot - each image has the same height, width, and alt, so you can move all of that out of the function. Also, assuming the src attribute is just a number that is incrementing, you can instead do something like:
var num_lives = 8;
var lives_left = 8;
function guess() {
lives_left--;
x.setAttribute('src', 'Hangman-' + (num_lives - lives_left) + '.png');
}
So, as a working example, your code would basically be:
var url = 'https://www.oligalma.com/downloads/images/hangman/files/';
const num_lives = 10;
var lives = 10;
var x = document.createElement("IMG");
x.setAttribute("width", "304");
x.setAttribute("height", "228");
x.setAttribute("alt", "Hangman");
x.setAttribute("src", url + (num_lives - lives) + '.jpg');
document.body.appendChild(x);
function change() {
lives--;
if (lives < 0) {
lives = num_lives;
}
x.setAttribute("src", url + (num_lives - lives) + '.jpg');
}
<button onClick="change()">Guess</button>

Javascript guessing game, defining onkeyup variable

Super new to javascript. I'm trying to make a psychic guessing game. Everything here works except the onkeyup function. When I open the console log and type letters, it tells me that the userGuess variable is undefined. How do I defined the userGuess variable to match the onkeyup function?
Thanks:
//Available choices
var letterChoices = ['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']
//score
var wins = 0;
var losses = 0;
var guesses = 9;
var guessesLeft = 9;
var guessedLetters = [];
var letterToGuess = null;
//computer randomly chooses a letter
var computerGuess = letterChoices [Math.floor(Math.random()*letterChoices.length)];
//guesses left function
var updateGuessesLeft = function() {
document.querySelector('#guessLeft').innerHTML = "Guesses Left: " + guessesLeft;
};
//letter to guess function
var updateletterToGuess = function(){
this.letterToGuess = this.letterChoices[Math.floor(Math.random() * this.letterChoices.length)];
};
var updateGuessesSoFar = function(){
document.querySelector('#let').innerHTML = "Your guesses so far: " + guessedLetters.join(', ');
};
//reset
var reset = function(){
totalGuesses = 9;
guessesLeft = 9;
guessedLetters = [];
updateletterToGuess();
updateGuessesSoFar();
updateGuessesLeft();
};
updateGuessesLeft();
updateletterToGuess();
//user input key
document.onkeyup = function(event) {
guessesLeft--;
var userGuess;
console.log(userGuess)
guessedLetters.push(userGuess);
updateGuessesLeft();
updateGuessesSoFar();
if (guessesLeft > 0){
if (userGuess === letterToGuess){
wins++;
document.querySelector('#wins').innerHTML = 'Wins: ' + wins;
alert("How did you know!?!");
reset();
}
} else if (guessesLeft == 0){
losses++;
document.querySelector('#losses').innerHTML = 'Losses: ' + losses;
alert("Sorry, you're not a psychic!");
reset();
}
}
The variable userGuess is undefined because it is just declared. There is no assignment operation happening to this variable. I looked at the working sample, modified it in the browser, and it seems to be working as expected. The only change I did was to assign userGuess to the key pressed, as follows
var userGuess = event.key;
Here is the output I got by playing around a bit with your code
Since you have a list of characters that you want to allow, you could add the following code at the beginning, to make sure anything other than the allowed characters are not considered
if (letterChoices.indexOf(userGuess) === -1) return;

Javascript Hangman - Replace Character In String

I've seen similar questions asked on Stack Overflow regarding this topic, but I haven't seen anything specific that would help me. My issue is that I can't seem to figure out how to replace a dash in hiddenWord with a correctly guessed letter while still retaining the dashes for un-guessed letters. Here is what I have so far and I'm not even sure if it's on the right track.
<script type="text/javascript">
// Declaration of Variables
var wordPool= ["Alf", "MarriedWithChildren", "Cheers", "MASH", "CharlesInCharge", "FmailyTies", "KnightRider", "MagnumPI", "MiamiVice"];
var lives = 6;
var myLetter;
var letter;
var wordChoice;
var hiddenWord;
var i;
var enter;
// Selects word randomly from wordPool[]. Then replaces the letters with "- ".
function selectedWord() {
var number = Math.round(Math.random() * (wordPool.length - 1));
wordChoice = wordPool[number];
for(i = 0; i < wordChoice.length; i++){
hiddenWord = wordChoice.replace(/./g,"- ");
}
console.log(hiddenWord);
}
// Gives myLetter a value of key pressed. If key is "Enter" selectedWord() initiates
document.onkeyup = function(event) {
var myLetter = event.key;
if(myLetter === "Enter"){
selectedWord();
}
console.log(myLetter);
}
</script>
I have seen some stuff with jQuery and PHP but I have to do it in javascript for class. Any help would be appreciated and if this has been addressed before please let me know.
You can check each character at the word string, compare it with the chosen character and replace it, if it is the same character.
I changed your code a bit to reflect what you are looking for.
Also make sure to lowercase all characters to make it easier for the player.
// Declaration of Variables
var wordPool= ["Alf", "MarriedWithChildren", "Cheers", "MASH", "CharlesInCharge", "FmailyTies", "KnightRider", "MagnumPI", "MiamiVice"];
var lives = 6;
var myLetter;
var letter;
var wordChoice;
var hiddenWord;
var i;
var enter;
// Change character to selected one
function checkCharacter(n) {
for(i = 0; i < wordChoice.length; i++){
console.log(wordChoice[i].toLowerCase() + "==" + n);
if(wordChoice[i].toLowerCase() == n.toLowerCase()){
hiddenWord = setCharAt(hiddenWord,i,n);
}
}
console.log("[" + hiddenWord + "]");
}
function setCharAt(str,index,chr) {
if(index > str.length-1) return str;
return str.substr(0,index) + chr + str.substr(index+1);
}
// Selects word randomly from wordPool[]. Then replaces the letters with "- ".
function selectedWord() {
var number = Math.round(Math.random() * (wordPool.length - 1));
wordChoice = wordPool[number];
hiddenWord = wordChoice.replace(/./gi,"-");
console.log(wordChoice + "[" + hiddenWord + "]");
}
// Gives myLetter a value of key pressed. If key is "Enter" selectedWord() initiates
document.onkeyup = function(event) {
var myLetter = event.key;
if(myLetter === "Enter"){
if(lives == 0){
selectedWord();
lives = 6;
}else{
lives--;
}
}
console.log(myLetter);
checkCharacter(myLetter);
}
//Select a random word at start
selectedWord();
I made a JSfiddle that is working and playable:
Check it out here...
Try
hiddenWord += "- "
Instead of replace
Or
hiddenWord += wordChoice[i].replace(/./g,"- ");
Here's an example:
var word = "do this";
var displayWord = [];
for (var i = 0; i < word.length; i++) {//build array
if (word[i] === " ") {
displayWord.push(" ");
} else {
displayWord.push("-");
}
}
function update(userGuess) {//update array
for (var i = 0; i < word.length; i++) {
if (word[i] === userGuess) {
displayWord[i] = userGuess;
} else {
displayWord[i] = displayWord[i];
}
}
}
//Guess letters
update("h");
update("o");
displayWord = displayWord.join('');//convert to string
alert(displayWord);
Check out the pen - https://codepen.io/SkiZer0/pen/VbQKPx?editors=0110

I'm using raphael.js for a visual interface on my Battleship game. I'm having some problems

I'm using raphael.js as a visual interface of my Battleship game. I have a function called createCanvas() which creates a grid (10x10). That way the user can see where to aim. The problem is, the grid doesn't appear until after the code of the game (putting in coordinates etc) has finished. Anyone know how to solve this?
Here's the entire code. Below, the code of createCanvas() and of game().
function createCanvas() {
$(function() {
var canvas = Raphael(0, 0, 2000, 2000);
for(var i = 0; i != (BOARD_WIDTH); i++) {
canvas.text((60+70*i), 15, i+1);
}
for(var i = 0; i != (BOARD_HEIGHT); i++) {
canvas.text(15, (60+70*i), i+1);
}
for(var i = 0; i != (BOARD_WIDTH+1); i++) {
canvas.path( "M" + (25+(70*i)) + ",25 L" + (25 + (70*i)) + ",725" );
}
for(var i = 0; i != (BOARD_HEIGHT+1); i++) {
canvas.path( "M25," + (25+(70*i)) + " L725," + (25+(70*i)) );
}
});
}
function game(){
inputArray = [4,3,2];
var boats = randomBoats(inputArray);
var currentBoat = 0;
var sunkenBoat = 0;
var numberOfTurns = 0;
while(sunkenBoat !== inputArray.length ) {
var hit= false;
var target = "(" + prompt("Enter targetcoordinate (x,y)") + ")";
var targetString = target.replace(/\s+/g, '');
for(var i = 0; i !== inputArray.length; i++) {
for(var j = 0; j !== boats[i].usedPositions().length; j++) {
console.log(targetString)
if(targetString === boats[i].usedPositions()[j].toString()) {
hit = true;
boats[i].hits[j] = 1;
console.log(boats[i].hits);
currentBoat = boats[i];
fillSquare(targetString, "red");
break;
}
}
}
console.log(currentBoat.hits);
console.log(allEquals(currentBoat.hits, 1));
if(hit)
alert ("Hit!");
else {
fillSquare(targetString, "blue");
alert ("Miss!");
}
if(allEquals(currentBoat.hits, 1)) {
alert("Boat with length " + currentBoat.hits.length + " has sunken!");
sunkenBoat++;
}
numberOfTurns++
}
alert("You've won! You did it in " + numberOfTurns + " turns.")
}
In my code I call
createCanvas();
game();
so I would think the canvas is drawn first...
The issue is the While loop. You're not giving anything else a chance to get in and do anything. This will just keep going around and around as fast as possible until you're done.
You should take a stab at putting a Input box on the page and and detecting key events looking for the enter key with something like this.
document.onkeypress = function(evt) {
evt = evt || window.event;
var charCode = evt.keyCode || evt.which;
var charStr = String.fromCharCode(charCode);
alert(charStr);
};
That way the animations and other stuff your're going to need later can run without being blocked, you don't burn CPU cycles like crazy, and you only check for a hit when the user has actually entered a value
Then you will maybe even write some code display "Hit" or "Miss" on canvas (may be animated) and that way you can remove all the alert and message boxes that keep popping up.

Categories