TPop TPop - 8 days ago 5
Javascript Question

How to update multiple array elements

In the homestretch with my Javascript Hangman Game. Remaining task is to handle updating the dashes (placeholders for letters) when the user guesses a letter that is contained more than once in the mystery word.

The code knows how many times the guessed letter appears in the mystery word (var name: totalCorrect) as well as the indices (array var name: indices) for those letters in the mystery word (array name: combineDashes).

I'm using the following code to update the dashes in the mystery word when the user guesses a letter that appears only once in the word but can't figure out how to update the dashes placeholder when there are multiple instances of the letter in the mystery word (indices contains multiple indices).

// replaces dash with the correctly guessed letter in the mystery word.
combineDashes[indices] = letter;


Full code follows:

// JavaScript Document


$(document).ready(function() { // upon page load

var badGuesses; // reset bad guess counter
var theWord; // defines variable globally
var combineDashes; // defines variable globally
var letter; // defines variable globally
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", "Z"]; // array of letters to choose
$("#lettersRemaining").html(alphabet); // gets elements of the alphabet array and displays on UI


// N E W G A M E B U T T O N C L I C K E D

$("#newGame").click(function() { // when user clicks on Start New Game button...

$("#status").hide(); // upon game reset hide the status section stating game over
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", "Z"]; // reset array of letters to choose from

$("#hangmanGuy").html('<img src="img/Hangman-0.png" id="hangmanImg" alt="pic of hangman no limbs" width="144" height="216">'); // reset hangman image
badGuesses = 0; // reset guess counter which is used later

var wordCollection = ["MANSION", "STATUE", "GORILLA", "NOTEBOOK", "SMARTPHONE", "ILLUSTRATION", "PHOTO", "ELEGANT", "ARBORIST", "KEYBOARD", "CALENDAR", "CAPITAL", "TEXTBOOK", "HORRIBLE", "LIBRARY"]; // array of words the computer will randomly choose from

theWord = wordCollection[Math.floor(Math.random()*wordCollection.length)]; // randomly selects a word
console.log("theWord is ....");
console.log(theWord);

var theWordLength = theWord.length; // Get number of characters in randomly selected word to know how many dashes to display
console.log("theWordLength is ....");
console.log(theWordLength);

// D I S P L A Y D A S H E S

combineDashes = []; // creates an array to hold the number of dashes inside the for loop

for (var i = theWordLength; i > 0; i--)
{
combineDashes.push(" - "); // each loop through adds a dash to the array
}

combineDashes.join(" "); // joins cumulative dashes and converts to a string

$("#dashes").html(combineDashes); // displays dashes on UI
console.log("combineDashes is...");
console.log(combineDashes);

});


// G U E S S L E T T E R C L I C K E D

$("#guessLetter").click(function() { // when user clicks on the Guess Letter button pass in theWord value ....
console.log(combineDashes);

var letter = $("#theLetter").val().toUpperCase(); // gets the letter the user is guessing & makes uppercase
console.log("letter is ...");
console.log(letter);

// Is the letter a good or bad guess?
var indices = []; // new array to capture indices of all letters contained in the word

var idx = theWord.indexOf(letter);

while (idx !== -1) { // loops thru to find all letters in the word
indices[indices.length] = idx;
idx = theWord.indexOf(letter, idx + 1);
}
console.log("indices of letter guess contained in the word");
console.log(indices);

var totalCorrect = indices.length; // captures how many letters guessed were correct
console.log("totalCorrect letters...");
console.log(totalCorrect);

// F O R B A D G U E S S E S
if (indices.length === 0) // if bad guess
{
badGuesses++; // increment bad guess counter
$("#status").show();
$("#status").html("Sorry, " + letter + " is incorrect. Try again."); // status message displays
console.log("Total badGuesses...");
console.log(badGuesses);

// remove guessed letter from alphabet
var alphaIndex = alphabet.indexOf(letter); // gets index of letter in alphabet
alphabet.splice(alphaIndex,1); // removes the letter from the alphabet array
console.log("alphabet index of letter guessed...");
console.log(alphaIndex);
$("#lettersRemaining").html(alphabet); // refreshes letters remaining

// display correct hangman image based on how many bad guesses
if (badGuesses === 1)
{
$("#hangmanGuy").html('<img src="img/Hangman-1.png" id="hangmanImg" alt="pic of hangman 1 limb" width="144" height="216">');
}
else if (badGuesses === 2)
{
$("#hangmanGuy").html('<img src="img/Hangman-2.png" id="hangmanImg" alt="pic of hangman 2 limbs" width="144" height="216">');
}
else if (badGuesses === 3)
{
$("#hangmanGuy").html('<img src="img/Hangman-3.png" id="hangmanImg" alt="pic of hangman 3 limbs" width="144" height="216">');
}
else if (badGuesses === 4)
{
$("#hangmanGuy").html('<img src="img/Hangman-4.png" id="hangmanImg" alt="pic of hangman 4 limbs" width="144" height="216">');
}
else if (badGuesses === 5)
{
$("#hangmanGuy").html('<img src="img/Hangman-5.png" id="hangmanImg" alt="pic of hangman 5 limbs" width="144" height="216">');
}
else if (badGuesses === 6)
{
$("#hangmanGuy").html('<img src="img/Hangman-6.png" id="hangmanImg" alt="pic of hangman 6 limbs" width="144" height="216">');
$("#status").html("Game Over. Sorry, you didn't win. Click Start New Game and try again."); // status message displays
}
}
// F O R G O O D G U E S S E S
else
{
// remove guessed letter from alphabet
var alphaIndex = alphabet.indexOf(letter); // gets index of letter in alphabet

alphabet.splice(alphaIndex,1); // removes the letter from the alphabet array
console.log("alphabet index of letter guessed...");
console.log(alphaIndex);

$("#lettersRemaining").html(alphabet); // refreshes letters remaining

console.log(indices[0]); // gives value of the indexes array position 0
console.log(indices[1]); // gives value of the indexes array position 1
console.log(indices[2]); // gives value of the indexes array position 2
console.log(indices[3]); // gives value of the indexes array position 3
console.log(indices[4]); // gives value of the indexes array position 4
console.log(indices[5]); // gives value of the indexes array position 5
console.log(indices[6]); // gives value of the indexes array position 6
}


// R E P L A C E D A S H E S W I T H L E T T E R

// if there's only one instance of the letter in the word...
if (totalCorrect === 1) {
combineDashes[indices] = letter;
console.log(letter);
console.log(combineDashes);
}

else // if there are multiple instances of the letter in the word...
{
letterInWordIndex0 = indices[0]; // assigns value of index to variable
letterInWordIndex1 = indices[1]; // assigns value of index to variable
letterInWordIndex2 = indices[2]; // assigns value of index to variable

combineDashes[letterInWordIndex0] = letter; // replaces dash with letter
combineDashes[letterInWordIndex1] = letter; // replaces dash with letter
combineDashes[letterInWordIndex2] = letter; // replaces dash with letter
}
// D I S P L A Y S T A T U S M E S S A G E
$("#dashes").html(combineDashes); //
$("#status").show();

// HUNG UP HERE
combineDashes.find(" - ");

if (noMoreDashes = []) { // ?? HOW TO SAY NO DASHES REMAIN ?
$("#status").html("YOU WIN! Click Start New Game to play again."); // status message displays
}
else
{
$("#status").html(letter + " is correct! Go again."); // status message displays
}


});

});

