Basic JavaScript: Counting Cards - Card Counting Function with Strings - javascript

The card function has been explained multiple times, and I understand it. For those who do not know it: my function receives a card parameter, which can be a number or a string. I then increment or decrement the global count variable according to the card's value 2,3,4,5,6 increments, 7,8,9 keeps it at 0, while 10, J, Q, K, A decrements it. My function then returns a string with the current count and the string "Bet" if the count is positive, or "Hold" if it is negative.
So I understand how the function is done, and FreeCodeCamp accepted my solution as technically it meets their conditions. But have a question regarding this function:
var count = 0;
function cc(card) {
if (card >= 2 && card <= 6) {
count++;
} else if (card >= 7 && card <= 9) {
count += 0;
} else {
count--;
}
if (count <= 0) {
return count + " Hold";
} else {
return count + " Bet";
}
}
console.log(cc(2));
console.log(cc(3));
console.log(cc(7));
console.log(cc('K'));
console.log(cc('A'));
As I can see, the first condition is fairly simple and easy to define, so is the else if. In the third case, there are both numbers and strings involved. Does this not mean that when I put ANY string into cc, it will decrement? As anything that is not between 2 and 6, or 7 and 9, will automatically decrement? Even if the user inputs something that is not a card or is not a value from the list?
I understand that there is a list of predefined card values and names, but nevertheless, is there any better way to condition my statement to make sure that my condition will ONLY run IF the card is either 10, J, Q, K or A, and not any other value?

You can change your current else, to return and error message or just return immediately in case of the input being a non-valid card, and add another else-if to check for 10 through Ace:
if (card >= 2 && card <= 6) {
count++;
} else if (card>=7 && card <=9) {
count+= 0;
} else if (card === 10 || card === 'J' || card === 'Q' || card === 'K' || card === 'A'){
count--;
}else {
//Either just return or alert an error message and return
}

There are a number of ways you could deal with this situation. You could initially parse the input, and say assign 'J' to 11, 'Q' to 12, 'K' to 13 and 'A' to 1 (if you need to distinguish), or just a common number to that category. Everything else is an invalid input and you return immediately/post an error message. Something like:
var count = 0;
function cc(card) {
if (card == 'J' || card == 'Q' || card == 'K' || card == 'A')
card = 11;
if (card >= 2 && card <= 6) {
count++;
} else if (card>=7 && card <=9) {
count+= 0;
} else if (card >= 10 && card <= 11) {
count--; // to keep structure cleaner we use dummy 11 value
} else
//error message
if (count <= 0) {
return count + " Hold";
} else {
return count + " Bet";
}
}
cc(2); cc(3); cc(7); cc('K'); cc('A');
Also, you need to make sure to handle lower case and upper case values for the picture cards.

Define a set of allowed values and check if the value you are given is within that set using .includes(). For example:
var count = 0;
function cc(card) {
// Only change code below this line
const up = [2,3,4,5,6];
const no = [7,8,9];
const down = [10, "J", "Q", "K", "A"];
if(up.includes(card))count++;
if(down.includes(card))count--;
const str = count > 0 ? "Bet" : "Hold";
return `${count} ${str}`;
// Only change code above this line
}
// Add/remove calls to test your function.
// Note: Only the last will display
cc(2); cc(3); cc(7); cc('K'); cc('A');
Bear in mind this is type sensitive.

Another possibility is something like the following, which explicitly lists the changes for each card:
const counter = () => {
let count = 0
let values = {2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 0, 8: 0,
9: 0, 10: -1, J: -1, Q: -1, K: -1, A: -1}
return (card) => {
const change = values[card] || 0 // no change if card is, say, 'XYZ' or 'Joker'
count += change
return count <= 0 ? 'Hold' : 'Bet'
}
}
const cc = counter();
console.log(cc(2));
console.log(cc(3));
console.log(cc(7));
console.log(cc('K'));
console.log(cc('A'));
For a list as short as thirteen values, I think this sort of explicit list is cleaner.
This also encapsulates the count variable in a closure. I find that cleaner than a global variable.
Where the comment talks about jokers, you might want some more robust error-handling:
if (!(card in values)) {throw 'Bad card'}
const change = values[card]

