I need an if (X is not "a","b" or "c") code [duplicate] - javascript

This question already has answers here:
Javascript If Condition with multiple OR and AND
(7 answers)
Closed 8 years ago.
I'm currently in the process of learning to do Javascript, with the help of the ever so useful website www.codecademy.com. I've recently managed to make a simple Rock, Paper, Scissors game, and I've decided to try and improve on it.
The basic idea is that the script prompts for an input, and if it is "Rock", "Paper", or "Scissors", then it randomises a response, and so forth.
I'm currently trying to add a system that makes it so that if the user types anything other than "Rock", "Paper" or "Scissors" in the prompt window, they get an error and get asked to answer again. Is there an if statement or anything similar that will allow me to do this?
Basically
if(userInput isNot "Rock","Paper" or "Scissors"){
prompt again;
} else {
continue;
}
Sorry if I'm incompetent, I'm new to this.
Thanks for your help.

You could simply do check each valid input like this:
if(!(userInput == "Rock" || userInput == "Paper" || userInput == "Scissors")) {
...
}
Which, by De Morgan's Law is equivalent to:
if(userInput != "Rock" && userInput != "Paper" && userInput != "Scissors") {
...
}
Or could store the valid inputs in an array and check to see if userInput is in that array:
var validInputs = [ "Rock", "Paper", "Scissors" ];
if(validInputs.indexOf(userInput) == -1) {
...
}
Note that .indexOf is not supported by some older browsers. See ECMAScript 5 compatibility table. If you happen to be using jQuery you can use inArray (many other JavaScript toolkits have a similar feature):
var validInputs = [ "Rock", "Paper", "Scissors" ];
if($.inArray(validInputs, userInput)) {
...
}

Basically:
if(userInput != "Rock" && userInput != "Paper" && userInput != "Scissors") {
.....
} else {
.....
}

Create an array and test to see if the answer exists in the array.
var ans = ["Rock","Paper","Scissors"];
if(ans.indexOf(userInput) == -1) {
// prompt again to user
}
else {
// continue...
}

Related

How t match a variable captured via document.onkeyup against an array index in javascript?

I am building a Rock Paper Scissors game. what I am trying to do is capture the user input via document.onkeyup event, then compare it to an array of valid choices. If user choice is mataches any index within that array, an alert should show up confirming user choice. If not, an alert should show requesting a valid entry.
The problem is, JavaScript engine seems unable to capture the userChoice part regardless of what I do, unless it is a specifically defined string such as: var userChoice = "r". Here is the code below
document.onkeyup = function (event) {
var userChoice = (event.key);
}
var validChoices = ["r" , "p" , "s"];
var choiceIsValid = false;
for (var i=0; i < validChoices.length; i++) {
if(validChoices[i] === userChoice) {
choiceIsValid = true;
}
}
if(choiceIsValid) {
alert("Your choice is " + userChoice);
} else {
alert("Please make a valid choice");
}
When the user presses a key, your code stores it in the userChoice variable but doesn't actually do anything with the stored value, since that's all you have included inside the keyup handler function.
To obtain the intended effect, you have to move the input handling part of your code inside the keyup function:
var validChoices = ["r", "p", "s"];
document.onkeyup = function(event) {
var choiceIsValid = false;
var userChoice = (event.key);
for (var i = 0; i < validChoices.length; i++) {
if (validChoices[i] === userChoice) {
choiceIsValid = true;
}
}
if (choiceIsValid) {
alert("Your choice is " + userChoice);
} else {
alert("Please make a valid choice");
}
}
You need to place all your code within the keyup event function. Your code has to be told to run, if it's outside of that function it is never told to execute.
You don't need to iterate over an array to discover if something is included within it. You can use the Array includes method:
arr.includes(item)
which will return true or false. This also negates your use of a variable to store whether or not the choice is valid.
We can then use a ternary, since there are only two possible outcomes, to either alert that the typed key was valid and included in the valid choices array, or alert that it was not.
Example of ternary:
(condition) ? (code for true) : (code for false);
document.onkeyup = function(event) {
var userChoice = event.key,
validChoices = ["r", "p", "s"];
(validChoices.includes(userChoice)) ?
alert("Your choice is " + userChoice):
alert("Please make a valid choice");
}

