What is the best practice when counting the number of times an action has been carried out in javascript? for example I have a prompt that asks for a number
var playerGuess = prompt("What is your guess ");
What i would like to do is after 3 attempts end the game with another prompt.
What I am having difficulty with is actually counting the number of inputs
Thanks
I have tried creating a function do count the number of times an input has been made
var guessCount = playerGuess.count;
function limit(playerGuess){
if (guessCount >= 3){
alert("game over");
} else{
alert("carry on");
}
}
totally wrong i know but having a go
Like so:
// Global var to hold number of guesses
var guessCount = 0;
// Function to get the guess
function getGuess() {
// Get a new guess
var guess = prompt('What is your guess ');
// Process guess here, eg:
if (...whatever tests you want to make...) {
// Good guess
alert('Good guess: ' + guess);
} else {
// Bad guess
guessCount += 1;
// Fail out if too many guesses have been tried
if (guessCount >= 3) {
alert('Game over');
return;
}
}
};
Cheers!
You should evaluate the answer you get each time.
If the answer is valid, take the count in another variable and when the count reaches the desired amount take no inputs.
var attempts = 0;
function ask_question(){
if(attempts > 3)
{
// you have played enough!
return;
}
else
{
var playerGuess = prompt("What is your guess ");
if(parseInt(playerGuess) != NaN && playerGuess != '')
{
attempts++;
// do whatever you would like to do with playerGuess
}
}
}
You could do this with a while loop and a variable to store the current iteration. Consider the following, which gives you three chances to guess the "secret" number:
var secretNumber = 42,
youWon = false,
i = 0;
while (i < 3) {
var playerGuess = prompt("What is your guess?");
if (playerGuess == secretNumber){
youWon = true;
break;
}
i++;
}
if (youWon) {
alert("You got it!");
} else {
alert("Sorry, you have no more tries left.");
}
This code loops over and over, incrementing i each time. It asks the question, and checks the answer. If the answer is right, it sets the youWon flag and breaks out of the loop, ending it early. Otherwise, the loop ends naturally after 3 iterations. After the loop is done, the youWon flag is checked to determine if the loop ended because the right answer was given, or if it ended because the number of tries was exhausted.
Related
I am trying to write a function that gives a user 4 choices, does what they choose and then asks them the first 4 choices again and again until they exit.
I have tried using an if/else loop inside a while loop, but that just takes the first user input and loops at that point. It also concatenates the balance when I try to add the two numbers. I assume that due to the fact that the prompt is a string and assigns a string to the variable. I am using console.log() to try and see what is happening while everything is running, but to no avail.
Sorry if this is a lengthy post and redundant.
let balance = 0;
let deposit = 0;
let withdraw = 0;
function bankFunction (banked) {
alert('Hello, how can I help you today?');
let input = prompt('Q to quit the application \nW to withdraw \nD to deposit \nB to view balance');
while (input != 'Q') {
if (input === 'W') {
withdraw = prompt("Withdraw how much?");
console.log(withdraw);
balance = balance - withdraw;
console.log(balance);
} else if (input === 'D') {
deposit = prompt("Deposit how much?");
console.log(deposit);
balance = balance + withdraw;
console.log(balance);
} else {
alert("done");
break;
}
}
}
If you want to continuously prompt the user for inputs, then the prompt function should be inside your loop too. The essential pseudo code is: "While the input is not "Q", continue to prompt for a user choice".
Implementation:
let input = "A" // Initial input to get the loop working
while (input !== "Q") {
// Get actual user input
input = prompt("Choose Q or W or D or B");
if (input === "W") {
// Withdraw logic
}
else if (input === "D") {
// Deposit logic
} else if (input === "B") {
// ...
}
}
Note that there is a bit of a little gimmick here: I needed to have an initial input ("A") to get the first round of the loop working - since in the first round of the loop, user input has not been received yet. Once it get past that initial first round, the input variable is being continuously re-assigned through the user prompt, and the loop will exactly how the pseudo-code described it.
If you don't like that gimmick, there is another way, called the While-True-Break loop. The essential idea is that: The loop will automatically run forever, until you explicitly stop it (via break statement)
let input;
while (true) {
input = prompt("Choose Q or W or B or D");
if (input === "Q") {
// Stop the program loop
break;
} else if (input === "W") {
// ...
} else if ...
}
Today, i start my very first game application with javascripp for studing purpuse. It's a gambit game that you set the bet, chose Odd or Even then Call. It's just a simply game but i get the problem with sumerize the score.
The idea is: I create a callback function to proceed the data, it took value of odd button and even button then comparing to a random number of a variable, then if the result is win, your money will be raised otherwise it's reduced. Here is my js code:
var even = document.getElementById('even')
var odd = document.getElementById('odd')
var call = document.getElementById('submit_btn')
var result = document.getElementById('result')
var score = document.getElementById('capital')
function process(choice,money,capital=1000) {
console.log(capital)
call.addEventListener('click',function () {
let luck = Math.floor(Math.random()*2)
if (choice == luck) {
capital += parseInt(money) ;
result.innerHTML = 'win+ '+money;
} else {
capital -= money;
result.innerHTML = 'lose- '+money;
}
score.innerHTML = 'Capital: '+capital
console.log(capital)
if(capital<1){
alert('Game Over')
}
})
}
even.addEventListener('click',function () {
let bet = parseInt(document.getElementById('bets').value)
if(Number.isInteger(bet) == true){
process(1,bet)
console.log(bet)
}else{
alert('You must bet first!!!')
}
})
odd.addEventListener('click',function () {
let bet = parseInt(document.getElementById('bets').value)
if(Number.isInteger(bet) == true){
process(0,bet)
console.log(bet)
}else{
alert('You must bet first!!!')
}
})
here is my application.
My problem is it works correctly when I just bet and call but when I change the bet option the money will be reset. How could I save the result then use it when another even occur. Thank you very much
In process(choice,money,capital=1000) you defined a default value 1000 to capital.
Therefore every time you click odd / even, it call process(0,bet) / process(1,bet), the capital reset to 1000. Because you didn't provide any value as third parameter.
I notice you add event listener in every process function, it may cause memory issue. You just need to bind once in this situation.
I will probably write like this:
// use IIFE to prevent pollution of global variable
(function(){
var even = document.getElementById('even')
var odd = document.getElementById('odd')
var call = document.getElementById('submit_btn')
var result = document.getElementById('result')
var score = document.getElementById('capital')
var bet = document.getElementById('bets');
// define variables here to keep their value.
var capital = 1000;
var money = NaN;
var choice = NaN;
function process(){
if(Number.isNaN(money) && Number.isNaN(choice)) return;
let luck = Math.floor(Math.random()*2)
if (choice == luck) {
capital += parseInt(money) ;
result.innerHTML = 'win+ '+money;
} else {
capital -= money;
result.innerHTML = 'lose- '+money;
}
score.innerHTML = 'Capital: '+capital
console.log(capital)
if(capital<1){
alert('Game Over')
}
}
function chageBet(choice){
if(Number.isInteger(parseInt(bet.value)) == true){
choice = choice;
money = bet.value;
console.log(bet)
} else{
alert('You must bet first!!!')
}
}
// just bind event once
call.addEventListener('click', process)
even.addEventListener('click', chageBet.bind(null, 1))
odd.addEventListener('click', chageBet.bind(null, 0))
})();
And maybe it's better to provide a reset function to reset the capital/money/choice variables.
Update:
Try to explain how variables change their values.
Round 1
choice is NaN; money is NaN; capital is 1000;
User set bet to 10
Click even button
execute changeBet(1)
choice become 1; money become 10;
Click call button
execute process()
(assume)vwin -> capital become 1000 + 10 = 1010
Round 2
choice is 1; money is 10; capital is 1010
User set bet to 200
Click odd button
execute changeBet(0)
choice become 0; money become 200;
Click call button
execute process()
lose -> capital become 1010 - 200 = 810
Every click event on button will execute the function that assigned in their addEventListener, and function changes the values of variables.
Please let me know if I am not clear enough.
My game here is a guessing game, which counts the number of guess and does not include any repeated guesses.
I am trying to pass the variable tries from function attempts to function tries but it will not work. The count remains 0, but when I pass sameGuess.length it work, why is this?
let random = Math.round(Math.random()*100);
let guess = false;
let sameGuess = []
let tries = sameGuess.length;
function game(){
while (guess === false){
let myGuess = prompt('Guess a number between 0-100:');
numCheck(myGuess);
if (myGuess == random){
guess = true;
repeats(myGuess, sameGuess);
attempts(tries, sameGuess);
}else if (myGuess < random){
repeats(myGuess, sameGuess);
alert('Your number was too small, try again!');
guess = false;
}else if (myGuess > random){
repeats(myGuess, sameGuess);
alert('Your answer was too big, try again!');
guess = false;
}
}
}
function attempts(tries, sameGuess){
if (sameGuess.length == 1){
alert('Well done, you got it frist try!');
document.write("<h1>GUESSING GAME</h1><p>Thank you for playing the Guessing Game <br> Created by Jonathan Fox</p>");
}else if (sameGuess.length <= 15){
alert('You took ' + sameGuess.length + ' tries');
alert('Well done, you didn\'t take too many tries!');
document.write("<h1>GUESSING GAME</h1><p>Thank you for playing the Guessing Game <br> Created by Jonathan Fox</p>");
}else if (sameGuess.length >=16){
alert('You took ' + sameGuess.length + ' tries');
alert('You got it, but lets see less tries next time!');
document.write("<h1>GUESSING GAME</h1><p>Thank you for playing the Guessing Game <br> Created by Jonathan Fox</p>");
}
}
function repeats(myGuess, sameGuess){
if ((sameGuess.indexOf(myGuess)) == -1){
(sameGuess.push(myGuess));
}else alert('You have already guessed that number! - Dont worry, i haven\'t counted it!');
}
function numCheck(myGuess){
if (isNaN(myGuess)){
alert('Enter a number, don\'t try and be sneaky!');
}
}
game ();
When you access array.length, that value is copied, meaning it won't update even after you add a value to the array:
var array = [];
var length = array.length;
console.log(length); // 0
array.push('Some value');
console.log(length); // Still 0, since it was copied, it is _not_ a reference to the live value
console.log(array.length); // 1, this is a live reference to the length of the array
As it stands now, your code works fine, although it looks like you can remove the tries aspect of it and use the sameGuess.length directly, as you are now.
See this post for more discussion on Pass by Reference or Pass by Value.
You should put tries = sameGuess.length; inside of your while!
I am working on a course assignment where random questions are asked with 4 possible answers each. (This all runs in the console only, working with alert()).
My issue is with the score of the user. It is supposed to increment by 1 with each correct iteration and I attempted resolving this using a function, but the function returns NaN and I simply can't see the problem. Please have a look.
//Start by creating objects to contain the questions and answers
var Questions = function(question, answerq1, answerq2, answerq3, answerq4) {
this.question = question;
this.answerq1 = answerq1;
this.answerq2 = answerq2;
this.answerq3 = answerq3;
this.answerq4 = answerq4;
};
//create the questions
var question1 = new Questions('What is the fastest land animal in the world?', 'a dog', 'deer', 'cheetah', 'leopard');
//create a function that displays the question and present the possible answers as multiple option
function displayQandA() {
var test = 'question' + 1;
console.log(test);
if (test === 'question1') {
console.log(question1.question);
var q10a = [question1.answerq1, question1.answerq2, question1.answerq3, question1.answerq4];
//correct answer in array
var correct = q10a[2];
for (var i = 0; i < q10a.length; i++) {
console.log([i] + ' ' + q10a[i]);
}
captureAnswer(q10a.indexOf(correct));
} else {
displayQandA();
}
};
displayQandA();
//to hold score accumulation
var s = 0;
//function to increase score per correct answer
function incrementScore() {
s++;
return s;
};
//function to prompt user to enter/capture the answer & check whether its correct or not
function captureAnswer(el) { //el is the parameter from the random question function
var promptAnswer = prompt('Capture your answer here');
if (promptAnswer === 'exit') {
console.log('You entered ' + promptAnswer);
console.log('Bye, thanks for playing');
} else if (promptAnswer == el) {
console.log('You entered ' + promptAnswer);
console.log('Your answer is correct!');
incrementScore();
console.log('Your score is ' + s);
displayQandA(); //calling random question function
} else if (promptAnswer !== el) {
console.log('You entered ' + promptAnswer);
console.log('Your answer is wrong!');
console.log('Your score remains ' + s);
displayQandA(); //calling random question function
}
};
This is because you call displayQandA before assigning s = 0. The function already reads s (yielding undefined) and increments it (yielding NaN). var s; is hoisted up, so it’ll start as undefined. s = 0; actually won’t be executed until after you type "exit" in the prompt. Simply move var s = 0; to the top of your code.
Use parseInt() to typecast your variable, the comparison operator (!==) checks for either type or value difference.
=+ is not the same as +=. First is x = +y and another is x = x + y.
+x is a shortcut for Number(x) literally converting the variable to number. If the operation can't be performed, NaN is returned.
+= acts like string concatenation when one of the parts (left or right) has a string type.
I am learning JavaScript through Codecademy, but I have an issue. The code below is supposed to search through the text variable for my name in the myName variable and then push all of the individual letters to the hits array. The code that I have written is not correct but Codecademy says that it is correct and is going to let me move on in the lesson.
I have been trying to solve the issue that I am having with no luck. The problem is that when I run the hits.push(text); line it will output the entire variable but I have tried hits.push(text[i]); and get undefined for the result. Can someone please help me understand where I have made the mistake?
/*jshint multistr:true */
var text = "XsddfasASSFABrandonSFsdfdasBrandonsddfadfaBrandon";
var myName = "Brandon";
var hits = [];
for (i=0; i<=text.length;i++){
if (text[i]===myName[i]){
for(var x=i; x<i+myName.length;x++){
hits.push(text);
}
}
}
if (hits.length===0){
console.log("Your name wasn't found!");
} else {
console.log(hits);
}
The best way I can think to explain your mistake is simply by walking through a bit of the logic of what you have written.
for (i=0; i<=text.length;i++){
Your for loop will iterate i for as many characters as there are in your text variable, so: 49 times.
if (text[i]===myName[i]){
The first run through your for loop, where i=0, you are checking to see if text[0] is strictly equal to myName[0]. text[0] = X and myName[0] = B. The strictly equals condition is not met, so the loop proceeds to increment i repeat: text[1] = s and myName[1] = r. This continues 47 more times, and the condition is never met. myName[i] is undefined after the first 7 loops.
Normally you would do this kind of thing using indexOf, match, search, substr or substring, which are all string methods.
However for the purpose of this exercise you can do:
var text = "XsddfasASSFABrandonSFsdfdasBrandonsddfadfaBrandon";
var myName = "Brandon";
var hits = [],
namePosition = 0;
for (var i = 0; i < text.length; i++) {
if (text[i] === myName[namePosition]) {
hits.push(text[i]);
namePosition ++;
if (hits.length === myName.length) {
break;
}
}
else {
namePosition = 0;
hits = [];
}
}
if (hits.length === 0) {
console.log("Your name wasn't found!");
} else {
console.log(hits);
}
(See it working at http://jsfiddle.net/wCWxr/1/). The problems with your original code include:
you try to compare text[i] to myName[i] but the indices of the two strings won't match up.
you try to push the entire string text into hits instead of one character at a time
your logic doesn't deal with the possibility that the beginning but not the end of myName is in text, e.g. if text was aerwerBrasdfsgars
My suggestion fixes this by recording (with namePosition) what position we are currently at within the string myName, and incrementing that when we find a character in text that matches the relevant character in myName. If the characters do not match then it's not a true hit, so we reset hits = [] and namePosition = 0. If the characters all match then hits eventually reaches the length of myName and so we break out of the loop.
If you are trying to find if myName is in text here is what you do:
RegExp:
var pattern = new RegExp(myName);
if (pattern.test(text)){
console.log(myName);
}else {
console.log("Your name wasn't found!");
}
indexOf:
if (text.indexOf(myName) != -1){
console.log(myName);
}else {
console.log("Your name wasn't found!");
}
if (text[i]===myName[i]){
this line should create an error, because myName[i] is not the first letter of myName.
if (text[i]===myName[0]){
Change to this line should work.