Looping until the health runs out - Node.js - javascript

I am creating a JS CLI Game.
I need a loop that will automatically decrease health on both the player and the enemy and it won't stop until one of their's healths becomes 0 or less.
while (playerHealth > 0 || enemyHealth > 0) {
if (playerHealth > 0 || enemyHealth > 0) {
headerColor("Round", colors.blue, colors.green)
let decreaseHealth1 = randomDecreaseHealth()
playerHealth - decreaseHealth1
console.log("Ouch ! You lost " + decreaseHealth1)
let decreaseHealth2 = randomDecreaseHealth()
enemyHealth - decreaseHealth2
console.log("Nice hit. Enemy lost " + decreaseHealth2)
} else if (playerHealth <= 0) {
console.log("Damn, you lost. 😥😭 ")
} else if (enemyHealth <= 0) {
console.log("Yayyyyy, YOU WONNN !!! ")
}
}
This creates an infinite loop.
The headerColor("Round", colors.blue, colors.green) function creates a header that looks like this: https://i.stack.imgur.com/mCWes.png
randomDecreaseHealth() generates a random number that is used to decrease health from both the player and the enemy. I need different numbers. It doesn't always decrease the same amount. So normally I'd just call the function, except that I need to display the number by which health was decreased, so I stored it in a variable so that I could display that number.
So, basically, I need this loop to goes on until either playerHealth either enemyHealth reaches 0 or less. Also, I need that at the start of each round, the header displays the number of the round next to the Round word. One round is consisted of one hit taken and one hit given.
Any ideas ?
Thanks in advance

Did you try recursion? Something like this.
let playerHealth = 5;
let enemyHealth = 5;
function randomDecreaseHealth() {
return Math.random()
}
function headerColor(shape, color1, color2, round) {
console.log(`${shape}: ${round}`)
}
let colors = {
blue: "blue",
green: "green"
}
let count = 0;
function hit() {
if (playerHealth > 0 || enemyHealth > 0) {
count++
headerColor("ROUND", colors.blue, colors.green, count)
let decreaseHealth1 = randomDecreaseHealth()
playerHealth = playerHealth - decreaseHealth1
console.log("Ouch ! You lost " + decreaseHealth1)
let decreaseHealth2 = randomDecreaseHealth()
enemyHealth = enemyHealth - decreaseHealth2
console.log("Nice hit. Enemy lost " + decreaseHealth1)
hit()
} else if (playerHealth <= 0) {
console.log("Damn, you lost. 😥😭 ")
} else if (enemyHealth <= 0) {
console.log("Yayyyyy, YOU WONNN !!! ")
}
}
hit()

I solved it.
Because I imported playerHealth variable, for some unknown reason it was considered as a constant (even though I exported it as let). That's why it returned the error: TypeError: Assignment to constant variable. So I stored the imported playerHealth variable in another local variable and that solved the problem.
let count = 0
let playerHealthFight = playerHealth
function hit() {
if (playerHealthFight > 0 && enemyHealth > 0) {
count++
headerColor("Round #" + count, colors.green, colors.blue)
let decreaseHealth1 = randomDecreaseHealth()
playerHealthFight -= decreaseHealth1
console.log("Ouch ! You lost " + decreaseHealth1)
let decreaseHealth2 = randomDecreaseHealth()
enemyHealth -= decreaseHealth2
console.log("Nice hit. Enemy lost " + decreaseHealth2)
hit()
} else if (playerHealthFight <= 0) {
console.log("Damn, you lost. ")
} else if (enemyHealth <= 0) {
console.log("Yayyyyy, YOU WONNN !!! ")
}
}
hit()
Thanks for all the help !

Related

Functions and else ifs