You could use a regular expression at the very top of your function to skip all the conditionals and return a handy message if the argument passed in doesn't match a valid card:
// Check if card is valid
var cardRegex = /^(10|[2-9AJQK])$/i;
if (!cardRegex.test(card)) {
return "Invalid Card";
}
So, in the context of your code, it would look like:
var count = 0;
function cc(card) {
// Check if card is valid
var cardRegex = /^(10|[2-9AJQK])$/i;
if (!cardRegex.test(card)) {
return "Invalid Card";
}
if (card >= 2 && card <= 6) {
count++;
} else if (card >= 7 && card <= 9) {
count += 0;
} else {
count--;
}
if (count <= 0) {
return count + " Hold";
} else {
return count + " Bet";
}
}
// Valid inputs
console.log(cc(2));
console.log(cc(3));
console.log(cc(7));
console.log(cc('K'));
console.log(cc('a'));
// Invalid inputs
console.log(cc('e'));
console.log(cc('L'));
console.log(cc(0));

My solution for Basic JavaScript: Counting Cards
function cc(card) {
// Only change code below this line
if(card >= 2 && card <= 6) {
count++;
} else if (card === 10 ||card === 'J' || card === 'Q' || card === 'K' || card === 'A') {
count = count - 1;
}
if (count > 0) {
return count + ' Bet';
}
return count + ' Hold';
// Only change code above this line
}

My solution, based on what we learned so far.
Maybe it isnĀ“t the best, but it also works.
var count = 0;
function cc(card) {
// Only change code below this line
switch(card){
case 2:
case 3:
case 4:
case 5:
case 6:
count++;
break
case 7:
case 8:
case 9:
count = count;
break
case 10:
case 'J':
case 'Q':
case 'K':
case 'A':
count--;
break;
}
if (count <=0) {
return count + ' Hold';
}
else {
return count + ' Bet'
}
// Only change code above this line
}
console.log(cc(2));
console.log(cc(3));
console.log(cc(7));
console.log(cc('K'));
console.log(cc('A'));

let count = 0;
function cc(card) {
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
count++;
break;
case 10:
case 'J':
case 'Q':
case 'K':
case 'A':
count--;
}
if (count > 0) {
return count + " Bet";
} else {
return count + " Hold";
}
}

Related

