ShaunY
ShaunY

Reputation: 13

What causes this bug and how can I fix it?

I am trying to make a game in html and js where a word is displayed on the screen that is either new or has been shown before and you need to press the correct button ("seen" or "new") otherwise you lose a life.

My problem is that currently the word that determines if you lose a life or not is the word that comes AFTER you press the button which makes the game unplayable since you have no way of knowing the next word in advance.

var word_bank = ["test1", "test2", "test3", "test4", "test5", "test6", "test7", "test8", "test9", "test10", "test11", "test12", "test13", "test14", "test15"];

var old_words = [];
var dec = word_bank;
var lives = 3;

function updateLives() {
  document.getElementById("lives").innerHTML = "Lives: " + lives;
}

function thing(v) {

  var rndn = Math.floor(Math.random() * (1 - 0 + 1)) + 0;

  if (rndn == 1) {
    var dec = word_bank
  } else {
    var dec = old_words
  }

  var word = dec[Math.floor(Math.random() * dec.length)];

  document.getElementById("word").textContent = word;

  if (v == 1) {
    if (old_words.includes(word)) {

    } 
    else {
      --lives
      updateLives();
    }
  } 
  else {
    if (old_words.includes(word)) {
      --lives
      updateLives();
    }
  }

  old_words.push(word);

  var forDeletion = [word];

  word_bank = word_bank.filter(item => !forDeletion.includes(item))

};

var word = dec[Math.floor(Math.random() * dec.length)];

document.getElementById("word").textContent = word;

updateLives();
old_words.push(word);

var forDeletion = [word];

word_bank = word_bank.filter(item => !forDeletion.includes(item))
<span id="lives"></span>

<div id="center">
  <span id="word"></span>
</div>

<div>
  <div>
    <button name="submit" class="action_btn_left seen" type="submit" value="seen" onclick="thing(1)">Seen</button>
    <button name="submit" class="action_btn_right new" type="submit" value="new" onclick="thing(0)">New</button>
  </div>
</div>

Upvotes: 1

Views: 102

Answers (2)

Akhil
Akhil

Reputation: 879

  1. You started your program with a word - lets say it is test10
  2. Then the user selects an option b/w seen or not seen
  3. In the thing function You are generating a word for the next round lets say test2 and you are judging the player for that word (test2) at the same time instead of test10

So you need to save test10 in a variable. Then when the user takes an action you first evaluate him with this variable. And finally, you generate the next round word.

Check the below script for some reference

const livesCountElement = document.getElementById("lives");
const wordElement = document.getElementById("word");
const scoreElement = document.getElementById("score");
const playAgain = document.getElementById("playAgainBtn");
const playBtns = document.getElementById("playBtns");

const wordsBank = [
  "Test 1", "Test 2", "Test 3", "Test 4", "Test 5", "Test 6", "Test 7", "Test 8", "Test 9", "Test 10", "Test 11", "Test 12", "Test 13", "Test 14", "Test 15", "Test 16"
];

let oldWords = [];

let lives = 3;
let score = -1;
let currentWord = "";

function updateLives() {
  livesCountElement.innerHTML = "Lives: " + lives;
  if (lives <= 0) {
    death();
  }
}

function updateWord(wordToDisplay) {
  wordElement.innerHTML = "Word is: " + "<b>" + wordToDisplay + "</b>";
}

function updateScore() {
  score++;
  scoreElement.innerHTML = "Score: " + score;
}

function death() {
  wordElement.innerHTML = "<b> You died:( </b>";
  playAgain.style.display = "block";
  playBtns.style.display = "none";
}

function getRandomWord() {
  return wordsBank[Math.floor(Math.random() * wordsBank.length)];
}

function thing(v) {
  // Player already died :(
  if (lives <= 0) {
    return;
  }

  // Evaluate the current round  :: START -------------------
  const userSaidSeen = v === 1;
  const isAlreadySeen = oldWords.includes(currentWord);

  if ((userSaidSeen && !isAlreadySeen) || (!userSaidSeen && isAlreadySeen)) {
    --lives;
    updateLives();
  } else {
    updateScore(); // Success! -> Increase score and display
  }

  if (!isAlreadySeen) {
    // If it is a new word push it to {oldWords}
    oldWords.push(currentWord);
  }
  // Evaluate the current round  :: END -------------------

  // Next round preperation BELOW

  // If player is already dead :( you dont need to show any new word
  if (lives <= 0) {
    return;
  }

  // Show new word and set it as currentWord
  currentWord = getRandomWord();
  updateWord(currentWord);
}

function start() {
  lives = 3;
  score = -1;
  oldWords = [];

  updateLives();
  updateScore();

  currentWord = wordsBank[Math.floor(Math.random() * wordsBank.length)];
  updateWord(currentWord);

  playAgain.style.display = "none";
  playBtns.style.display = "block";
}

start();
<html>
<body>
  <p id="score"></p>
  <p id="lives"></p>

  <div id="center">
    <p id="word"></p>
  </div>
  
  <div>
    <div id="playBtns">
      <button name="submit" class="action_btn_left seen" type="button" onclick="thing(1)">Seen</button>

      <button name="submit" class="action_btn_right new" type="button" onclick="thing(0)">New</button>
    </div>
    
    <div id="playAgainBtn" style="display:none">
            <button name="submit" class="action_btn_right new" type="button" onclick="start()">Play again</button>
    </div>
  </div>
</body>
</html>

Upvotes: 1

Ravikumar
Ravikumar

Reputation: 2205

Seems this is what you are looking for

var word_bank = ["test1", "test2", "test3", "test4", "test5", "test6", "test7", "test8", "test9", "test10", "test11", "test12", "test13", "test14", "test15"];

var old_words = {};
let lives = 3;
let score = 0;

function updateLives() {
  document.getElementById("lives").innerHTML = `Lives:  ${lives}    Score: ${score}`;
}

function getRandomWord() {
  const rndm = Math.floor(Math.random() * word_bank.length);
  return word_bank[rndm];
}

function displayNewWord() {
  const word = getRandomWord();
  document.getElementById("word").textContent = word;
}

function thing(v) {
  const currentWord = document.getElementById("word").textContent;
  if ((v === 1 && !old_words[currentWord]) || (v === 0 && old_words[currentWord])) {
    --lives;
  } else {
    ++score;
  }
  updateLives();
  if (!lives) {
    document.getElementById("game-container").textContent = 'Game over!';
    return;
  }

  old_words[currentWord] = true;
  displayNewWord();
};

displayNewWord();
updateLives();
<html>

<head>

  <link rel="stylesheet" href="style.css">

</head>

<body>

  <span id="lives"></span>

  <div id="game-container">
    <div id="center">

      <span id="word"></span>

    </div>

    <div>

      <div>

        <button name="submit" class="action_btn_left seen" type="submit" value="seen" onclick="thing(1)">Seen</button>

        <button name="submit" class="action_btn_right new" type="submit" value="new" onclick="thing(0)">New</button>

      </div>

    </div>
  </div>

</body>

<script src="main.js"></script>

</html>

Upvotes: 1

Related Questions