I'm still pretty new to JavaScript and need to be pointed in the right direction on a tiny project that is just for practice.
Very sorry if I'm not posting incorrectly, this is my first post on Stack Overflow and any help is appreciated.
I've tried accomplishing my goal a few different ways and haven't gotten there.
attack.addEventListener("click", function(){
hit();
});
function hit(){
if (bossHealth.textContent > 0 && playerFocus.textContent >=2) {
playerFocus.textContent -= 2;
bossHealth.textContent -= 3;
console.log("attack");
}
else if (bossHealth.textContent >= 0 && playerFocus.textContent < 2){
alert("Attack costs 2 focus, try regenerating this turn to gain focus and health!");
}
};
strong.addEventListener("click", function(){
bigHit();
});
function bigHit(){
if(bossHealth.textContent > 0 && playerFocus.textContent >= 5){
playerFocus.textContent -= 6;
bossHealth.textContent -= 6;
console.log("strong attack");
}
else if (playerFocus <5){
alert("Strong attack costs 5 focus, if you do not have enough focus try regenerating for a turn");
}
else (bossHealth.textContent <= 0){
bossHealth.textContent = "Dead";
alert("You've killed the bad guy and saved the world!!!");
}
};
easy.addEventListener("click", function(){
reset();
});
function reset(){
playerHealth.textContent = 10;
playerFocus.textContent = 10;
bossHealth.textContent = 10;
};
hard.addEventListener("click", function(){
hardMode();
});
function hardMode(){
playerHealth.textContent = 10;
playerFocus.textContent = 10;
bossHealth.textContent = 15;
};
With function hit I don't get the alert in my else if statement
with function bigHit I also don't get my alert for the else if statement and neither part of the else statement works.
also subtraction works in my functions, but when trying to add another function that uses addition in the same way it adds the number to the end of the string instead of performing math
You really shouldn't depend on what is in the DOM for logic. You should try with local variables then update the DOM based on those variables.
var boss = {}
var player = {}
function reset(){
player.health = 10;
player.focus = 10;
boss.health = 10;
update()
};
function hit(){
if (boss.health > 0 && player.focus >=2) {
player.focus -= 2;
boss.health -= 3;
console.log("attack");
} else if (boss.health > 0 && player.focus < 2){
alert("Attack costs 2 focus, try regenerating this turn to gain focus and health!");
}
update()
}
function update() {
playerFocus.textContent = player.focus
playerHealth.textContent = player.health
bossHealth.textContent = boss.health
}
Your issue is caused by textContent automatically turning your numbers into strings, by managing the data using your own variables this doesn't affect your code's logic.
Alternatively you could parse the strings as numbers using new Number(playerFocus.textContent), parseFloat(playerFocus.textContent), or +playerFocus.textContent but your code will become very hard to read very quickly.
Hope this enough to help you to make more edits to your code.
It looks like your playerFocus variable is a DOM node? Based on that assumption, your condition is missing a check for its textContent:
if (bossHealth.textContent > 0 && playerFocus.textContent >= 5){
// ...
}
else if (playerFocus.textContent <5){
// ...
In JavaScript, else blocks cannot have conditions, so if you want to conditionally check whether bossHealth.textContent <= 0 at the end of your bigHit function, you will need to change it to an else if (bossHealth.textContent <= 0) { ... } block instead.
I'm adding on to #LoganMurphy's comment and my own. In order to use the value of bossHealth it needs to be an integer. Change your code to look something like this:
function hit(){
if (parseInt(bossHealth.textContent) > 0 && parseInt(playerFocus.textContent) >=2) {
playerFocus.textContent -= 2;
bossHealth.textContent -= 3;
console.log("attack");
}
else if (parseInt(bossHealth.textContent) >= 0 && parseInt(playerFocus.textContent) < 2){
alert("Attack costs 2 focus, try regenerating this turn to gain focus and health!");
}
};
https://www.w3schools.com/jsref/jsref_parseint.asp

Number guessing game, relationship between maxGuesses and guess count is skewed by 1

I am trying to let the game only let the user have 3 guesses to guess correctly. The problem is that it lets the user guess a 4th time, but even if user guesses correctly on 4th attempt I get a wrong answer message. I tried changing the number of guesses, changing that i = 0 start position, subtracting one from maxGuesses in the for loop. No matter what I try the relationship is off by one. Here is my code so far.
let readlineSync = require("readline-sync");
let hint = "";
let maxGuesses = 3;
const maxRange = 10;
const minRange = 1;
let userGuess = readlineSync.question(
"I have chosen a number between " +
minRange +
" and " +
maxRange +
". You have " +
maxGuesses +
" tries to guess it!\n"
);
const randomNumber = Math.floor(Math.random() * maxRange + 1);
function handleGuess(userGuess) {
if (userGuess != null && userGuess != undefined && (userGuess <= maxRange && userGuess >= minRange)) {
for (i = 0; i <= maxGuesses - 1; i++) {
if (userGuess == randomNumber) {
console.log(userGuess + " is CORRECT! YOU WIN!");
return;
} else {
if (userGuess > randomNumber) {
hint = "Think lower you fool.";
} else {
hint = "Think higher you fool.";
}
console.log(hint);
userGuess = readlineSync.question("Guess again. \n");
}
}
console.log("Dude...YOU SUCK!");
return;
} else {
userGuess = readlineSync.question("Fix your answer fool! \n");
handleGuess(userGuess);
}
}
I assume your first call is handleGuess() with no parameter.
Then, your program asks the user for its first guess (withe the message "Fix your answer fool!"). If you call handleGuess() with a parameter, the following still applies.
After that, the loop will begin.
if the first answer is wrong, the console will display the message "Think [higher/lower] you fool.", and then request the second guess. Still in the first loop iteration.
Do you see where the problem is ?
If the second guess is still wrong, the console will display the second wrong message and request the third guess while still being in the second loop iteration.
Finally, If the third guess is still incorrect, the third "wrong" message will appear and your code will request a fourth guess before ending the loop and display the message "Dude...YOU SUCK!" without verifying your input.
To prevent that, you can do something like this :
function handleGuess(userGuess) {
i = 0;
do {
if(i > 0) {
if(userGuess > randomNumber) {
hint = "Think lower you fool.";
} else {
hint = "Think higher you fool.";
}
console.log(hint);
userGuess = readlineSync.question("Guess again. \n");
}
while(isNaN(userGuess)) {
userGuess = readlineSync.question("Correct you guess. \n");
}
} while(userGuess != randomNumber && i < maxGuesses);
if (userGuess == randomNumber) {
console.log(userGuess + " is CORRECT! YOU WIN!");
} else {
console.log("Dude...YOU SUCK!");
}
}
Just set the condition for your loop to be i < maxGuesses not i <= maxGuesses -1:
var maxGuesses = 3;
for (i = 0; i < maxGuesses; i++) {
console.log("Guess " + (i + 1)); // Only adding 1 here so output is 1-based
}

want to put javascript code in while loop so that when cphealth or player health is <= 0 the game stops

i am wanting to put a while loop somewhere so the games stops when either you or the computer have 0 or less health and display a message after that saying somebody won but no matter how i try or where i put them i can never seem to get a while loop to work. Please help me :)
$(document).ready(function() {
var health = 100;
var cphealth = 100;
var lightAttacks = -20;
var block = 10;
var Ties = 0;
function randomGen() {
var max = 3;
var min = 1;
var answer = Math.floor(Math.random() * (max - min + 1)) + min;
return answer;
//sets up the random number generator
}
var name = "";
var userChoice = "";
var compChoice = 99;
$("#lightAttack").click(function() {
userChoice = "lightAttack"
compChoice = randomGen();
whoWon(userChoice, compChoice);
});
$("#block").click(function() {
userChoice = "block"
compChoice = randomGen();
whoWon(userChoice, compChoice);
});
$("#heal").click(function() {
userChoice = "heal"
compChoice = randomGen();
whoWon(userChoice, compChoice);
//sets up the random number generator
});
function whoWon(user, comp) {
var winnerMessage = "ERROR";
if (user == 'lightAttack') {
if (comp == 1) { //developer says 1 = attack back
winnerMessage = "Computer attacked back";
(health = health + lightAttacks) && (cphealth = cphealth + lightAttacks)
} else if (comp == 2) { //developer says 2 = block next attack
winnerMessage = "Computer blocked your attack and reflected some damage";
health = health - 5
} else { //developer says 3 = heal and its just else 1 or 2 ot must be 3
winnerMessage = "Computer heals back part of your attack damage";
cphealth = cphealth - 10
}
}
if (user == 'block') {
if (comp == 1) { //developer says 1 = lightAttack
winnerMessage = "You blocked the computer attack and reflected some damage";
cphealth = cphealth - 5
} else if (comp == 2) { //developer says 2 = block
winnerMessage = "Nothing happened because you both blocked";
health = health + 0
} else { //developer says 3 = heal and if its not 1 or 2 ot must be 3
winnerMessage = "Computer heals 10 health";
cphealth = cphealth + 10
}
//sets up the results for if the user picks block
}
if (user == 'heal') {
if (comp == 1) { //developer says 1 = lightAttack
winnerMessage = "Computer attacked";
health = health - 10
} else if (comp == 2) { //developer says 2 = block
winnerMessage = "Computer blocked";
health = health + 10
} else { //developer says 3 = heal and if its not 1 or 2 ot must be 3
winnerMessage = "You both picked heal";
health = health + 10;
cphealth = cphealth + 10;
}
}
if (comphealth <= 0) {
alert("You Win!")
}
document.getElementById("result").innerHTML = winnerMessage;
document.getElementById("myhealth").innerHTML = health;
document.getElementById("comphealth").innerHTML = cphealth;
}
});
If you try using a while loop in Javascript for this your program will get stuck in the while loop forever. Javascript has a single thread of execution so there is no way to run your while loop in parallel with the rest of the game.
One thing you could consider doing instead is to structure your game logic in "turns". Every turn you apply changes to the game state (player moves around a bit, takes damage, deals damage, etc) and at the end of the turn you check to see if their health dropped to zero.