I can't solve the Counting Cards problem on freeCodeCamp [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 10 months ago.
Improve this question
This is the freeCodeCamp Counting Cards activity.
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/counting-cards
My solution was
let count = 0;
function cc(card) {
// Only change code below this line
if (card = 2 || 3 || 4 || 5 || 6) {
count + 1;
} else if (card = 7 || 8 || 9) {
return;
} else if (card = 10, "J", "Q", "K", "A")
count - 1;
}
if (count > 0) {
return count + " " + "Bet";
} else if {
return count + " " + "Hold";
}
// Only change code above this line
}
cc(2); cc(3); cc(7); cc('K'); cc('A');
I checked the solution and it seemed similar. Why didn't it work?
A Few Modifications were necessary for this code to work.
= is assignment operator while == is comparing operator.
else if can be replaced with just else if there is no condition.
the third else if (card = 10, "J", "Q", "K", "A") didnt have closing or opening brackets.
avoid using return at else if (card == 7 || 8 || 9) { and instead use count += 0
You need too add a condition for || Or operator like this card == 7 || card == 8 and not like card == 7 || 8
Use count++ and count-- instead of count + 1 and count - 1
After all these changes the below code works fine.
let count = 0;
function cc(card) {
// Only change code below this line
if (card == 2 || card == 3 || card == 4 || card == 5 || card == 6) {
count++;
} else if (card == 7 || card == 8 || card == 9) {
count += 0;
} else if (card == 10|| card == "J"|| card == "Q"|| card == "K"|| card == "A"){
count--;
}
if (count > 0) {
return count + " " + "Bet";
} else {
return count + " " + "Hold";
}
}
cc(2); cc(3); cc(7); cc('K'); cc('A');
There are two main issues with your code.
Wrong if condition
Your if condition card = 2 || 3 || 4 || 5 || 6 does not work like you think it does. You would need to use car === 2 || card === 3 || car === 4 || card === 5 || car === 6. You cannot use the assignment operator = like this. You should use the strict comparison operator instead.
It's even easier to use an array and includes() like this [2, 3, 4, 5, 6].includes(card).
count is not updated
You need to assign the new value to count when you increment/ decrement it. You can use count++ instead of count + 1 which is the equivalent to count = count + 1.
let count = 0;
function cc(card) {
// Only change code below this line
if ([2, 3, 4, 5, 6].includes(card)) {
count++;
} else if ([10, "J", "Q", "K", "A"].includes(card)) {
count--;
}
if (count > 0) return `${count} Bet`;
return `${count} Hold`;
}
cc(2); cc(3); cc(7); cc('K'); cc('A');
= is used to assign a value and not to make comparison. In javascript we use == or === to make comparison, and also count - 1 will not update count. use count = count - 1 or count++
let count = 0;
function cc(card) {
// Only change code below this line
if ( card >= 2 && card <= 6) {
count = count + 1;
} else if (card >= 7 && card <= 9) {
return;
} else if (card === 10 || card === "J" || card === "Q" || card === "K" || card === "A")
count = count - 1;
}
if (count > 0) {
return count + " " + "Bet";
} else if {
return count + " " + "Hold";
}
// Only change code above this line
}
cc(2); cc(3); cc(7); cc('K'); cc('A');

why can't get expected result after truthy switch statements?

Trying to find all divisible numbers of an integer but getting an incorrect answer after switch loop.
function divisors(integer) {
let divNumbers = []
switch(true) {
case (integer % 2 === 0):
divNumbers.push(2);
case (integer % 3 === 0):
divNumbers.push(3);
case (integer % 4 === 0):
divNumbers.push(4);
case (integer % 5 === 0):
divNumbers.push(5);
break;
default: divNumbers.push(integer)
}
return divNumbers;
};
divisors(15)
Getting 3, 4, 5 as divNumbers where 4 shouldn't be here. Why?
Here's the correct solution that will not be hardcoded:
var divisors = function (num) {
const initial = num, result=[];
while(num--) {
if (initial % num ===0) {
result.push(num);
}
}
return result;
}
If you want to get the number itself in divisors, do this:
var divisors = function (num) {
const initial = num, result=[];
num++;
while(num--) {
if (initial % num ===0) {
result.push(num);
}
}
return result;
}
Switch stamenets fall through by default. To prevent this, you should break after each one. Having said that, you'll only end up with 3 in that case, as 15 is divisible by 3. Once the division was successful, you'd break out of the switch:
function divisors(integer) {
let divNumbers = []
switch (true) {
case (integer % 2 === 0):
divNumbers.push(2);
break;
case (integer % 3 === 0):
divNumbers.push(3);
break;
case (integer % 4 === 0):
divNumbers.push(4);
break;
case (integer % 5 === 0):
divNumbers.push(5);
break;
default:
divNumbers.push(integer)
}
return divNumbers;
};
console.log(divisors(15));
To ensure that you end up with both 3 and 5 in the array, I'd recommend swapping to if conditionals instead, because you want multiple conditions to trigger:
function divisors(integer) {
let divNumbers = []
if (integer % 2 === 0) {
divNumbers.push(2);
}
if (integer % 3 === 0) {
divNumbers.push(3);
}
if (integer % 4 === 0) {
divNumbers.push(4);
}
if (integer % 5 === 0) {
divNumbers.push(5);
}
return divNumbers;
}
console.log(divisors(15));
Hope this helps! :)

Counting cards game