Answer

For both when totalCorrect is 1 or when it is greater, you can use this single piece of code:

indices.forEach(function (index) {
    combineDashes[index] = letter; 
});

Then you do this:

combineDashes.find(" - ");

But you don't capture the result that it gives. Also, find needs a callback function. You can use includes instead, and can merge it into the if that follows, using the ! operator (i.e. "not"):

if (!combineDashes.includes(" - ")) {
    $("#status").html("YOU WIN! Click Start New Game to play again.");
}

If your browser does not support includes, then use indexOf, like this:

if (combineDashes.indexOf(" - ") == -1) {
    $("#status").html("YOU WIN! Click Start New Game to play again.");
}

Note that you have several other issues in your code. It is too long to completely analyse, but for instance, this:

combineDashes.join(" "); 

... does nothing. Because join returns the result -- it does not modify combineDashes. Instead use it where you pass it to be displayed:

$("#dashes").html(combineDashes.join(" "));

The code has a lot of repetition. Try to reuse code. For instance, this:

if (badGuesses === 1) 
{
    $("#hangmanGuy").html('<img src="img/Hangman-1.png" id="hangmanImg" alt="pic of hangman 1 limb" width="144" height="216">');
}
if (badGuesses === 2) 
    // ...etc

...can be written as:

if (badGuesses <= 6) {
    $("#hangmanGuy").html('<img src="img/Hangman-' + badGuesses 
        + '.png" id="hangmanImg" alt="pic of hangman ' + badGuesses 
        + ' limb" width="144" height="216">');
}
if (badGuesses >= 6) {
    $("#status").html("Game Over. Sorry, you didn't win. Click Start New Game and try again.");
}
Comments