1

I'm trying to create a poker game in JavaScript. I thought the function that tested flushes worked perfectly until I displayed the hand AFTER the method ran. If there is a flush, this function is supposed to show the user's full hand, and then only the flush underneath it. Instead, it shows only the flush, and then the flush again underneath it:

var $ = function (id) { return document.getElementById(id); };

var test = function() {
    var deck = new POKER.Deck(); //creates deck
    var hand = new POKER.Hand(); //creates hand
    //----------------TEST HAND UNTIL FLUSH-----------------
    while (hand.getValue() != POKER.HAND_TYPE.FLUSH) {
        deck.refreshDeck(); //refresh deck with new cards
        for (var i = 0; i < 7; ++i) { //populate hand
            hand.addCard(deck.dealCard());
        }

        console.log(hand.size() + " before"); //only for debugging. Prints "7 before"
        hand.testFlush();
        console.log(hand.size() + " after"); //only for debugging. Result unexpected

        if (hand.getValue() == POKER.HAND_TYPE.FLUSH) { //if hand has a flush
            for (var j = 0; j < hand.size(); j++) { //display full hand
                var img = document.createElement("img");
                var card = hand.getCardAtIndex(j);
                img.src = card.getImage();
                $("images").appendChild(img);
            }
            for (var k = 0; k < 5; k++) { //display flush hand
                var img2 = document.createElement("img");
                var card2 = hand.getValueCardAtIndex(k);
                img2.src = card2.getImage();
                $("handImg").appendChild(img2);
            }
            break;
        } else {
            hand.empty();
        }
    }
  
};

window.onload = function() {
    test();
};

The second console.log statement prints out "4 after" until the testFlush method detects a flush, and the final result is "5 after".

testFlush method:

POKER.Hand.prototype.testFlush = function() {
    //first, sort cards by rank so that the highest flush is 
    //taken if there are more than five cards of the same suit
    this.sortByRank();
    this.sortBySuit();
    var tempHand = this.cards; //modifiable version of this.cards
    var NUM_OF_TESTS = 3; //only 3 loops required to test for all possible flushes
    var LAST_CARD_INDEX = 4; //represents the fifth card, or index 4
    var MAX_CARDS = 5; //maximum cards possible in a hand (valueCards)

    for (var i = 1; i <= NUM_OF_TESTS; i++){
        //check if 1st and 5th cards are the same suit
        if(tempHand[0].getSuit() == tempHand[LAST_CARD_INDEX].getSuit()){
            this.value = POKER.HAND_TYPE.FLUSH;
            while(tempHand.length != MAX_CARDS){ //remove last card in tempHand until there are only five cards
                tempHand.pop();
            }
            this.valueCards = tempHand;
        }else{
            tempHand.splice(0,1); //removes first card from the temporary hand
        }
    }
};

All "hand.size()" does in the test function is "return this.cards.length". So what I don't understand is how the testFlush method could be altering the object attribute "this.cards" when it only alters the temporary variable tempHand.

Hand object:

POKER.Hand = function(){
    this.cards = [];
    this.value; //integer that corresponds to the POKER.HAND_TYPE
    this.valueCards = []; //array of the five cards that corresponds only to this.value
};

Hand.size method:

POKER.Hand.prototype.size = function() {
    return this.cards.length;
};

1 Answer 1

3

The problem is this line:

var tempHand = this.cards; //modifiable version of this.cards

Assigning an array or object to a variable does not make a copy of it. The variable is a reference to the same array, so tempHand.pop() modifies this.cards as well. You can make a copy of an array with .slice():

var tempHand = this.cards.slice();
Sign up to request clarification or add additional context in comments.

3 Comments

It might be worth stating that this applies to all objects. The line var temp_var = original_var; will only make a copy of a string or a number.
It's easier to just say that objects and arrays don't get copied, which is how I edited the answer.
That worked. Such a simple solution. So satisfying. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.