I am trying to write a card counting function in javascript. Each card is assigned a value according to the table below. When the count is positive, the player should bet high. When the count is zero or negative, the player should bet low.
(i) if cards are 2, 3, 4, 5, 6 then count change =(+1);
(ii) if cards are 7,8,9 then count change =0;
(iii)if cards are 10, 'J', 'Q', 'K', 'A', then count change = (-1);
Here is my function:
var count = 0;
function cc(card) {
{
case 2:
case 3:
case 4:
case 5:
case 6:
return count++;
case 7:
case 8:
case 9:
return count;
case 10:
case 'J':
case 'Q':
case 'K':
case 'A':
return count--;
}
}
cc(2); cc(3); cc(7); cc('K'); cc('A');
From the last line of the code, I was anticipating to get a '0', but instead it gives me a '1'. Can anyone enlightens me on this?
Notice that the expression count++ (or count--) returns the counter before the update (and updates it as a side effect).
If you want to return the counter after updating you should use the ++ (or --) before the counter.
For example, if the count is 1 -
If you return count++ then 1 will be returned and as a side effect count will increase to 2.
If you return ++count then count will first increase and then be returned so 2 will be returned.
var count = 0;
function cc(card) {
if (card >= 2 && card <= 6) {
count += 1
}
else if (card >= 7 && card <= 9) {
count += 0
} else {
count -= 1
}
return count <= 0 ? `${count} Hold` : `${count} Bet`;
}

Why does my Button with a script not work sometimes?