Very basic dice game in Javascript - trying to log 'wins' variable

I'm trying to make a very basic dice game (new to Javascript). On the page load, the 'dice' is 'rolled' three times and the results are displayed, with a message to say whether you managed to roll a 6 or not. I'm trying to put in a permanant message about how many games have been won - problem is, if you look at my code below, the variable I'm using for this 'wins' is incremented each time there is a win, but it only actually displays two values: 0 if the user just lost, and 1 if it was a win. It never gets to a higher number no matter how many times the dice is rolled. Wondering if anyone has a solution/explanation?
Code:
console.log("Dice game. You have 3 tries to roll a 6 - go");
var rolls = 0;
var wins = 0;
function rollDice() {
var dice = Math.random();
if (dice <= .17) {
dice = 1;
}
else if (dice <= .33) {
dice = 2;
}
else if (dice <= .50) {
dice = 3;
}
else if (dice <= .67) {
dice = 4;
}
else if (dice <= .84) {
dice = 5;
}
else if (dice <= 1) {
dice = 6;
}
return dice;
}
function diceGame() {
do {
var dice = rollDice();
console.log(dice);
rolls++;
if (dice === 6) {
console.log("You won!");
wins++;
if (rolls === 1) {
console.log("It took " + rolls + " try");
}
else {
console.log("It took " + rolls + " tries");
}
break;
}
}
while (rolls <= 2);
if (dice !== 6) {
console.log("You lost");
}
}
diceGame();
console.log("Times won: " + wins);
The value 1 will never be hit, because:
The Math.random() function returns a floating-point, pseudo-random
number in the range [0, 1) that is, from 0 (inclusive) up to but not
including 1 (exclusive), which you can then scale to your desired
range. The implementation selects the initial seed to the random
number generation algorithm; it cannot be chosen or reset by the user.
Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
How are you running the code? Each time it runs, it resets the wins variable to 0. You need to call the function with a button, or something so it doesn't have to refresh the code block to run a second time.
Some improvements ;)
Call continue instead of break MDN continue
Change rollDice function Random number from range
anonymous function for create namespace
// namespace for our variables
(function(){
console.log("Dice game. You have 3 tries to roll a 6 - go");
var rolls = 0;
var wins = 0;
function rollDice() {
// simple random from range ( https://stackoverflow.com/a/1527820/2746472 )
return Math.floor(Math.random()*6)+1;
}
function diceGame() {
do {
var dice = rollDice();
console.log(dice);
rolls++;
if (dice === 6) {
console.log("You won!");
wins++;
if (rolls === 1) {
console.log("It took " + rolls + " try");
} else {
console.log("It took " + rolls + " tries");
}
continue; //instead of break!
}
} while (rolls <= 2);
if (dice !== 6) {
console.log("You lost");
}
}
diceGame();
console.log("Times won: " + wins);
})();
Your rollDice function can be simplified to 1 line.
var dice = Math.floor(Math.random() * 6) + 1;
It's because you have a break if you win so it exits the loop after the first win.

