I am an extremely new (read as three hours old) amateur with JavaScript so I have an extremely low level question. However I thought it would offer a great chance to explore this stackoverflow community. I have run through approx 50% of the CodeAcademy JavaScript intro and just finished the section on while and for loops. On the free practice section I decided to try and write a program to simulate a coin flip 1,000 times and report the results to the user. The program seems to run OK but on line 9 I am seeing a hint that syntax is wrong as I introduce an if/else statement. Also I now see that if you answer "no" it runs anyways. What is wrong with the syntax and what other general feedback do you have on my very first independent program? Thanks!
var userReady = prompt("Are you ready for me to flip a coin one thousand times?");
var flipCount = 0;
var heads = 0;
var tails = 0;
if (userReady = "yes" || "Yes") {
flipCount++;
while (flipCount <= 1000) {
var coinFace = Math.floor(Math.random() * 2);
if (coinFace === 0) {
heads++;
flipCount++;
} else {
tails++;
flipCount++;
}
}
} else {
confirm("Ok we'll try again in a second.");
var userReady = prompt("Are you ready now?");
}
confirm("num of heads" + " " + heads);
confirm("num of tails" + " " + tails);
var userReady = prompt("Are you ready for me to flip a coin one thousand times?");
var flipCount = 0;
var heads = 0;
var tails = 0;
if (userReady = "yes" || "Yes") {
flipCount++;
while (flipCount <= 1000) {
var coinFace = Math.floor(Math.random() * 2);
if (coinFace === 0) {
heads++;
flipCount++;
} else {
tails++;
flipCount++;
}
}
} else {
confirm("Ok we'll try again in a second.");
var userReady = prompt("Are you ready now?");
}
confirm("num of heads" + " " + heads);
confirm("num of tails" + " " + tails);
This line:
if (userReady = "yes" || "Yes") {
does not do what you expect it to. First, you cannot use = to compare values (it means assignment in Javascript). So you can use ===. Second, the || joins two independent conditions, not values. So you can write:
if (userReady === "yes" || userReady === "Yes") {
Additionally, you can cover the case where the user types something like YES or yEs by normalising the case of the user input before comparison:
if (userReady.toLowerCase() === "yes") {
Your if statement only looks for boolean statements (of which "Yes" is not one). Also, = is the assignment operator, whereas == is the comparison operator. Changing your if statement line to the following will solve the problem.
if (userReady == "yes" || userReady == "Yes") {
I made a few changes to the code:
1. Added a default answer of yes
2. Changed the while loop to a for loop (in your code you can put the flipCount directly after the else statement)
3. Changed the confirm to alert
4. Made the number of heads and tails in one alert
var userReady = prompt("Would you like to run a coin simulator?" + "\n"
+ "Answer yes or no:","Yes");
if(userReady.toLowerCase() === "yes")
{
var heads = 0, tails = 0;
for (var flipCount = 0; flipCount < 1000; flipCount++)
{
var coinFace = Math.floor(Math.random() * 2);
if (coinFace === 0)
{
heads++;
}
else
{
tails++;
}
}
alert("Number of heads: " + heads + "\n"
+ "Number of tails: " + tails);
}
else
{
// statement goes here if the user doesn't want to play
//alert("You're no fun!");
}
When you compare the values you should use == instead of =, also for or operation its not correct, you need to do something like :
if (userReady == "yes" || userReady == "Yes")
Related
So my alternative version of this code is in Java, the logic is fairly similar although in JavaScript the userinput is repeated infinitely rather than carrying until the user loses. This is my working Java code for reference:
int stop =0;
Scanner scan = new Scanner(System.in);
Random rand = new Random();
do {
int card;
int upcommingcard;
String userinput;
card= rand.nextInt(13)+1;
System.out.println("Card is "+card);
System.out.println("Higher or Lower?");
userinput = scan.next();
upcommingcard = rand.nextInt(13)+1;
if(!userinput.equalsIgnoreCase("H")&&(!userinput.equalsIgnoreCase("L"))){
System.out.println("Invalid Input ");
}
else if((userinput.equalsIgnoreCase("H")) && (upcommingcard > card)){
System.out.println("Correct!");
}
else if(userinput.equalsIgnoreCase("L") && upcommingcard < card){
System.out.println("Correct!l ");
}
else {
System.out.println("You lost it was " + upcommingcard);
stop=1;
}
}while (stop != 1);
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JavaScript - Not working
var max=13;
var min=1;
var stop=0;
var card = Math.floor((Math.random() * (13 - 1) + 1));
var userinput = prompt("Card is "+card+"... Higher or lower?");
var upcommingcard = Math.floor((Math.random() * (13 - 1) + 1));
do{
if((userinput !="H")&&(userinput !="L")){
console.log("Invalid input");
}
else if((userinput ="H")&&(upcommingcard > card)){
console.log("Correct!");
}
else if((userinput ="L")&&(upcommingcard < card)){
console.log("Correct!");
}
else{
console.log("You lost, it was "+ upcommingcard);
stop=1;
}
}
while(stop !=1);
Just to mention also that it registers that the user's input is correct although it fails to continue and just keeps on spitting out the same output until the browser crashes.
EDIT: Thanks for the responses! the loop works perfectly now, my only issue is that the logic is a bit flawed since sometimes I Input 'L' for 8 and upcoming int is 10.. Dispite this I get the Incorrect response.
It's not that your console isn't updating, it's that you never exit your loop if the input is incorrect, and you never offer them the option to try again.
Thus if they are incorrect, the loop will never end, the console won't be updated, and they can't retry.
I would recommend changing the code to the following, to alert the user to try again.
var max = 13;
var min = 1;
var stop = 0;
var card = Math.floor((Math.random() * (13 - 1) + 1));
var userinput = prompt("Card is " + card + "... Higher or lower?");
var upcommingcard = Math.floor((Math.random() * (13 - 1) + 1));
do {
if ((userinput != "H") && (userinput != "L")) {
console.log("Invalid input");
alert("Invalid input!");
userinput = prompt("Card is " + card + "... Higher or lower?");
} else if ((userinput == "H") && (upcommingcard > card)) {
console.log("Correct!");
alert("Correct!");
stop = 1;
} else if ((userinput == "L") && (upcommingcard < card)) {
console.log("Correct!");
alert("Correct!");
stop = 1;
} else {
console.log("You lost, it was " + upcommingcard);
alert("You lost, it was " + upcommingcard);
stop = 1;
}
}
while (stop != 1);
There are some points I want to make on this:
Your Java and Javascript code logic differs. You had the variables and input reads inside do while in Java but outside in Javascript.
As your prompt right now is outside the loop, it will keep having the same input value everytime and not asking for another one, and will carry on until it's a wrong guess, or forever if it's an invalid input. And the next point worsens your problem:
Your if comparison operators are invalid. What you did, as mentioned in the comments, is a data assignment to userinput and will always return correct
That being said, I corrected it below while adding alert popups instead of console.log only:
var stop = 0;
do {
var card = Math.floor((Math.random() * (13 - 1) + 1));
var userinput = prompt("Card is " + card + "... Higher or lower?");
var upcommingcard = Math.floor((Math.random() * (13 - 1) + 1));
if ((userinput != "H") && (userinput != "L")) {
console.log("Invalid input");
alert("Invalid input");
stop = 1; //Currently stopping if having invalid input, you can remove this later
} else if ((userinput == "H") && (upcommingcard > card)) {
//Note the '==' above, and also the next one for comparing equal values
console.log("Correct!");
alert("Correct");
} else if ((userinput == "L") && (upcommingcard < card)) {
console.log("Correct!");
alert("Correct!");
} else {
console.log("You lost, it was " + upcommingcard);
alert("You lost, it was " + upcommingcard);
stop = 1;
}
}
while (stop != 1);
Now, do compare the JS snippet above with your working Java code you've posted. If you compare again with your JS code, you should be able see what I meant by having different logic.
I am a novice programmer. I have started teaching myself JavaScript. I made a rudimentary battleship game. Problem is that if the user enters the same location(if it's a hit) 3 times the battleship sinks. To avoid that I added an array "userchoices" to record user inputs and then cross-check by iterating through a for-loop. the for loop, in turn, contains an If statement that should alert the user if they have already fired at the location before. Problem is that the if statement gets executed each time.
Please review the code below and suggest corrections. Thank you.
var randomloc = Math.floor(Math.random() * 5);
var location1 = randomloc;
var location2 = location1 + 1;
var location3 = location2 + 1;
var guess;
var userchoices = [];
var hits = 0;
var guesses = 0;
var issunk = false;
function battleship() {
while(issunk == false)
{
guess = prompt("Ready,Aim,Fire! (Enter a number 0-6):");
console.log("users input = " + guess);
if (guess == null)
break;
if (guess < 0 || guess > 6){
alert("Please enter a valid cell number. No of guesses has been
incremented.")
}
else{
guesses++;
userchoices[guesses] = guess;
console.log("users choices = " + userchoices);
}
/* for(var i = 0; i <= guesses; i++)
{
if(userchoices[guesses] = guess)
console.log("you have already fired at this location");
} */
if (guess == location1 || guess == location2 || guess == location3){
alert("Enemy Battleship HIT");
hits = hits + 1;
if (hits == 3){
issunk = true;
alert("Enemy battleship sunk")
}
}
else{
alert("You Missed");
}
}
if (issunk){var stats = "you took " + guesses + " guesses to sink the battleship. You accuracy was " + (3/guesses);alert(stats);}
else{alert("You Failed!"); issunk = false;}
}
This is the part that is causing an error
for(var i = 0; i<=guesses; i++)
{
if (userchoices[guesses] = guess){
console.log("you have fired at this location already");
}}
The if statement should execute only when the user enters a grid number that he already has fire upon, no matter hit or miss.
You are accessing the array by the wrong index. Try userchoices[i] instead of userchoices[guesses]. Also equality comparison is performed using 2 equal signs ==:
for(var i = 0; i<=guesses; i++)
{
if (userchoices[i] == guess){
console.log("you have fired at this location already");
}
}
This can also be expressed as:
if (userchoices.includes(guess)){
console.log("you have fired at this location already");
}
Also guesses should be incremented after adding the first value:
else{
userchoices[guesses] = guess;
guesses++;
console.log("users choices = " + userchoices);
}
EDIT
There is a logic error here as you are checking the array for the element after inserting it into the array, perform the check in the else statement before inserting the element. Combining all of the above:
else if (userchoices.includes(guess)){
console.log("you have fired at this location already");
} else {
userchoices[guesses] = guess;
guesses++;
console.log("users choices = " + userchoices);
}
After much-needed help from Avin Kavish and bit of tinkering of my own, I can now present an answer to my own question for future viewers.
Edit: More like my final program
function battleship()
{
var guess; //Stores user's guess
var userchoices = []; //records user's guess until ship is sunk or user chickens out
var issunk = false; //status of ship
var hits = 0; //number of hits
var guesses = 0; //number of guesses
var randomloc = Math.floor(Math.random() * 5); //Random Number Generator
var location1 = randomloc;
var location2 = location1 + 1;
var location3 = location2 + 1;
while(issunk == false)
{
guess = prompt("Ready,Aim,Fire! (Enter a number 0-6):");
console.log("users input = " + guess);
if(guess == null) // If users presses 'OK' without entering anything or the 'Cancel' this would break the loop.
break;
if (guess < 0 || guess > 6){
alert("Please enter a valid cell number. No of guesses has been incremented.");
guesses++; //Gotta punish the player.
}
else if (userchoices.includes(guess) == false) /*instead of doing what i did yo u
can change this line to "else if (userchoices.includes(guess)) and then put the
following oprations in its else clause. */
{
guesses++;
userchoices[guesses] = guess;
console.log("User choices = " + userchoices);
if (guess == location1 || guess == location2 || guess == location3)
{
alert("Enemy Battleship HIT");
hits = hits + 1;
if (hits == 3)
{
issunk = true;
alert("Enemy battleship sunk");
}
}
else
{
alert("You Missed");
}
}
else
{
alert("you have already fired at this location.")
}
if (issunk) //writing issunk == true is overkill
{
var stats = "you took " + guesses + " guesses to sink the battleship. You
accuracy was " + (3/guesses);
alert(stats);
}
}
if(guess == null && issunk == false)
console.log("You failed"); //Humiliate the user for chickening out.
userchoices = []; //Empties the array so user can start over again without relaoding the page
issunk = false; //sets issunk to false for a new game
var randomloc = Math.floor(Math.random() * 5); //creates new random numbers for ship coordinates
}
2D 7X7 version coming soon. Will post here.
This code isn't working: Help! It is only displaying as "no answers left", not anything else and that is displaying that I have only 0 attempts left. I am new to Javascript and need some support, I think the "for" loop isn't working. I can only try out this code once, then the page crashes.
function mathCheck() {
var inputValues1 = document.mathGuesser.mGuesser.value;
var attempts;
for (attempts = 3; attempts >= 0; ) {
if (inputValues1 === 'y = 2x - 3' || inputValues1 === 'y=2x-3') {
document.getElementById("answer").style.color = "Green";
document.getElementById("answer").innerHTML = "<span>" + "Correct" + "</span>";
}
else if (inputValues1 === ' ' || inputValues1 === '') {
document.getElementById("answer").style.color = "Black";
document.getElementById("answer").innerHTML = "<span>" + "Please enter text" + "</span>";
}
else {
document.getElementById("answer").style.color = "Red";
document.getElementById("answer").innerHTML = "<span>" + "Incorrect" + "</span>";
document.getElementById("attempts").innerHTML = attempts;
attempts--;
}
}
document.getElementById("answer").style.color = "Black";
document.getElementById("answer").innerHTML = "No attempts left";
}
In general the algorithm you came up with is working, e.g.:
for (attempts = 3; attempts >= 0; ) {
const answer = prompt("Answer to live?");
if(answer === "42"){
alert("correct!");
} else {
attempts--;
alert(attempts + " attempts left");
}
}
alert("you lost :(");
But that scenario does work because weve got synchronous code. Waiting for the user to enter the right answer is not synchronous but rather asynchronous. So in your case it will check the answer three times before the user is even to able to enter the right answer and in case the right answer was entered the loop runs forever so fast, that it freezes the browser. To solve this you need a state (remaining) and handle the different cases on every click:
var attenpts = 3;
function mathCheck() {
if(attempts <= 0)
return answer("Your tries are up!", "red");
var inputValues1 = document.mathGuesser.mGuesser.value;
if (inputValues1 === 'y = 2x - 3' || inputValues1 === 'y=2x-3') {
answer("Correct", "green");
} else if (inputValues1 === ' ' || inputValues1 === '') {
answer("Please enter your answer!", "black");
} else {
answer("Incorrect!", "red");
document.getElementById("attempts").innerHTML = attempts;
attempts--;
}
}
function answer(text, color){
const el = document.getElementById("answer");
el.innerHTML = "<span>" + text + "</span>";
el.style.color = color;
}
I don't know what you're trying to do, you should specify what the function aims to do in your question, and provide details of the issue, however this is the format of a For loop:
for(var foo = 0; foo < 10; foo++)
So your for loop should look like so:
for (attempts = 3; attempts >= 0; attempts++)
This makes "attempts" increment by exactly one on each iteration of the loop.
Note that the last part is up to you, since your variable starts at 3, and loops while greater than or equal to 0, I'm going to assume you want to decrement, so you could use: attemps--, attempts-=1..
I'm a new programmer learning HTML/CSS/Javascript, and was fiddling around with it until I came across a bug. I was making the computer guess my number (0-5), but then realized if I put in a number higher than 5, the website just crashes. Is there any way I can make it so that if the user puts in a number higher than 5 it will just delete it automatically? Or is that not Javascript. Thanks in advance :)
document.getElementById("guess").onclick=function() {
var gotit=false;
var guesses=1;
var x;
while(gotit==false) {
x=Math.random();
x=6*x;
x=Math.floor(x);
if(document.getElementById("myNumber").value==x) {
gotit=true;
} else {
guesses++;
}
}
alert("Got it! It was a " + x + ". It only took me " + guesses + " guesses!");
}
Try this :
document.getElementById("guess").onclick=function() {
if(document.getElementById("myNumber").value > 5) {
document.getElementById("myNumber").value = "";
alert("Please provide a number that is with in 0 to 5");
} else {
var gotit=false;
var guesses=1;
var x;
while(gotit==false) {
x=Math.random();
x=6*x;
x=Math.floor(x);
if(document.getElementById("myNumber").value==x) {
gotit=true;
} else {
guesses++;
}
}
alert("Got it! It was a " + x + ". It only took me " + guesses + " guesses!");
}
Than define a onchange function to check length:
document.getElementById("myNumber").onchange = function (ev){
try{
var target = document.getElementById("myNumber");
if(parseInt(target.value) > x) { // can throw exception, when given a non number
target.value="";
}
} catch(ex) {
alert('Not a number');
}
};
IMPORTANT:
You have a greater problem here: You are generating a random number, and then comparing it to input( that does not change). This is an infinite loop. Because this is a random operation, and you can hit same number more than once.
You need to generate your number first (before click event on 'guess' button), before clicking on quess button. Like so:
var luckyNumber = x;
var guesses=1;
document.getElementById("start").onclick=function(){ //init counters once
guesses=0;
x=Math.floor(Math.random()*6);
gotit = false;
}
document.getElementById("guess").onclick=function() { // guess as many times as you want
if(document.getElementById("myNumber").value==x) {
gotit=true;
}
guesses++;
if(gotit){
alert("Got it! It was a " + x + ". It only took me " + guesses + " guesses!");
}
}
But if you want to computer to quess your number, than you need to limit number of guesses (add a counter), or it will hang eventualy.
I took this as a little challenge and just went ahead and re-did your little game. Hope this helps.
Demo here
(function (guess, tryy, message) {
var comp = function () {
return Math.floor(Math.random() * 6)
};
var number = comp();
var count = 0;
var test = function () {
var val = guess.value;
if (!Number.isNaN(val) && val >= 0 && val <= 5) {
switch (true) {
case val > number:
message.innerHTML = 'Your guess was too high!';
count++;
break;
case val < number:
message.innerHTML = 'Your guess was too low!';
count++;
break;
case val == number:
count++;
message.innerHTML = 'Congratulations you found the number! It took you ' + count + ' guesses';
//Reseting game here
setTimeout(function(){
count = 0;
number = comp();
guess.value = '';
message.innerHTML = 'Your game has been reset';
}, 2000);
break;
};
}
};
tryy.onclick = test;
guess.onkeyup = function (e) {
if (e.keyCode == 13) {
test();
}
}
})(document.getElementById('guess'), document.getElementById('tryy'), document.getElementById('message'));
In the code below, when I set the userDoor variable to the prompted user input, the user input attaches to the variable. I know this because the value shows up in the console.log statement just below the variable declaration.
However, the variables revealDoor and offerDoor, which are set based on the userInput variable, act wonky in ways that suggest the variable didn't "catch" the value. (Wonky: easier to demonstrate than explain. please run the code below. UserDoor, revealDoor, and offerDoor should all be different numbers in the range of 1-3. Some of the time, revealDoor === userDoor. This should never happen. ).
Interestingly, the program works fine when I set userDoor directly to an integer--see commented debug line.
Why would the userInput variable show the right value in the console but not seem to catch in the rest of the program?
(This program, by the way, is meant to illustrate the monty hall paradox
alert("There are 3 doors. Behind two of them are DEATH and DOOM. Behind the other is a BIG TASTY SAUSAGE.");
var yWin = 0;
var yLoss = 0;
var nWin = 0;
var nLoss = 0;
while(true){ //noprotect
var userDoor = prompt("choose door: 1, 2, or 3");
//var userDoor = 1 //debug
console.log('UD: ' + userDoor);
var prizeDoor = randomRange(1,3);
console.log('PD: ' + prizeDoor);
var revealDoor = (function(){
var revealDoor = prizeDoor;
if (prizeDoor === userDoor) {
while (revealDoor === prizeDoor) {
revealDoor = randomRange(1,3);
}
return revealDoor;
}
else {
while (revealDoor === prizeDoor || revealDoor === userDoor){
revealDoor = randomRange(1,3);
}
return revealDoor;
}
})();
console.log('RD: ' + revealDoor);
var offerDoor = (function(){
var offerDoor = prizeDoor;
while(offerDoor === revealDoor || offerDoor === userDoor){
offerDoor = randomRange(1,3);
}
return offerDoor;
})();
console.log('OD: ' + offerDoor);
var choice = prompt("You chose door " + userDoor + ". Behind door " + revealDoor + ", I reveal DEATH AND DOOM. I would like to offer you the chance to change your choice to " + offerDoor + ". Do you accept--y/n?");
if(choice === "y"){
userDoor = offerDoor;
}
var result = (function(){
var result;
if(userDoor === prizeDoor){
alert("YOU FOUND THE PRIZE!");
result = 'w';
}
else {
alert("You chose DEATH AND DOOM!");
result = 'l';
}
return result;
})();
//Analytics:
switch(result){
case 'w':
if(choice === 'y'){
yWin++;
}
else {
nWin++;
}
break;
case 'l':
if(choice === 'y'){
yLoss++;
}
else {
nLoss++;
}
break;
}
var done = prompt("Are you Done? y/n");
if(done === "y"){
break;
}
}
function randomRange(min, max) {
return Math.floor(Math.random () * (max - min +1)) + 1;
}
var totalSamples = yWin + nWin + yLoss + nLoss;
var yChoices = yWin + yLoss;
var nChoices = nWin + nLoss;
console.log('With a sample set of ' + totalSamples);
console.log('You chose to change ' + (yChoices/nChoices * 100) + '% of the time.');
console.log('When you\'ve chosen to change, you\'ve won ' + (yWin/yChoices * 100) + '% of the time.');
console.log('When you\'ve chosen to stay, you\'ve won ' + (nWin/nChoices * 100) + '% of the time.');
var userDoor = prompt("choose door: 1,2, or 3")) * 1
Its better 2 use radio button for this
The problem is that prompt() returns a string. Which means any '===' comparisons are returning undefined. I need to convert the returned string to a number using Number().
var userDoor = Number(prompt("choose door: 1,2, or 3"))
Use
var done = confirm("Are you Done? y/n");
if (done) break;
Instead of d prompt confirmation