I've made a simple script using Javascript which generates a random number between 0-5+1 (Dice.) My issue is that when I press the button, it does nothing half the time forcing me to spam the button multiple times before a dice roll would appear.
I've looked everywhere, but couldn't find any resources as to what the issue might be.
Here is my code:
<html>
<head>
</head>
<body>
<button type="button" onclick="spin()">Click here to roll the Dice!</button>
<img src="" id="demo">
<script>
function spin() {
if (Dice() == 1) {
document.getElementById("demo").src="http://i.imgur.com/QRTs9Ax.png";
}
else if (Dice() == 2) {
document.getElementById("demo").src="http://i.imgur.com/OMz1o8U.png";
}
else if (Dice() == 3) {
document.getElementById("demo").src="http://i.imgur.com/J4Xx2yO.png";
}
else if (Dice() == 4) {
document.getElementById("demo").src="http://i.imgur.com/CJb2ojk.png";
}
else if (Dice() == 5) {
document.getElementById("demo").src="http://i.imgur.com/8W6UL5O.png";
}
else if (Dice() == 6) {
document.getElementById("demo").src="http://i.imgur.com/NGxBete.png";
}
}
</script>
<script>
function Dice() {
return Math.floor(Math.random() * 6) + 1;
}
</script>
</body>
</html>
Because Math.floor(Math.random() * 6) + 1; could return 7.
EDIT
Math.floor(Math.random() * 6) + 1; can't return 7 according to Mozilla Developers because Math.random() doesn't include 1 and Math.floor just cut the value so you'll always recive a value between 1 and 6.
The proble is that with if (Dice() == x) you start the function so it will retur a diferent vaule for all the is statement. You have to build a switch like this:
function spin() {
switch (Dice()) {
case 1:
document.getElementById("demo").src = "http://i.imgur.com/QRTs9Ax.png";
break;
case 2:
document.getElementById("demo").src = "http://i.imgur.com/OMz1o8U.png";
break;
case 3:
document.getElementById("demo").src = "http://i.imgur.com/J4Xx2yO.png";
break;
case 4:
document.getElementById("demo").src = "http://i.imgur.com/CJb2ojk.png";
break;
case 5:
document.getElementById("demo").src = "http://i.imgur.com/8W6UL5O.png";
break;
case 6:
document.getElementById("demo").src = "http://i.imgur.com/NGxBete.png";
break;
}
Store the value of dice() once to a variable and check it with the if statements. You are regenerating the the value each time so there is no guarantee you will get the current value when checking.
Also, as mentioned by paolo, Math.floor(Math.random() * 6) + 1; could return 7.
<html>
<head>
</head>
<body>
<button type="button" onclick="spin()">Click here to roll the Dice!</button>
<img src="" id="demo">
<script>
function spin() {
var dice = Dice();
if (dice == 1) {
document.getElementById("demo").src="http://i.imgur.com/QRTs9Ax.png";
}
else if (dice == 2) {
document.getElementById("demo").src="http://i.imgur.com/OMz1o8U.png";
}
else if (dice == 3) {
document.getElementById("demo").src="http://i.imgur.com/J4Xx2yO.png";
}
else if (dice == 4) {
document.getElementById("demo").src="http://i.imgur.com/CJb2ojk.png";
}
else if (dice == 5) {
document.getElementById("demo").src="http://i.imgur.com/8W6UL5O.png";
}
else if (dice == 6) {
document.getElementById("demo").src="http://i.imgur.com/NGxBete.png";
}
}
</script>
<script>
function Dice() {
return Math.floor(Math.random() * 6) + 1;
}
</script>
</body>
</html>
You're trying to keep your random number from returning 0 by incrementing it by + 1 after flooring. However, when Math.random() returns exactly 1.0, your multiplication will result in exactly 6, which gets floored to 6 and then gets + 1 added to it, making it 7.
Instead, only multiple your random number by 5.
return Math.floor(Math.random() * 5) + 1;
Or, even more simply, just use Math.ceil(). Which will always round up to the nearest whole number.
return Math.ceil(Math.random() * 6);
You're calling the Dice() function on every else if statement.
I've created a fiddle where you can see on the console, which number is been generated, but your spin function would go like this:
function spin() {
var number = Dice();
console.log(number);
switch (number) {
case 1:
document.getElementById("demo").src="http://i.imgur.com/QRTs9Ax.png";
break;
case 2:
document.getElementById("demo").src="http://i.imgur.com/OMz1o8U.png";
break;
case 3:
document.getElementById("demo").src="http://i.imgur.com/J4Xx2yO.png";
break;
case 4:
document.getElementById("demo").src="http://i.imgur.com/CJb2ojk.png";
break;
case 5:
document.getElementById("demo").src="http://i.imgur.com/8W6UL5O.png";
break;
case 6:
document.getElementById("demo").src="http://i.imgur.com/NGxBete.png";
break;
}
}
Also you may get the same number multiple times, since it's random.
Just because Dice() hasn't static value and may return different value with each if statement, also may return the same random number with multiple if.
So store generated number in a variable and do your if statements as you like.
This below example based on selecting random image from imgs array and should do the task as your code do.
//add images what ever.
var imgs = [
"http://i.imgur.com/QRTs9Ax.png",
"http://i.imgur.com/OMz1o8U.png",
"http://i.imgur.com/J4Xx2yO.png",
"http://i.imgur.com/CJb2ojk.png",
"http://i.imgur.com/8W6UL5O.png",
"http://i.imgur.com/NGxBete.png"
];
function spin() {
var d = Dice(); //store the number in a variable
//Dice(5); ===> if you want the max random number will be 5
var i = d-1; //to get the right position in array
if(imgs[i])document.getElementById("demo").src = imgs[i];
//Also if you want additional statements use if(d == 1){}else if(d == 2){}
}
function Dice(max){
max = max || imgs.length;
return Math.floor(Math.random() * max) + 1;
}

javascript fizzbuzz switch statement

I'm currently taking the code academy course on Javascript and I'm stuck on the FizzBuzz task. I need to count from 1-20 and if the number is divisible by 3 print fizz, by 5 print buzz, by both print fizzbuzz, else just print the number. I was able to do it with if/ else if statements, but I wanted to try it with switch statements, and cannot get it. My console just logs the default and prints 1-20. Any suggestions?
for (var x = 0; x<=20; x++){
switch(x){
case x%3==0:
console.log("Fizz");
break;
case x%5===0:
console.log("Buzz");
break;
case x%5===0 && x%3==0:
console.log("FizzBuzz");
break;
default:
console.log(x);
break;
};
};
Switch matches the x in switch(x){ to the result of evaluating the case expressions. since all your cases will result in true /false there is no match and hence default is executed always.
now using switch for your problem is not recommended because in case of too many expressions there may be multiple true outputs thus giving us unexpected results. But if you are hell bent on it :
for (var x = 0; x <= 20; x++) {
switch (true) {
case (x % 5 === 0 && x % 3 === 0):
console.log("FizzBuzz");
break;
case x % 3 === 0:
console.log("Fizz");
break;
case x % 5 === 0:
console.log("Buzz");
break;
default:
console.log(x);
break;
}
}
I thought switch too,but no need.
for (var n = 1; n <= 100; n++) {
var output = "";
if (n % 3 == 0)
output = "Fizz";
if (n % 5 == 0)
output += "Buzz";
console.log(output || n);
}
Switch statement checks if the situation given in the cases matches the switch expression. What your code does is to compare whether x divided by 3 or 5 is equal to x which is always false and therefore the default is always executed. If you really want to use a switch statement here is one way you can do.
for (var i=1; i<=30; i++){
switch(0){
case (i % 15):
console.log("fizzbuzz");
break;
case (i % 3):
console.log("fizz");
break;
case (i % 5):
console.log("buzz");
break;
default:
console.log(i);
}
}
Not to too my own horn but this is much cleaner:
var numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
for (var i = 1; i <= numbers.length; i++) {
if (i % 15 === 0) {
console.log("FizzBuzz");
} else if (i % 5 === 0) {
console.log("Buzz");
} else if (i % 3 === 0) {
console.log("Fizz");
} else {
console.log(i);
}
};
The switch(true) part of this statement helped me. I was trying to do a switch statement for fizzbuzz. My solution incorporates the coding style of Rosettacodes - general solution. Most significantly the use of force typing to shorten the primary conditionals. I thought, it was valuable enough to post:
var fizzBuzzSwitch = function() {
for (var i =0; i < 101; i++){
switch(true) {
case ( !(i % 3) && !(i % 5) ):
console.log('FizzBuzz');
break;
case ( !(i % 3) ):
console.log('Fizz');
break;
case ( !(i % 5) ):
console.log('Buzz');
break;
default:
console.log(i);
}
}
}
Here's what made it clear for me, might help :
It's a misinterpretation of what switch (x){} means.
It doesn't mean : "whenever whatever I put inbetween those brackets is true, when the value of x changes."
It means : "whenever x EQUALS what I put between those brackets"
So, in our case, x NEVER equals x%3===0 or any of the other cases, that doesn't even mean anything. x just equals x all the time. That's why the machine just ignores the instruction. You are not redefining x with the switch function. And what you put inbetween the brackets describes x and x only, not anything related to x.
In short :
With if/else you can describe any condition.
With switch you can only describe the different values taken by the variable x.
Here's a solution incorporating #CarLuvr88's answer and a switch on 0:
let fizzBuzz = function(min, max){
for(let i = min; i <= max; i++){
switch(0){
case i % 15 : console.log('FizzBuzz'); break;
case i % 3 : console.log('Fizz'); break;
case i % 5 : console.log('Buzz'); break;
default : console.log(i); break;
}
}
}
fizzBuzz(1,20)
We can use a function to find a multiple of any number and declare two variables to identify these multiples so that if you want to change the multiples you only need to change at max 2 lines of code
function isMultiple(num, mod) {
return num % mod === 0;
}
let a = 3;
let b = 5;
for(i=0;i<=100;i++){
switch(true){
case isMultiple(i,a) && isMultiple(i,b):
console.log("FizzBuzz")
case isMultiple(i,a):
console.log("Fizz");
case isMultiple(i,b):
console.log("Buzz");
default:
console.log(i);
}
}

Categories

Resources