using if statement with && and || inside for loop

I have an if statement inside for loop with more than one condition. I want to match the data in database with input data in an HTML form. When the input field in the form is blank it is stored as null in the database. I have this column(itemsSortedByDate[i].FD_MIMO) in the database which can be null or can have some value. I am unable to match the blank field with null in the database. Also even if that column(itemsSortedByDate[i].FD_MIMO) has some value in the database, my for loop searches for the database which has null field just because other fields are matching. My Javascript is as below. The last condition is creating problems. ScenarioListViewModel.fdMimo()and itemsSortedByDate[i].FD_MIMO are supposed to be same whether it's null or has some value. But in the console.log they are different. Thank you for your help, much appreciated.
self.getJobIdForCapacity = function(itemsSortedByDate){
var jobIdForCapacity;
var found = false;
for (var i = 0, len = itemsSortedByDate.length; i < len; i++) {
if(itemsSortedByDate[i].DB_Name == ScenarioListViewModel.db_name()
&& itemsSortedByDate[i].Split_Mode == ScenarioListViewModel.splitMode()
&& itemsSortedByDate[i].Full_Output == ScenarioListViewModel.fullOutput()
&& (itemsSortedByDate[i].Workflow_Status == "Completed" || itemsSortedByDate[i].Workflow_Status == "Running")
&& (itemsSortedByDate[i].Disposition == "Success" || itemsSortedByDate[i].Disposition == "None")
&& (itemsSortedByDate[i].FD_MIMO == ScenarioListViewModel.fdMimo() || itemsSortedByDate[i].FD_MIMO == null)){
jobIdForCapacity = itemsSortedByDate[i].Title;
console.log("Job Id:" + jobIdForCapacity);
console.log("fdmimo from form:" +ScenarioListViewModel.fdMimo());
console.log("fdmimo from list:" +itemsSortedByDate[i].FD_MIMO);
self.getJobResults(jobIdForCapacity);
found = true;
break;
}
}
if (!found) {
alert("Job not found in Sharepoint Execution History List. Click Execute Model to run");
}
};
I would suggest you use === in all the conditions in if statement and it may help you solve your problem as there is difference in === vs ==.
Please refer this question for the difference.
For example:
itemsSortedByDate[i].DB_Name == ScenarioListViewModel.db_name()
will be
itemsSortedByDate[i].DB_Name === ScenarioListViewModel.db_name()
Condition:
"Completed" || itemsSortedByDate[i].Workflow_Status == "Running"
will always return "Completed" does not matter itemsSortedByDate[i].Workflow_Status == "Running" is true or false. Here your can use ternary operator like
itemsSortedByDate[i].Workflow_Status == "Running"? "Running" : "Compelted"
Something of this kind. Check all conditions like this.

Replacing if else if statements with something more efficient

