I've already had one questions regarding this game answered, but I keep getting stuck up on keeping track of my "wins" and "losses" and then reseting my random word after a win or a loss. Here is what I have so far:
var guess; //user guess
var letters = []; //correctly guessed letters
var wrongLetters = []; //incorrectly guessed letters
var counter = 7; //counts correct letters
var losses = 0;
var wins = 0;
document.getElementById("counter").innerHTML = counter;
document.getElementById("losses").innerHTML = losses;
document.getElementById("wins").innerHTML = wins;
var wordList = ["cat", "dog", "wolf", "laser", "apple"]; //FILL LIST LATER!!
//randomly chooses a word from wordList
var word = wordList[Math.floor(Math.random() * wordList.length)];
//choosen word is replaced with
function start() {
for (i = 0; i < word.length; i++) {
letters[i] = "__";
}
document.getElementById("answer").innerHTML = letters.join(" ");
console.log(word);
}
//checks if letter is in the word or not
function checkLetter() {
document.onkeyup = function(event) {
guess = event.key.toLowerCase();
var found = false;
for (i = 0; i < word.length; i++) {
if (guess === word[i]) {
letters[i] = guess;
document.getElementById("answer").innerHTML = letters.join(" ");
found = true;
}
}
//wrong letters go into the wrongLetters array and are displayed
if (found) return;
if (wrongLetters.indexOf(guess) < 0) {
wrongLetters.push(guess);
document.getElementById("wrongGuesses").innerHTML = wrongLetters.join(" ");
counter--;
console.log(counter);
//+1 to the losses if 7 words are missed
if (counter === 0) {
document.getElementById("losses").innerHTML = losses + 1;
console.log(losses);
confirm("play again?"); {
counter = 7;
letters = [];
wrongLetters = [];
start();
}
}
}
}
}
//need the counter to subtract 1 with every wrong guess
//when counter hits zero losses = losses + 1
//make a wins var that adds 1 when word is guessed
//reset if either are
start();
checkLetter();
<!DOCTYPE html>
<html>
<head>
<title>Hangman</title>
</head>
<body>
<h1>Hangman!</h1>
<span>Just start writing to play.</span>
<p>
<font size="+3"><span id="answer"></span></font>
</p>
<p id="counter"></p>
<p id="wrongGuesses"></p>
<p>Wins: <span id="wins"></span></p>
<p>Losses: <span id="losses"></span></p>
</body>
</html>
The counter is ALMOST working! It seems to be counting down from 7 and adding 1 to the losses when it reaches zero as it should; however, the count displayed is off (even though the count logged to the console seems right).
Another issue is that this "losses" count won't continue to add past 1 even if the counter resets and hits 0 again.
Also, when I try to grab a new random word after the player fails to answer the first, the game chooses the same word as it did before.
I feel like most of these issues have to deal with the scope of my variables, but none of the reworking I try seems to have any affect (if it doesn't make things worse). I know I'm asking a lot here, but if anyone could even point me in the right direction it would be greatly appreciated!
Lets start with fixing the random word.
The variable word needs to be accessed by several functions so it need to be defined on a scope outside the current functions. But you want to set it new each time inside the start() function. You can do that by declaring the variable outside of the function where it is now, but set it inside the function. You should also reset the counter here.
//randomly chooses a word from wordList
var word
//choosen word is replaced with
function start() {
word = wordList[Math.floor(Math.random() * wordList.length)];
counter = 7;
document.getElementById("counter").innerHTML = counter;
for (i = 0; i < word.length; i++) {
letters[i] = "__";
}
document.getElementById("answer").innerHTML = letters.join(" ");
console.log(word);
}
The counter isn't working, because it doesn't look like you're updating the html when the counter changes. You need something like this with each guess:
document.getElementById("counter").innerHTML = counter;
counter--;
console.log(counter);
The losses aren't incrementing because you are only changing the HTML but not the losses variable (kind of the opposite of the above). You need both:
losses++
document.getElementById("losses").innerHTML = losses;
There is also one subtly problem -- you are catching all the keyups including an enter keyup when you first start. You can catch only letters with something like this:
document.onkeyup = function(event) {
// don't catch numbers, punctuation, enter, etc.
if (!(event.which <= 90 && event.which >= 65)) return
Related
I am the very begginer (only if/else, for, while, slice etc) and i ve got a problem: so i wrote Hangman game. I need to put in there code saying ‘’let’s player upper case guess letter transform to lowercase one every time he puts uppercase letter”
Did i choose the right place for this new code in existing code?
Were my thoughts about appropriate code more or less right?
If not: what s wrong then?
var words = ["fish", "monkey", "pioni", "agreable"];
var randomWord = words[Math.floor(Math.random() * words.length)];
var answerArray = [];
for (var i = 0; i < randomWord.length; i++) {
answerArray[i] = "_";
}
var ramainingLetters = randomWord.length;
//Game circle
while (ramainingLetters > 0) {
alert(answerArray.join(" "));
var guess = prompt("Guess a letter or press cancel to exit game");
if (guess === null) {
break;
} else if (guess.length !== 1) {
alert("Enter only one letter");
} else if (guess == guess.toUpperCase()) {
guess = guess.toLowerCase();
} else {
//renew game cycle
for (var j = 0; j < randomWord.length; j++) {
if (randomWord[j] === guess) {
answerArray[j] = guess;
ramainingLetters--;
}
}
}
// stop game
}
alert(answerArray.join(" "));
alert(" Cool! this word was " + randomWord);
You could easily solve your problem by converting the chosen word to uppercase and everytime the user puts in a letter, make that uppercase too.
var randomWord = words[Math.floor(Math.random() * words.length)].toUpperCase();
And convert your quess always to uppercase
guess = guess.toUpperCase();
This way everything is consistent.
If they type in a letter in lowercase its getting converted to uppercase and compared with the word also in uppercase.
So Im pretty new to javascript and coding in general. Im making a Wordle algorithm just for fun to build my skills in coding. and while making this algorithm i realized that i was going to have to kind of recreate Wordle. so i looked online for wordle recreations in java script, and all the ones I found I saw one flaw that I didn't want to have.
The flaw that I saw was in the IF statement for checking a letter in the wordle answer. Specifically when the letter is in the word but not in the right spot. The recreations that i saw had an IF statement that looked something like this.
IF (answerWord.includes(guessLetter[i])) {
guessLetter[i] = color.(yellow)
}
(this isnt exactly how they wrote it, but its the main idea)
My main focus is on the .includes. This would not work because say our guess word is "agree" and the answer word "ready". the 2 E's in "agree" would be yellow, and we dont want that because their is is only 1 E in "ready. So we only want the first E in "agree" to be yellow and not the second E.
So i decided to figure it out on my own, and i was able to come up with this and it works. At least Im pretty sure it works, base on the the many words i tested it on.
So my question is, since Im making an algorithm im going to be making alot of calculations, is this the most efficient i could write this or can i make it better?
let guessWord = "agree"; // the first word thats inputed
let answerWord = "ready"; // the answer to the wordle
/*
'letterCheck' is an array that tells what condition each letter in 'startLetter' is, based on the answer word
2 = the letter is in the word and in the correct place (GREEN)
1 = the letter is in the word but not in the correct place (YELLOW)
0 = the letter in not in the word (GREY)
*/
var letterCheck = ["0", "0", "0", "0", "0"];
var guessLetter = ["A", "A", "A", "A", "A"]; // the separated letters of 'startword' in a array
var answerLetter = ["A", "A", "A", "A", "A"]; // the separated letters of 'answord' in a array
//adds the start word and the answer world to the arrays
for (var i = 0; i < 5; i++) {
guessLetter[i] = guessWord.substring(i, i + 1);
answerLetter[i] = answerWord.substring(i, i + 1);
}
console.log(guessLetter);
console.log(letterCheck);
console.log(answerLetter);
//this loops goes though every letter one by one
for (var i = 0; i < 5; i++) {
//checks if the letter is in the right spot
if (guessLetter[i] == answerLetter[i]) {
letterCheck[i] = "2";
console.log(guessLetter[i]);
console.log(letterCheck);
} else if (answerWord.includes(guessLetter[i])) {
//checks if there is more than one letter in start word or its the first letter
if (guessWord.split(guessLetter[i]).length - 1 == 1 || i == 0) {
letterCheck[i] = "1";
console.log(guessLetter[i]);
console.log(letterCheck);
//checks if the the amount of same letters in start words is equel to the amount of same letters in answer word
} else if (guessWord.split(guessLetter[i]).length - 1 == answerWord.split(guessLetter[i]).length - 1) {
letterCheck[i] = "1";
console.log(guessLetter[i]);
console.log(letterCheck);
//opposite of above
} else if (guessWord.split(guessLetter[i]).length - 1 != answerWord.split(guessLetter[i]).length - 1) {
letterCheck[i] = "1";
console.log(guessLetter[i]);
console.log(letterCheck);
// checks if any of the letters infront of it are the same as it
for (var j = 0; j < i; j++) {
if (guessLetter[i] == guessLetter[j]) {
letterCheck[i] = "0";
console.log(guessLetter[i]);
console.log(letterCheck);
}
}
}
} else {
letterCheck[i] = "0";
console.log(guessLetter[i]);
console.log(letterCheck);
}
}
console.log(guessLetter);
console.log(letterCheck);
console.log(answerLetter);
( I will remove the console.log's later they just helped my to debug.)
Sorry if my code might be confusing, im not the best at keeping my code clean. if you have any confusion or questions, I'll try my best in clear up any confusion.
To get all of the states (in precedence order: correct, wrong-position, incorrect), you should check in that precedence order, and remove letters from contention once the state in that letter's position has been set.
function check(guess, targetWord) {
const checkStates = new Array(5).fill("incorrect");
const letters = guess.split('');
const targetLetters = targetWord.split('');
for (let i=0; i<5; i++) {
if (targetLetters[i] === letters[i]) {
checkStates[i] = "correct";
targetLetters[i] = '';
letters[i] = '';
}
}
for (let i=0; i<5; i++) {
if (!letters[i]) continue;
let fi = targetLetters.findIndex(t => t===letters[i]);
if (fi > -1) {
checkStates[i] = "contains";
targetLetters[fi] = '';
}
}
return checkStates;
}
let solution = "ready"
console.log(`solution is ${solution}`);
let guess = "agree";
console.log(`checking ${guess}... ${check(guess, solution)}`);
guess = "roars";
console.log(`checking ${guess}... ${check(guess, solution)}`);
guess = "boars";
console.log(`checking ${guess}... ${check(guess, solution)}`);
solution = "beast"
console.log(`\nsolution is ${solution}`);
guess = "treat";
console.log(`checking ${guess}... ${check(guess, solution)}`);
Well, here's something to consider in simplifying. You can use a simple MAP loop to determine which letters are incorrect, then later highlight those in the word.
let guessWord = "agree"; // the first word thats inputed
let answerWord = "ready"; // the answer to the wordle
let tmpGuess = guessWord.split('');
let incorrects = answerWord.split('').map(e => {
let i = tmpGuess.indexOf(e);
if (i > -1) { // found it!
tmpGuess.splice(i, 1); // remove
return '';
}
return e;
}).filter(f => f);
console.log(incorrects);
I m not sure what i m doing wrong. Thanks in advance for helping me in this matter.
var sum = 0;
var pricecheck = 35;
while (sum < pricecheck) {
var userinput = prompt("Please enter the cost of the item...");
var num1 = parseInt(userinput);
submitprice.push(num1);
for (i = 0; i < submitprice.length; i++) {
sum += submitprice[i];
}
}
alert("free shipping.");
Declare sum to zero each time you are executing the sum of items. Or else it will keep on adding to the sum that was calculated in previous iteration.
Also your submitprice seems to be undefined. I have initilaized it as an empty array.
Working Fiddle
var sum = 0;
var pricecheck = 35;
const submitprice = [];
while (sum < pricecheck) {
var userinput = prompt("Please enter the cost of the item...");
var num1 = parseInt(userinput);
submitprice.push(num1);
sum = 0;
for (i = 0; i < submitprice.length; i++) {
sum += submitprice[i];
}
}
alert("free shipping.");
To start, you need to create an empty array to store the totals in. For this, I will call it "cart":
var cart = [];
Next, I would suggest creating an if statement to check if the input is a number:
var num1 = parseInt(userinput);
if(isNaN(userinput){
alert("Please enter a number");
continue;
}
You don't need the for loop to add the input to the sum, just remove the loop:
sum += userinput
After the loop, you would push to the cart:
cart.push(num1)
Finally, you need to check if the sum is more than free shipping
if(sum >= pricecheck) {
alert("You qualify for free shipping!")'
}
Then just output the result to the console with a pipe (|) concatenated between the numbers.
console.log(cart.join(" | ")
var sum = 0;
var cart = [];
var pricecheck = 35;
while (sum < pricecheck) {
var userinput = prompt("Please enter the cost of the item...");
if (userinput === null) {
break;
}
var num1 = parseInt(userinput);
if (isNaN(userinput)) {
alert("Please enter a number");
continue;
}
cart.push(num1);
sum += num1;
}
if (sum >= pricecheck) {
alert("free shipping.");
}
I took a look at this assignment again to refresh on what was asked for this question. You do not need to have that for loop at all within the while loop. Within each iteration of the while loop, you are asking the user for the price of their next item, adding it to the shopping cart, and also adding it to a running total (this total being your "sum"). This running total does not need to be re-calculated each time inside of the while loop because you would have done that in a single line. You are trying to calculate the price, starting at 0, each time you loop through the while loop (using your for loop). But this is not needed as you already have a running total that can be added to each time the user enters a value.
"Austin Caron" explained it well but for this assignment we do not need to do user authentication.
P.S. Try your best to avoid asking questions directly about an assignment and ask more general questions about a concept or idea you are struggling with.
I am trying to build a hangman game and I need help with the logic. I am in a beginners class so I want to try and build this using beginners syntax. What I am trying to figure out
2) My issue is I need to display dashes (-) that represent blank lines and they need to be the same length of the randomly chosen word. In addition, every time a letter is correctly guessed, I need to replace the dashes with the correctly chosen letter. A solution I have thought of is making an empty array and then assigning it the dash signs in a for loop that is the length of the string and then replacing the indexes of specific dashes with matched letters, but I am not sure if this will work.
var randomWords = ['rock', 'paper', 'scissors'];
var numWins = 0;
var chosenWord = randomWords[Math.floor(Math.random() * randomWords.length)];
document.onkeyup = function(event) {
// var userGuess = String.fromCharCode(event.keyCode).toLowerCase();
var dashes = "";
for (var x = 0; x < chosenWord.length; x++) {
dashes += " - ";
// document.getElementById("word").innerHTML = blankLines;
// document.getElementById("word").innerHTML = ;
}
document.getElementById("word").innerHTML = dashes;
Trying to replace a dash with a letter in lines below. But both commented out code and non commented out codes work. That is why I am thinking of using an empty array but not sure if I can fill it with data using a foor loop
// for (x = 0; x < chosenWord.length; x++)
// {
// dashes[x] = "a";
// dahes.charAt(x) = 'a';
// }
dashes.charAt(0) = "a";
document.getElementById("test2").innerHTML = dashes;
This one should work. In the first case (if there's a white space in the word) it will display a whitespace. In the second case, it will replace every letter of the word with a dash.
var dashes = "";
for (i = 0; i < chosenWord.length; i++) {
if (chosenWord.charAt(i) == " ") {
dashes += " ";
} else {
dashes += "-";
}
}
I have a game of hangman where if someone guesses an incorrect letter it adds the image changes. to accomplish this I created a variable that when an incorrect letter is guessed is incremented and I use Jquery .html to change the picture. The problem I have is that the first wrong guess changes the picture but subsequent guesses do not. Is this because Jquery's .html just adds another div? what is a good solution to this? Below is the code
var word;
var wrongGuess = 0;
var usedLetters = [];
$(document).ready(function () {
SetGameBoard();
});
//When guess button is clicked
$('#BtnGuess').click(function () {
CheckGuess();
});
function GetPhrase() {
word = ReturnWord();
alert(word);
}
function SetGameBoard() {
$('#WinLose').hide();
$('#controls').show();
GetPhrase();
wordToGuess = new Array(word.length);
// Place underscore for each letter in the answer word in the DivWord div
for (var i = 0; i < word.length; i++){
wordToGuess[i] = "_ ";
}
$('#DivWord').html(wordToGuess);
}
function CheckGuess() {
var pos = 0;
var posArray = [];
var guessLetter = $('#tbGuessLetter').val();
var picNum = 0;
//check to see if letter has been used
if(usedLetters.indexOf(guessLetter) != -1){
alert("You've already used this Letter!");
}
//populate array with indices of occurrences of guessed letter
while ((pos = word.indexOf(guessLetter, pos)) > -1) {
posArray.push(++pos);
}
//if the guessed letter is not in the word...
if (posArray.length == 0) {
picNum++;
alert(guessLetter + " is not in the word.");
$('#DivPic').html('<img src="images/h'+picNum+'.png" />');
}else{
//iterate over array of underscores (wordToGuess[]) and splice in guessed letter
for(i=0; i < posArray.length; i++){
wordToGuess.splice(posArray[i] - 1, 1, guessLetter);
}
//update DivWord
$('#DivWord').html(wordToGuess);
usedLetters.push(guessLetter);
}
$('#tbGuessLetter').val("");
}
You should move picNum to the top, to declare it as global:
var picNum = 0;
var word;
var wrongGuess = 0;
var usedLetters = [];
Because each time it goes to the CheckGuess() function it resets to zero, then if the user fails it will only increment to 1. That's why you are seeing the same image (first time)