Leahcim
Leahcim

Reputation: 41919

Why is this code returning NaN?

blackjack game: I made the deal function below that's supposed to return a random number between 1-4 which represents a suit, as well as another random number between 1-3 which represents a card number.

when I test the code by calling console.log(getSuit(card1)); it returns NaN

Anyone know why?

// Make your card constructor again here, but make sure to use private
// variables!
function Card(num, suit){
    var num = num; 
    var suit = suit;
    getSuit = function(){
        return suit; 
    }; 
    getNumber = function(){
        return num; 
    };

    getValue = function(card){
        if (card > 10){
            return 10; 
        }else if (card === 1){
            return 11; 
        }else{
            return card; 
        }

    };

}

// Make a deal function here.  It should return a new card with a suit
// that is a random number from 1 to 4, and a number that is a random
// number between 1 and 13

var deal = function(){
    var suit = Math.floor(Math.random * 4 + 1);
    var number = Math.floor(Math.random * 13 + 1);
    return new Card(number, suit); 
}; 


// examples of the deal function in action
var card1 = deal();
var card2 = deal();

console.log(getSuit(card1));

Upvotes: 0

Views: 5783

Answers (7)

jfriend00
jfriend00

Reputation: 707178

You have three separate things to fix:

  1. You need parens on Math.random().
  2. You need to call getSuit() like this card1.getSuit() not how you were doing it.
  3. You need to acutally make getSuit, getNumber and getValue be methods of the Card object. As you have declared it so far, they are just local functions inside of the Card constructor and cannot be called from outside that constructor.

There are two common ways of making those functions methods. One is to assign them to the Card prototype object. The other is to assign them to this in the constructor.

Here's what it looks like to assign them to the prototype object:

function Card(num, suit){
    this.num = num; 
    this.suit = suit;
}

Card.prototype = {
     getSuit: function() {
         return suit;
     },
     getNumber: function() {
         return num;
     },
     getValue: function(card) {
        if (card > 10){
            return 10; 
        }else if (card === 1){
            return 11; 
        }else{
            return card; 
        }
    }
};

// Make a deal function here.  It should return a new card with a suit
// that is a random number from 1 to 4, and a number that is a random
// number between 1 and 13

var deal = function(){
    var suit = Math.floor(Math.random() * 4 + 1);
    var number = Math.floor(Math.random() * 13 + 1);
    return new Card(number, suit); 
}; 


// examples of the deal function in action
var card1 = deal();
var card2 = deal();

console.log(card1.getSuit());

If you want num and suit to remain private variables, then you have to define the methods inside of Card like this:

// Make your card constructor again here, but make sure to use private
// variables!
function Card(num, suit){
    var num = num; 
    var suit = suit;
    this.getSuit = function(){
        return suit; 
    }; 
    this.getNumber = function(){
        return num; 
    };

    this.getValue = function(card){
        if (card > 10){
            return 10; 
        }else if (card === 1){
            return 11; 
        }else{
            return card; 
        }

    };

}

// Make a deal function here.  It should return a new card with a suit
// that is a random number from 1 to 4, and a number that is a random
// number between 1 and 13

var deal = function(){
    var suit = Math.floor(Math.random() * 4 + 1);
    var number = Math.floor(Math.random() * 13 + 1);
    return new Card(number, suit); 
}; 


// examples of the deal function in action
var card1 = deal();
var card2 = deal();

console.log(card1.getSuit());

Upvotes: 0

Nicholas Albion
Nicholas Albion

Reputation: 3284

Try this:

// Make your card constructor again here, but make sure to use private 
// variables!
function Card(num, suit){
    // NOTE: "this."
    this.num = num;
    this.suit = suit;
    this.getSuit = function(){
        return this.suit;
    };
    this.getNumber = function(){
        return this.num;
    };

    this.getValue = function(card){
        if (card > 10){
            return 10;
        }else if (card === 1){
            return 11;
        }else{
            return card;
        }
    };
}

// Make a deal function here.  It should return a new card with a suit
// that is a random number from 1 to 4, and a number that is a random
// number between 1 and 13   
var deal = function(){
    // NOTE: Math.random()
    var suit = Math.floor(Math.random() * 4 + 1);
    var number = Math.floor(Math.random() * 13 + 1);
    return new Card(number, suit);
};

// examples of the deal function in action
var card1 = deal();
var card2 = deal();

// NOTE: card1.getSuit()
console.log(card1.getSuit());

Upvotes: 0

Neil
Neil

Reputation: 55382

This version preserves the use of private variables. Note that the function arguments are automatically private variables, so you don't need to redeclare them.

function Card(num, suit) {
    this.getSuit = function() {
        return suit;
    }; 
    this.getNumber = function() {
        return num;
    };
    this.getValue = function() {
        if (num > 10)
            return 10;
        if (num == 1)
            return 11;
        return num;
    };
}

Upvotes: 0

Gerard Sexton
Gerard Sexton

Reputation: 3200

You had some compounding issues, but the reason you were getting a NaN was from your use of the random function. Please include () after all calls to methods/functions.

Other changes were made to the Card class. this. assigns the variable to that class instance. Same applies to the functions. So this changes the way you call getSuit(), as a method call. It worked before because your getSuit() was being put into the global namespace.

function Card(num, suit){
    this.num = num; 
    this.suit = suit;
    this.getSuit = function(){
        return suit; 
    }; 
    this.getNumber = function(){
        return num; 
    };

    this.getValue = function(card){
        if (card > 10){
            return 10; 
        }else if (card === 1){
            return 11; 
        }else{
            return card; 
        }

    };

}

var deal = function(){
    var suit = Math.floor(Math.random() * 4 + 1);
    var number = Math.floor(Math.random() * 13 + 1);
    return new Card(number, suit); 
}; 


// examples of the deal function in action
var card1 = deal();
var card2 = deal();

console.log(card1.getSuit());

Upvotes: 1

Eduardo Almeida
Eduardo Almeida

Reputation: 171

Just add the () after the random

var deal = function() {
    var suit = Math.floor(Math.random() * 4 + 1);
    var number = Math.floor(Math.random() * 13 + 1);
    return new Card(number, suit);
}; 

Upvotes: 4

TMan
TMan

Reputation: 1905

Shouldn't you be calling:

console.log(card1.getSuit());

?

Upvotes: 1

Lee Taylor
Lee Taylor

Reputation: 7984

Change:

var num = num; 
var suit = suit;

to

this.num = num; 
this.suit = suit;

etc.

Upvotes: 0

Related Questions