I'm trying to learn coding by building a simple text game. The end game is going to have 4 rooms. You'll start in room 1, exit west to room 2, exit south to room 3, and finally exit east in room 4. (clockwise).
Anyway, my starting code is from a YouTube tutorial I found that consists of all if / else if statements. I already see that's terribly inefficient. My question is how do I improve this code?
I'm guessing I should make each room and it's contents an object (ie. Room 1 has a sword in it, so the object would contain the location of the room and the sword). I'm also guessing if I have a monster in a room, he'd be his own object.
My problem is if the above is correct (object) - I don't understand how to use the object once I create it. ie. if the user types "take sword" how do I call the object to do that?
If I'm on the complete wrong track, please point me back in the right direction.
Here's the current code for the first room:
$("form").submit(function() {
var input = $("#commandLine").val();
function check() {
check = true;
}
if (input == "help") {
$("#messageHelp").clone().insertBefore("#placeholder").fadeIn(1000);
check();
}
if (input == "take sword" && currentRoom == "nCorridor") {
$("<p>You picked up a sword.</p>").hide().insertBefore("#placeholder").fadeIn(1000);
check();
}
else if (input == "take sword" && currentRoom != "nCorridor") {
$("<p>The sword is not here.</p>").hide().insertBefore("#placeholder").fadeIn(1000);
check();
}
else if (input != "take sword" && input != "help") {
$("<p>I don't understand " + input + ".</p>").hide().insertBefore("#placeholder").fadeIn(1000);
}
$("#commandLine").val("");
});
Ideally, I'd like to eliminate or greatly reduce my need to use if and else if statements for something more efficient.
First let's improve the logic in the if statements to reduce the duplicate conditions, to see how far that gets you:
if (input == "help") {
$("#messageHelp").clone().insertBefore("#placeholder").fadeIn(1000);
check();
} else if (input == "take sword") {
if (currentRoom == "nCorridor") {
$("<p>You picked up a sword.</p>").hide().insertBefore("#placeholder").fadeIn(1000);
check();
} else {
$("<p>The sword is not here.</p>").hide().insertBefore("#placeholder").fadeIn(1000);
check();
}
} else {
$("<p>I don't understand " + input + ".</p>").hide().insertBefore("#placeholder").fadeIn(1000);
}
Another way to determine the action depending on input is using a switch, which may be more useful when you get more options:
switch (input) {
case "help":
$("#messageHelp").clone().insertBefore("#placeholder").fadeIn(1000);
check();
break;
case "take sword":
if (currentRoom == "nCorridor") {
$("<p>You picked up a sword.</p>").hide().insertBefore("#placeholder").fadeIn(1000);
check();
} else {
$("<p>The sword is not here.</p>").hide().insertBefore("#placeholder").fadeIn(1000);
check();
}
break;
default:
$("<p>I don't understand " + input + ".</p>").hide().insertBefore("#placeholder").fadeIn(1000);
}
To go on and using objects for keeping track of items, you could create an object for the sword (with just the location for now):
var sword = {
room: "nCorridor"
};
In the code you could use the object like this:
if (currentRoom == sword.room) {
$("<p>You picked up a sword.</p>").hide().insertBefore("#placeholder").fadeIn(1000);
check();
} else {
$("<p>The sword is not here.</p>").hide().insertBefore("#placeholder").fadeIn(1000);
check();
}
From there you can add more properties and methods to items. The objects might for example have methods that you can use to determine what you can do with them, like that the item apple can be eaten, but the item sword can not.

Score Incrementing in Javascript (Variable Scope Issues, probabbly?)

As a complete beginner to programming I was following the JavaScript courses at CodeAcademy. I've completed the rock-paper-scissors assignmennt and now I want to add a score system to my game. What I decided to do was creating two global variables called userScore and computerScore. The game function would then increment these scores at a win. Eventually I plan to add a for or while loop with a break to end the game when a score of 3 is reached. The problem is I am unable to increment the score. Here is the code
var userScore=0
var compScore=0
//COMPARING FUNCTION
var compare = function(choice1, choice2)
{
if(choice1 === choice2){ return "The result is a tie!" ;}
else if(choice1 === "rock"){
if(choice2 === "scissors"){ return "rock wins"; userScore++; }
else{ return "paper wins"; computerScore++;}
}
};
console.log(compare(userChoice, computerChoice));
console.log(userScore);
console.log (compScore);
However the score increments do not work when I console.log the scre variables. As an alternative approach I have tried to create separate functions to increment scores called userwin and compwin. Here are them:
var userwin= function()
{
window.userScore++;
};
var compwin= function()
{
window.computerScore++;
};
These function work on their own and succesfully change the userScore and computerScore variables. However when I try to use them within the if statement of my comparing function, again they fail.
So a recap: For some reason I am unable to change the userScore and computerScore form within my comparing function. Is it a simple syntax mistake or am I not understandig some fundemental aspect of variable scope. Or would you guys reccomend a completely different approach to scoring instead of using two different score variables?
Two issues,
You are attempting to increase the score after returning from the compare function
You have wrong names at two places in the code (compScore and computerScore)
var userScore=0;
var compScore=0;
//COMPARING FUNCTION
var compare = function(choice1, choice2)
{
if(choice1 === choice2){ return "The result is a tie!" ;}
else if(choice1 === "rock"){
if(choice2 === "scissors"){ userScore++; return "rock wins"; }
else{ compScore++; return "paper wins"; }
}
};
console.log(compare(userChoice, computerChoice));
console.log(userScore);
console.log (compScore);
You are incrementing the score after the return statement. Code after a return statement will never be executed.
Do this instead:
if(choice2 === "scissors"){
userScore++;
return "rock wins";
}
else{
computerScore++;
return "paper wins";
}
Seems simple ;=))
Just put the return statement AFTER the variable increment...
The way you have it you are returning from the function before doing the increment...

