3

I'm working on a hangman game in JavaScript and if the user guesses a letter correctly then I need to replace the "-" with the letter that the user has guessed in the corresponding position to where the letter is in the word. I can't seem to be able to replace the string, I can add the string on to the start or end of the "-"'s but when it comes to replacing them, I can't seem to figure out the solution. Any help appreciated. Thanks.

Function that checks if the letter is in the word or not

document.addEventListener("keydown", function textFunction(event)
{
if (event.keyCode > 64 && event.keyCode < 91) 
{
    var guess = event.keyCode;
    var a = "a";
    var letterGuess = String.fromCharCode(event.keyCode).toLowerCase();
    if(sayings[randomSaying].indexOf(letterGuess) >= 0){
        var letterLocation = sayings[randomSaying].indexOf(letterGuess) + 1;
        progress.innerHTML += letterGuess;
    } else {
        alert("no");
    }
    alert(letterGuess);
} 
else 
{
    alert("Please type a letter");
}
});

Prints out the dashes

for (var i = 0; i < sayings[randomSaying].length; i++)
{
   progress.innerHTML += "-";
}

Variables

var progress = document.getElementById("dashes");


var sayings = [
    "cash on the nail",
    "charley horse",
    "double cross",
    "fit as a fiddle",
    "hands down",
    "if the cap fits",
    "mumbo jumbo",
    "see red",
    "stone the crows",
    "thick and thin",
]
sayings.toString();
var randomSaying = Math.floor(Math.random()*sayings.length);
seanrs97
  • 323
  • 3
  • 14

5 Answers5

1

Make a list of it (and drop the +1 because its 0-based now)

if(sayings[randomSaying].indexOf(letterGuess) >= 0){
    var letterLocation = sayings[randomSaying].indexOf(letterGuess);
    var li = progress.innerHTML.split('');
    li[letterLocation] = letterGuess;
    progress.innerHTML = li.join('');

.split('') will split a string into its letters. So for "apple" you get ['a','p','p','l','e'].

Then simply replace the position in the list li[letterLocation] with your letter, and li.join('') the list again.

To have it look for repeated letters, a while loop should do. We also need to start the search after the last match, so it will not find the same spot repeatedly.

if(sayings[randomSaying].indexOf(letterGuess) >= 0) {
    var letterLocation = -1;
    while(sayings[randomSaying].indexOf(letterGuess, letterLocation + 1) >= 0) {
        var letterLocation = sayings[randomSaying].indexOf(letterGuess, letterLocation + 1);
        var li = progress.innerHTML.split('');
        li[letterLocation] = letterGuess;
        progress.innerHTML = li.join('');
    }
} else {
    alert("no");
}
C14L
  • 12,153
  • 4
  • 39
  • 52
  • Thankyou this does work but only for the first letter it finds, how do I do this if there are more than one of the same letters in the word? – seanrs97 May 18 '16 at 13:53
  • In the first line, replace `if` with `while`, so it will loop until no more concurrences of `letterGuess` are found. – C14L May 18 '16 at 13:58
  • Just tried this and the program wouldn't run at all, with no errors in the console – seanrs97 May 18 '16 at 14:08
  • Oh, there is an `else`, so that can't work. Wait a sec, I'll add it to the answer. – C14L May 18 '16 at 14:11
  • Thankyou for the update, But I think there's something wrong with the code, everytime I try it now, nothing is replaced and the page crashes when I try to reload the page – seanrs97 May 18 '16 at 14:24
  • There was a `+ 1` missing, I added it now. So it was finding the same spot over and over. – C14L May 18 '16 at 14:32
  • Argh, now I added it. Sorry. In two places, so it is each time `.indexOf(letterGuess, letterLocation + 1)` – C14L May 18 '16 at 14:35
  • That's It, Thankyou very much for bearing with me and helping me! One small problem is that it's not replacing the first letter if it's correct, but I'm sure that only requires a minor change. – seanrs97 May 18 '16 at 14:41
  • I don't suppose you'd be able to help with that would you? Iv'e got it to move a space up so that it starts where it should now, but not so it puts the letter at the start – seanrs97 May 18 '16 at 14:59
  • Fixed it. We need to start at `var letterLocation = -1` now, because we are adding one, so that it starts to find letters at position `0` again. – C14L May 18 '16 at 15:47
  • Thankyou again! I was going the complete opposite direction and adding 1 on, I don't know why but It didn't make sense to start from -1 in my head – seanrs97 May 18 '16 at 16:30
0

You may want to .split('') the sayings into char arrays, then iterate through the array testing to see if its in the saying. Then you can build up a array of index's to replace.

example:

var dummyInput = 'a';

var sayings = [
  'cake'
];

//placeholder
var sayingMatches = [];

//go over all the sayings
for (var i = 0; i < sayings.length; i++) {
  var indexMatches = [];
  var sayingChars = sayings[i].split(''); //convert to char array

  //go over char array
  for (var j = 0; j < sayingChars.length; j++) {
    var letterToTest = sayingChars[j];
    if (letterToTest == dummyInput) {
      indexMatches.push(j); //push index of the match
    }
  }
  //push index of the saying you were just matching
  sayingMatches.push({
    sayingIndex: i,
    indexOfTheLettersWhichMatch: indexMatches
  });
}

This will give you an output of:

var sayingMatches = [
  {
    sayingIndex: 0,
    indexOfTheLettersWhichMatch: [2]
  }
];

From this you can then use replace to replace the '-'s with the input.

Rhys Bradbury
  • 1,699
  • 13
  • 24
0

You can replace the string at the corresponding index with substrings:

var index = 2;
var str = "012345";
var newstr;

newstr = str.substr(0, index) + 'a' + str.substr(index+1, str.length);

// result: 01a345

Just replace the index with the result of your indexOf() call. Remember that you will have to run this function multiple times if the letter appears more than once. Something like this inside your keydown call:

var reducer = sayings[randomSaying];
while (reducer.indexOf(letterGuess) >= 0) {
    index = reducer.indexOf(letterGuess);
    // ...
    reducer.replace(letterGuess, ''); // removes first instance of the letter
}
KWeiss
  • 2,954
  • 3
  • 21
  • 37
0

You might be interested in this topic: And as you can see there you need to define a replaceAt() to the String.prototype like this

String.prototype.replaceAt=function(index, character) {
    return this.substr(0, index) + character + this.substr(index+character.length);
}

and then all you need to do is call it from your code as such:

if(sayings[randomSaying].indexOf(letterGuess) >= 0){
        var letterLocation = sayings[randomSaying].indexOf(letterGuess) + 1;
        progress.innerHTML = progres.innerHTML.replaceAt(letterLocation, letterGuess);

    }
Community
  • 1
  • 1
-2

Did you try replacing the whole word? For instance, if the word is apple and you present is as

a _ _ l _

as soon as the user presses p you would replace the value of the element to

a p p l _

This would be much easier that replacing a single character within the value of an element.

FDavidov
  • 3,505
  • 6
  • 23
  • 59