I'm trying to create a game in which a user "bets" on if the next card will be in between the previous two shown. In order to calculate that, I created a random number through 52 and set it equal to an array variable value. I need a number 2-14 as opposed to 1-52 (to evaluate the # of the card in case 2 cards with same # and different suite show). To do that, I used slice to get the 1st letter of the array item and store it in a variable (num1, num2, numUser).
I then used if else statements to give the face cards (10, jack, queen, king, ace) # values. The issues is, I need to apply this to all 3 variables. Currently, the statement stops when it identifies a face card and sets the # value. If there are multiple face cards, the statement only applies to the first.
I tried wrapping this in a for loop and making it run 3 times- ex.(for (var i = 0; i > 3; i++), but that didn't work. Sorry if this is confusing, any help is greatly appreciated.
function outputCards(){
rand1 = Math.floor((Math.random() * 52));
rand2 = Math.floor((Math.random() * 52));
$('#cardUser').attr("src", "#");
if(rand1 == rand2){
rand2 = Math.floor((Math.random() * 52));
} else {
card1 = cards[rand1];
card2 = cards[rand2];
$('#cardOne').attr("src", "imgs/" + card1);
$('#cardTwo').attr("src", "imgs/" + card2);
}
}
function userCard(){
rand_user = Math.floor((Math.random() * 52));
if(rand_user == rand1 || rand_user == rand2){
rand_user = Math.floor((Math.random() * 52));
} else {
user_card = cards[rand_user];
$('#cardUser').attr("src", "imgs/" + user_card);
}
}
function outcome(){
userCard();
num1 = card1.slice(0,1);
num2 = card2.slice(0,1);
numUser = user_card.slice(0,1);
if(num1 == "j"){
num1 = 11;
} else if (num2 == "j") {
num2 = 11;
} else if (numUser === "j") {
numUser = 11;
} else if (num1 == "q") {
num1 = 12;
} else if (num2 == "q") {
num2 = 12;
} else if (numUser === "q") {
numUser = 12;
} else if (num1 == "k") {
num1 = 13;
} else if (num2 == "k") {
num2 = 13;
} else if (numUser === "k") {
numUser = 13;
} else if (num1 == "a") {
num1 = 14;
} else if (num2 == "a") {
num2 = 14;
} else if (numUser === "a") {
numUser = 14;
} else if(num1 == 1){
num1 = 10;
} else if(num2 == 1){
num2 = 10;
} else if(numUser == 1){
numUser = 10;
} else {
}
}
well theres more efficient ways to accomplish this, the most straightforward (and beginner friendly) one is to use 3 else if trees not a single one.
if(num1 == "j"){
num1 = 11;
} else if (num2 == "j") {
num2 = 11;
} else if (numUser === "j") {
numUser = 11;
...
you have these grouped together when they need to be separate
if(num1 == "j"){
num1 = 11;
} else if (num1 == "q") {
num1 = 12;
} else if (num1 === "k") {
num1 = 13;
...
if(num2 == "j"){
num2 = 11;
} else if (num2 == "q") {
num1 = 12;
} else if (num2 === "k") {
num2 = 13;
...
this can be accomplished by putting the if statements in a function
function outcome(number){
if(number == "j"){
return 11;
} else if (number == "q") {
return 12;
} else if (number === "k") {
...
} //etc
}
num1 = outcome(card1.slice(0,1))
num2 = outcome(card2.slice(0,1))
numUser = outcome(user_card.slice(0,1));
you can also create an object map to map the card letter with a number value
var cardMap = {
j: 11,
q: 12,
k: 13,
...
}
then you can do
num1 = cardMap[card1.slice(0,1)]
num2 = cardMap[card2.slice(0,1)]
numUser = cardMap[user_card.slice(0,1)]
An if-elseif block will stop execution whenever it finds a true conditional, regardless of how many you have.
So you want to evaluate the variable based on the first character, and you know that will always be the same, right? This is a great opportunity to use a simple function that does just that one job (as all functions should do).
function getCardValueFromFirstCharacter(character) {
// you may need to check for the number as well:
// if (character == "1") {
// return 1;
// } else if (character == "2") {
// return 2;
// }
// etc..
if (character == "j") {
return 11;
} else if (character == "q") {
return 12;
}
// etc..
}
Now, in your other function, your outcome function, you can call this one with each of your desired inputs:
function outcome() {
userCard();
num1 = getCardValueFromFirstCharacter(card1.slice(0,1));
num2 = getCardValueFromFirstCharacter(card2.slice(0,1));
numUser = getCardValueFromFirstCharacter(user_card.slice(0,1));
}
In this way, we have our single function that is solely responsible for identifying the value of a card based on the first character. This function can change its implementation to affect all of places we need to use it - so, let's say you decide Jokers should be evaluated as 20, you can add it to that one function, and all of your code will now work with that new value. Thus, breaking apart our code into tiny functions that do one thing and are referenced for that one thing all over our codebase is important.
Related
I'm creating a code to randomly assign three skills for my friends and I as we start a Skyrim challenge. As there's 18 skills to choose from, I wrote code generating three random numbers, and then created conditions that would assign strings containing the names of the skills to 3 variables so I could print them. When I ran it the first time there was an error saying that the string variables weren't defined, and I assumed that was because they were only defined within the parameters of my if statements. So I assigned some arbitrary letters to the strings beforehand, so that they would be changed as the numbers were generated but now it won't change the strings and only the placeholder text is printing. Here's my code
//three random numbers for skills
var num1 = Math.floor(Math.random() * 18) + 1;
var num2 = Math.floor(Math.random() * 18) + 1;
var num3 = Math.floor(Math.random() * 18) + 1;
let skill1 = "as ";
let skill2 = " sd";
let skill3 = " sd";
//makes sure there's no overlap
if (num1 == num2) {
var num2 = Math.floor(Math.random() * 18) + 1;
}
if (num1 == num3) {
var num3 = Math.floor(Math.random() * 18) + 1;
}
if (num2 == num3) {
var num3 = Math.floor(Math.random() * 18) + 1;
}
//setting the string to the skill name based on the random number
if (num1 == 1) {
let skill1 = "Illusion";
}
if (num1 == 2) {
let skill1 = "Conjuration";
}
if (num1 == 3) {
let skill1 = "Destruction";
}
if (num1 == 4) {
let skill1 = "Restoration";
}
if (num1 == 5) {
let skill1 = "Alteration";
}
if (num1 == 6) {
let skill1 = "Enchanting";
}
if (num1 == 7) {
let skill1 = "Smithing";
}
if (num1 == 8) {
let skill1 = "Heavy Armor";
}
if (num1 == 9) {
let skill1 = "Block";
}
if (num1 == 10) {
let skill1 = "Two-Handed";
}
if (num1 == 11) {
let skill1 = "One-Handed";
}
if (num1 == 12) {
let skill1 = "Archery";
}
if (num1 == 13) {
let skill1 = "Light Armor";
}
if (num1 == 14) {
let skill1 = "Sneak";
}
if (num1 == 15) {
let skill1 = "Lockpicking";
}
if (num1 == 16) {
let skill1 = "Pickpocket";
}
if (num1 == 17) {
let skill1 = "Speech";
}
if (num1 == 18) {
let skill1 = "Alchemy";
}
if (num2 == 1) {
let skill2 = "Illusion";
}
if (num2 == 2) {
let skill2 = "Conjuration";
}
if (num2 == 3) {
let skill2 = "Destruction";
}
if (num2 == 4) {
let skill2 = "Restoration";
}
if (num2 == 5) {
let skill2 = "Alteration";
}
if (num2 == 6) {
let skill2 = "Enchanting";
}
if (num2 == 7) {
let skill2 = "Smithing";
}
if (num2 == 8) {
let skill2 = "Heavy Armor";
}
if (num2 == 9) {
let skill2 = "Block";
}
if (num2 == 10) {
let skill2 = "Two-Handed";
}
if (num2 == 11) {
let skill2 = "One-Handed";
}
if (num2 == 12) {
let skill2 = "Archery";
}
if (num2 == 13) {
let skill2 = "Light Armor";
}
if (num2 == 14) {
let skill2 = "Sneak";
}
if (num2 == 15) {
let skill2 = "Lockpicking";
}
if (num2 == 16) {
let skill2 = "Pickpocket";
}
if (num2 == 17) {
let skill2 = "Speech";
}
if (num2 == 18) {
let skill2 = "Alchemy";
}
if (num3 == 1) {
let skill3 = "Illusion";
}
if (num3 == 2) {
let skill3 = "Conjuration";
}
if (num3 == 3) {
let skill3 = "Destruction";
}
if (num3 == 4) {
let skill3 = "Restoration";
}
if (num3 == 5) {
let skill3 = "Alteration";
}
if (num3 == 6) {
let skill3 = "Enchanting";
}
if (num3 == 7) {
let skill3 = "Smithing";
}
if (num3 == 8) {
let skill3 = "Heavy Armor";
}
if (num3 == 9) {
let skill3 = "Block";
}
if (num3 == 10) {
let skill3 = "Two-Handed";
}
if (num3 == 11) {
let skill3 = "One-Handed";
}
if (num3 == 12) {
let skill3 = "Archery";
}
if (num3 == 13) {
let skill3 = "Light Armor";
}
if (num3 == 14) {
let skill3 = "Sneak";
}
if (num3 == 15) {
let skill3 = "Lockpicking";
}
if (num3 == 16) {
let skill3 = "Pickpocket";
}
if (num3 == 17) {
let skill3 = "Speech";
}
if (num3 == 18) {
let skill3 = "Alchemy";
}
let message = skill1 + " " + skill2 + " " + skill3;
I tried defining the string outside of the if statement, and the result was that the strings were printed as the placeholder and weren't changed by the condition being met
Your issue is that you're redeclaring the variable within every if statement.
Instead of:
if (num1 == 4) {
let skill1 = "Restoration";
}
Put:
if (num1 == 4) {
skill1 = "Restoration";
}
Adding the let tells javascript you're declaring a new variable, just putting the variable name lets it know to modify your previously created variable.
Your solution can be simplified a bit to avoid repetition:
// Use an array to store a list of all availble skills
// We're going to treat this like a deck of cards
const skills = [
"Illusion",
"Conjuration",
"Destruction",
"Restoration",
"Alteration",
"Enchanting",
"Smithing",
"Heavy Armor",
"Block",
"Two-Handed",
"One-Handed",
"Archery",
"Light Armor",
"Sneak",
"Lockpicking",
"Pickpocket",
"Speech",
"Alchemy",
];
// Shuffle the skills so that they have a random order in the new array
const shuffledSkills = skills.sort((a, b) => 0.5 - Math.random());
// We now have a mixed deck of cards
// Select the first three skills, i.e. pick three cards from the deck
const selectedSkills = shuffledSkills.slice(0, 3);
// Now we have an array with three random skills
console.log(selectedSkills);
// You can make a string out of them if you like
const message = selectedSkills.join(" ");
If you want to improve the randomization, this question has many good answers: How to randomize (shuffle) a JavaScript array?
I have been working on a maths project for my son, and am currently struggling to attach the correct maths sum to the correct math operator currently shown on the website.
The function mathOperator() aims to identify what math operator is currently on page and then supply the correct sum.
Then i am trying to check if the textContent of the chosen clicked answer matches that sum or not using the anonymous function below mathOpertor().
I am getting no errors in the console but the code is annoyingly just adding num1 and num2 together no mater which math operator is currently active.
I figure the problem is within the lines:
let operator = num1 + num2;
if (this.textContent == operator) { }
I figured (let operator) would be mutated to the condition that was met within the mathOperator() function, but this is not the case!
Here is my code below:
//Globals
const arrLength = 10
const randomArr = []
//push random numbers to randomArr.
for (let i=0; i<arrLength; i++) {
randomArr.push(Math.floor(Math.random() * 10));
}
//DOM targets
//first and second numbers.
const num1 = document.getElementById("num1").textContent = randomArr[0];
const num2 = document.getElementById("num2").textContent = randomArr[1];
//Multiple choice answers
let option1 = document.getElementById("option1").textContent = randomArr[2];
let option2 = document.getElementById("option2").textContent = randomArr[3];
let option3 = document.getElementById("option3").textContent = randomArr[4];
//Places the correct asnwer randomly within the 3 multiple choice answers.
const correctAnswerPosition = Math.floor(Math.random() * 3);
document.querySelectorAll(".options h1")[correctAnswerPosition].textContent = num1 + num2;
//function to decide how to calculate equation depending on what HTMLpage you are on.
function mathoperators(sum) {
if (document.querySelector(".wrapper div").children[1].textContent == "+") {
sum = num1 + num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "-") {
sum = num1 - num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "*") {
sum = num1 * num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "/") {
sum = num1 / num2;
}
}
//What do to if you pick right or wrong answer.
for (let a=0; a<document.querySelectorAll(".options").length; a++) {
//targets the 3 divs that contain random incorrect answers plus correct answer.
document.querySelectorAll(".options")[a].addEventListener("click", function() {
let operator = num1 + num2;
if (this.textContent == operator) { //problem here i don't know how to connect this to sum in math operators function.
const correct = new Audio("Sounds/correct.mp3");
correct.play();
document.querySelector(".wrapper").style.display="none";
document.querySelector(".well-done").style.display="block";
setTimeout(function() {
location.reload();
}, 3000);
} else {
const incorrect = new Audio("Sounds/incorrect.mp3");
incorrect.play();
}
mathoperators(operator)
})
}
function reload() {
reload = location.reload();
}
Thankyou for your time in advance.
# bergi, Thanks very much this is the push in the right direction I needed, the changes have been made below:
function mathoperators() {
if (document.querySelector(".wrapper div").children[1].textContent == "+") {
return num1 + num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "-") {
return num1 - num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "*") {
return num1 * num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "/") {
return num1 / num2;
}
}
//What do to if you pick right or wrong answer.
for (let a=0; a<document.querySelectorAll(".options").length; a++) {
document.querySelectorAll(".options")[a].addEventListener("click", function() {
const number = parseFloat(this.textContent)
if (mathoperators() === number) {
const correct = new Audio("Sounds/correct.mp3");
correct.play();
document.querySelector(".wrapper").style.display="none";
document.querySelector(".well-done").style.display="block";
After this I also noticed that the below needed changing so that it was equal to mathOperator() and not num1 + num2;.
//Places the correct asnwer randomy within the 3 multiple choice answers.
const correctAnswerPosition = Math.floor(Math.random() * 3);
document.querySelectorAll(".options h1")[correctAnswerPosition].textContent = mathoperators();
Thanks for your help Bergi.
Is there a way that I can combine these two codes into one? I want to check if some variables are equal to 0 or equal to 1 or equal to 2 or greater than 2 and less than 5 or greater than 5. Should I write a code for each variable or I can write a code for all variables?
<script>
if (NRIRDL==0){
XRIRDL=0;
}
else if (NRIRDL == 1){
XRIRDL = 1;
}
else if (NRIRDL == 2){
XRIRDL = 1.8;
}
else if (NRIRDL > 2 && NRIRDL < 5){
XRIRDL = 0.9 * NRIRDL;
}
else {
XRIRDL = NRIRDL - 1;
}
// code below is the same as code above, but variables are different.
if (NRIRDR==0){
XRIRDR=0;
}
else if (NRIRDR == 1){
XRIRDR = 1;
}
else if (NRIRDR == 2){
XRIRDR = 1.8;
}
else if (NRIRDR > 2 && NRIRDR < 5){
XRIRDR = 0.9 * NRIRDR;
}
else {
XRIRDR = NRIRDR - 1;
}
</script>
actually, it can be written shorter with ternary operator and without multiple if conditions, check it out:
function getValue(n) {
return n >= 2 && n < 5 ? n * 0.9 : n == 0 ? 0 : n == 1 ? 1 : n - 1;
}
var var1 = 0;
var var2 = 1;
var var3 = 2;
var var4 = 3;
var var5 = 5;
console.log(getValue(var1)); // outputs 0
console.log(getValue(var2)); // outputs 1
console.log(getValue(var3)); // outputs 1.8
console.log(getValue(var4)); // outputs 2.7
console.log(getValue(var5)); // outputs 4
Just use getValue(n) function: pass your variable and it will return needed value that can be stored into another variable like var XRIRDL = getValue(NRIRDL); or var XRIRDR = getValue(NRIRDR);
You could make it into a function:
function yourFunction(val) {
if (val == 0){
return 0;
}
else if (val == 1){
return 1;
}
else if (val == 2){
return 1.8;
}
else if (val > 2 && val < 5){
return 0.9 * val;
}
else {
return val - 1;
}
XRIDR = yourFunction(NRIDR);
XRIDL = yourFunction(NRIDL);
When you OR the two inputs together, you lose valuable information about which one of the two inputs triggered that condition.
Mike's answer might not fit your needs because you can't update the values independently of one another (i.e. if NRIDR == 0 and NRIDL == 2, it sounds like you don't want both XRIDR and XRIDL to equal 1.8.)
You could put it inside a function. Here's a copy paste of your code inside a function.
function xrirdr(dr_or_dl){
var XRIRDL = null;
if (dr_or_dl==0){
XRIRDL=0;
}
else if (dr_or_dl == 1){
XRIRDL = 1;
}
else if (dr_or_dl == 2){
XRIRDL = 1.8;
}
else if (dr_or_dl > 2 && dr_or_dl < 5){
XRIRDL = 0.9 * dr_or_dl;
}
else {
XRIRDL = dr_or_dl - 1;
}
return XRIRDL;
}
You can pass NRIRDL or NRIRDR in the function and it will get you your XRIRDL
<script>
if (NRIRDL==0 || NRIRDR==0 ){
XRIRDL=0;
XRIRDR=0;
}
else if (NRIRDL == 1 || NRIRDR == 1)){
XRIRDL = 1;
XRIRDR = 1;
}
else if (NRIRDL == 2 || NRIRDR == 2)){
XRIRDL = 1.8;
XRIRDR = 1.8;
}
else if ((NRIRDL > 2 && NRIRDL < 5) || (NRIRDR > 2 && NRIRDR < 5) ){
XRIRDL = 0.9 * NRIRDL;
XRIRDR = 0.9 * NRIRDR;
}
else {
XRIRDL = NRIRDL - 1;
XRIRDR = NRIRDR - 1;
}
</script>
I wrote a javascript to ask the user to input 5 numbers and check for the largest and smallest number. I can get it to display the largest and smallest number sometimes. The main problem is that I need to show an error message when the user inputs the smallest or largest number more than once. When i enter two large numbers in the first two boxes, I get an error message, but if I enter two small numbers, I don't get an error message. Here's my code, I suspect it's my else if, but I'm not totally sure.
EDIT: Sorry all, I forgot to mention that I'm restricted to only using if-else statements. No loops, no arrays. None of that. I know, I know, it's absolutely terrible.
function testProgram() {
var largestNum, smallestNum;
var num1, num2, num3, num4, num5;
var smallDupe, largeDupe;
var num1 = document.getElementById("Num1").value;
var num2 = document.getElementById("Num2").value;
var num3 = document.getElementById("Num3").value;
var num4 = document.getElementById("Num4").value;
var num5 = document.getElementById("Num5").value;
num1 = parseFloat(num1);
num2 = parseFloat(num2);
num3 = parseFloat(num3);
num4 = parseFloat(num4);
num5 = parseFloat(num5);
if ((!isNaN(num1)) && (!isNaN(num2)) && (!isNaN(num3)) && (!isNaN(num4)) && (!isNaN(num5))) {
largestNum = num1;
smallestNum = num1;
smallDupe = 0;
largeDupe = 0;
if(num2 >= largestNum) {
if(num2 == largestNum) {
largeDupe++;
}
else if (num2 <= smallestNum) {
if(num2 == smallestNum) {
smallDupe++;
}
smallestNum = num2;
smallDupe = 0;
} else {
largestNum = num2;
largeDupe = 0;
}
}
if(num3 >= largestNum) {
if(num3 == largestNum) {
largeDupe++;
}
else if (num3 <= smallestNum) {
if(num3 == smallestNum) {
smallDupe++;
}
smallestNum = num3;
smallDupe = 0;
} else {
largestNum = num3;
largeDupe = 0;
}
}
if(num4 >= largestNum) {
if(num4 == largestNum) {
largeDupe++;
}
else if (num4 <= smallestNum) {
if(num4 == smallestNum) {
smallDupe++;
}
smallestNum = num4;
smallDupe = 0;
} else {
largestNum = num4;
largeDupe = 0;
}
}
if(num5 >= largestNum) {
if(num5 == largestNum) {
largeDupe++;
}
else if (num5 <= smallestNum) {
if(num5 == smallestNum) {
smallDupe++;
}
smallestNum = num5;
smallDupe = 0;
} else {
largestNum = num5;
largeDupe = 0;
}
}
if (smallDupe > 0 || largeDupe > 0) {
// Display an error to the user stating that there are duplicates
window.alert("The smallest number and/or largest number contains is duplicated.");
console.log("Error notice");
}
// Reference out1 and out2 to the HTML document
var out1 = document.getElementById("Out1");
var out2 = document.getElementById("Out2");
out1.disabled = false;
out1.value = largestNum;
out2.disabled = false;
out2.value = smallestNum;
} else {
// Tells the user that their input is invalid and to input five numbers again
window.alert("Please input five numbers");
console.log("Error notice");
}
}
After you increment smallDupe, you're setting it back to 0. You need to handle the case of the current number being less than the smallest separately from it being equal. Also, if you enter the same number in the first sequence of boxes, it will be a duplicate of both the largest and smallest, and you need to allow this; the simplest way to do this is to use two separate groups of if/else if rather than combining them all into one big statement.
if(num2 > largestNum) {
largestNum = num2;
largeDupe = 0;
} else if (num2 == largestNum) {
largeDupe++;
}
if (num2 < smallestNum) {
smallestNum = num2;
smallDupe = 0;
} else if (num2 == smallestNum) {
smallDupe++;
}
I am having a bit of trouble with a few math calculation in javascript.
The goal of this calculation is to generate a value when the user clicks on a text field.
For example:
1 Kilogram costs 32 cents to ship to America and the user wants to find out what 10KG will cost him which is $3.20. For this I have the following piece of javascript code:
function calculate(num) {
var weight = document.getElementById('weight'+num);
var price = document.getElementById('price'+num);
if(num == undefined || num == '' || num.length <= 0 || isNaN(weight.value) || isNaN(price.value)) return false;
if(num == 1) multiplyBy = 0.32;
if(num == 2) multiplyBy = 0.14;
if(num == 3) multiplyBy = 0.24;
if(num == 4) multiplyBy = 0.53;
var sum = parseInt(document.getElementById('weight'+num).value) * multiplyBy;
if(isNaN(sum)) return false;
price.value = sum;
}
The above code works perfectly fine, however when I reverse the process (someone has $3.20 and wants to find out how much KG he/she can ship with that (which is 10KG) the script returns: 9.375KG
The following code is used for this calculation:
function reverse(num) {
var weight = document.getElementById('weight'+num);
var price = document.getElementById('price'+num);
if(num == undefined || num == '' || num.length <= 0 || isNaN(weight.value) || isNaN(price.value)) return false;
if(num == 1) divideBy = 0.32;
if(num == 2) divideBy = 0.14;
if(num == 3) divideBy = 0.24;
if(num == 4) divideBy = 0.53;
var sum = parseInt(document.getElementById('price'+num).value) / divideBy;
if(isNaN(sum)) return false;
weight.value = sum;
}
I honestly don't grasp why it is failing, It would be much appreciated if someone could help me out with this.
var sum = parseInt(document.getElementById('price'+num).value) / divideBy;
You are forcing price into an integer before dividing it. So if price is 3.20, you are actually dividing 3 / 0.32, which is 9.375.
Don't force it into an integer.