.innerHTML not updating HTML in Javascript

working on a rock paper scissors assignment where a global variable increments forward depending on whether the computer or the human wins. My functions work fine, but the scoreboard will not update when using .innerHTML. Any suggestions?
document.getElementById("humanScore").innerHTML = humanTotal;
document.getElementById("computerScore").innerHTML = compTotal;
http://codepen.io/anon/pen/GvpaJ
There are a few issues you are having.
In your play function, you are not doing anything with computerChoice variable, and it should be a result of the function call to compPlay(). Presently it is var computerChoice = compPlay, which is actually assigning computerChoice to a function, not the result of it.
Secondly in the testing if statements, you are checking the value again compPlay, which is a function, I think it should be computerChoice
Thirdly. the return value from compPlay is an index, it should that index value from the compOptions array
updated code below
var humanTotal =0;
var compTotal=0;
document.getElementById("rock").onclick = setRock;
document.getElementById("paper").onclick = setPaper;
document.getElementById("scissors").onclick = setScissors;
function setRock(){
play("rock")
}
function setPaper(){
play("paper")
}
function setScissors(){
play("scissors")
}
function play(humanChoice) {
var computerChoice = compPlay(); //<-- Change Here
//And all the following if statements to check the computer choice
if (humanChoice == "rock"){
if (computerChoice =="rock"){
} else if (computerChoice =="scissors"){
humanTotal++;
} else if (computerChoice =="paper"){
compTotal++;
}
}
if (humanChoice == "paper"){
if (computerChoice =="paper"){
} else if (computerChoice =="rock"){
humanTotal++;
} else if (computerChoice =="scissors"){
compTotal++;
}
}
if (humanChoice == "scissors"){
if (computerChoice =="scissors"){
} else if (computerChoice =="paper"){
humanTotal++;
} else if (computerChoice =="rock"){
compTotal++;
}
}
document.getElementById("humanScore").innerHTML = humanTotal;
document.getElementById("computerScore").innerHTML = compTotal;
}
function compPlay (){
var compOptions = ['rock', 'paper', 'scissors'];
var randomChoice = Math.floor(Math.random()*compOptions.length);
return compOptions[randomChoice]; //<-- Change Here
}
It has nothing to do with innerHTML, that is working fine, it was just that the score was always zero. The reason was because none of the if statements testing for "rock", "paper" or "scissors" ever resolved to true as the computerChoice never matched "rock","paper", or "scissors", so sorry but it was your functions.
Your functions does not work fine. The innerHTML-part works like it should (proof: http://codepen.io/anon/pen/qlIsG).
The problem is that you've made some error in your game logic that causes the scoreboard to end up 0-0 every time.
Good luck on your assignment.
You have several mistakes, its not a problem of innerHTML:
1) Change this, and use computerChoice to check computers play
var computerChoice = compPlay();
2) In your compPlay function, change this:
return compOptions[randomChoice]; // you want the play, not the random number
Working version:
http://codepen.io/juvian/pen/pLqxD

Categories