Guess a number game, score counter giving incorrect result

I am making a simple 1 - 10 guess the number game with Javascript.
It can be viewed here Guessing game
To add up score i have a var score = 4 which de-increments each time the number guessed (with a for loop which is smaller than 5) incorrect. I += to var tally and display tally as score.
My problem is score always equals 0, and therefore does not add anything to tally, I am struggling to find a solution.
My javascript is:
var tally;
function play() {
var compNum = (Math.random() * 10).toFixed(0);
var score = 4;
for (var i = 0; i < 4; i++) {
if (i == 0) {
var userNum = prompt("Enter a number between 1 and 10");
} else {
if (userNum < compNum) {
userNum = prompt("Guess higher, you have " + (4 - i) + " turns left ", userNum);
} else if (userNum > compNum) {
userNum = prompt("Guess lower you have " + (4 - i) + " turns left ", userNum);
}
}
score--;
}
tally += score;
$("#score").html("score: " + tally);
if (i >= 3 && userNum != compNum) {
var again = confirm("Sorry you lost. The number was: " + compNum + " Play again?");
} else if (userNum == compNum) {
again = confirm("Well done! play again?");
i <= 5;
}
if (again) {
play();
}
if (userNum == "") {
i <= 5;
}
}
HTML:
<button onclick="play()">PLAY</button>
<div id="score"></div>
Your help is really appreciated
You should check whether the number entered by the use is equal to the random one and if that is the case exit form the for loop.
With your code the loop runs the whole 4 times,
In your loop, you need to check if the user has the right answer and exit the loop if they do.
for (var i = 0; i < 4; i++) {
if (i == 0) {
var userNum = +prompt("Enter a number between 1 and 10");
} else {
if (userNum < compNum) {
userNum = prompt("Guess higher, you have " + (4 - i) + " turns left ", userNum);
} else if (userNum > compNum) {
userNum = prompt("Guess lower you have " + (4 - i) + " turns left ", userNum);
}
}
if (userNum === compNum) {
// they guessed right, so exit the loop
break;
}
score--;
}
In addition, I'd check to see if isNaN(userNum) to check your user actually entered a number. It's up to you if you want to give them another chance if they don't.

Categories