0
\$\begingroup\$

I'm working on the card game "war" and I'm noticed an issue. When both players have different sized hands and one player reshuffles, the size of the master deck resizes. This is an issue because the master deck needs to stay the same size throughout the entire game so a winner can be decided on. Can anyone explain to me why and how to fix it? You'll notice it happening if you open the console and watch the log. The second time one player reshuffles, the deck gets smaller.

Fiddle

JS

var play = document.getElementById("play");
var reshuffle = document.getElementById("reshuffle");
var cardHolder = document.getElementsByClassName("cardHolder");
var wonCardsHolder = document.getElementsByClassName("wonCardsHolder");

play.onclick = function(){
    PlayGame(Player1, Player2);
}
Player = function(name, currentDeck, wonDeck){
    this.name = name;
    this.currentDeck = currentDeck;
    this.wonDeck = wonDeck;
}
Player.prototype.GetCurrentCard = function(){
    this.currentCard = this.currentDeck.shift();
}
Player.prototype.isReshuffling = false;
Deck = {
    //suits: ["Clubs", "Diamonds", "Hearts", "Spades"],
    suits: ["Spades", "Clubs"],
    cards: [14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
    deck: [],
    shuffledDeck: [],
    BuildDeck: function(){
        for(var suit = 0; suit < this.suits.length; suit++){
            for(var card = 0; card < this.cards.length; card++){
                this.deck.push([this.cards[card], this.suits[suit]]);
            }
        }
    },
    ShuffleDeck: function(){
        while(this.deck.length){
            var index = Math.floor(Math.random() * this.deck.length); 
            this.shuffledDeck.push(this.deck.splice(index, 1)[0]);    
        }
    },
    DistributeCards: function(player1Deck, player2Deck){
        for(var i = 0; i < this.shuffledDeck.length / 2; i++){
            player1Deck.push(this.shuffledDeck[i]);
            player2Deck.push(this.shuffledDeck[this.shuffledDeck.length - i - 1]);
        }
    },
    ReshuffleDeck: function(player){
        while(player.wonDeck.length){
            var index = Math.floor(Math.random() * player.wonDeck.length);
            player.currentDeck.push(player.wonDeck.splice(index, 1)[0]);
        }
        player.wonDeck = [];
    }
}
PlayGame = function(player1, player2){
    player1.GetCurrentCard();
    player2.GetCurrentCard();
    if(player1.currentCard == undefined){
        player1.isReshuffling = true;
    }
    if(player2.currentCard == undefined){
        player2.isReshuffling = true;
    }
    GoToWar = function(){
        console.log("War");
        var player1WarDeck = [];
        var player2WarDeck = [];
        player1WarDeck.push(player1.currentCard);
        player1.GetCurrentCard();
        player1WarDeck.push(player1.currentCard);
        player1.GetCurrentCard();
        player1WarDeck.push(player1.currentCard);

        player2WarDeck.push(player2.currentCard);
        player2.GetCurrentCard();
        player2WarDeck.push(player2.currentCard);
        player2.GetCurrentCard();
        player2WarDeck.push(player2.currentCard);

        if(player1WarDeck[player1WarDeck.length - 1][0] == player2WarDeck[player2WarDeck.length - 1][0]){
            console.log("Tie");
            player1.GetCurrentCard();
            player1WarDeck.push(player1.currentCard);
            player1.GetCurrentCard();
            player1WarDeck.push(player1.currentCard);

            player2.GetCurrentCard();
            player2WarDeck.push(player2.currentCard);
            player2.GetCurrentCard();
            player2WarDeck.push(player2.currentCard);
        }
        if(player1WarDeck[player1WarDeck.length - 1][0] > player2WarDeck[player2WarDeck.length - 1][0]){
            player1.wonDeck = player1.wonDeck.concat(player1WarDeck, player2WarDeck);
            console.log("Player 1 wins");
        }
        else{
            player2.wonDeck = player2.wonDeck.concat(player1WarDeck, player2WarDeck);
            console.log("Player 2 wins");
        }
    }
    if(!player1.isReshuffling && !player2.isReshuffling){
        if(player1.currentCard[0] == player2.currentCard[0]){
            GoToWar();
        }
        else if(player1.currentCard[0] > player2.currentCard[0]){
            player1.wonDeck.push(player1.currentCard);
            player1.wonDeck.push(player2.currentCard);
        }
        else{
            player2.wonDeck.push(player2.currentCard);
            player2.wonDeck.push(player1.currentCard);
        }
    }
    if(player1.isReshuffling){
        ReshuffleDeck(player1);
        player1.isReshuffling = false;
    }
    if(player2.isReshuffling){
        ReshuffleDeck(player2);
        player2.isReshuffling = false;
    }
    if(player1.currentDeck.length == 26){
        GameOver(player1);
    }
    if(player2.currentDeck.length == 26){
        GameOver(player2);
    }
    console.log(player1.currentDeck.length + player1.wonDeck.length + player2.currentDeck.length + player2.wonDeck.length)
    cardHolder[0].textContent = player1.currentCard[0] +" of " +player1.currentCard[1];
    cardHolder[1].textContent = player2.currentCard[0] +" of " +player2.currentCard[1];
    wonCardsHolder[0].textContent = player1.wonDeck.length;
    wonCardsHolder[1].textContent = player2.wonDeck.length;
}
ReshuffleDeck = function(player){
    Deck.ReshuffleDeck(player)
}
GameOver = function(player){
    console.log(player.name +" wins!");
}
Player1 = new Player("Player 1", [], []);
Player2 = new Player("Player 2", [], []);
Deck.BuildDeck();
Deck.ShuffleDeck();
Deck.DistributeCards(Player1.currentDeck, Player2.currentDeck);
\$\endgroup\$
1
\$\begingroup\$

Your problem comes from the fact that you do

player1.GetCurrentCard();
player2.GetCurrentCard();

even in the case where you have to shuffle.

When player 1 still has cards in his hand but player 2 has none, you will discard a card from player 1 hand, then shuffle player 2 hand, then start the loop again, which means the discarded card from player 1 is lost in the process.

\$\endgroup\$
  • \$\begingroup\$ So, I should move these two function calls into the if(!player1.isReshuffling && !player2.isReshuffling){ block? \$\endgroup\$ – Robert Feb 20 '17 at 17:25
  • \$\begingroup\$ You start by trying that yes. I do not know if it is gonna work directly just like that, maybe you need some few adjustments in your logic, but the problem is definitly what I said in the second paragraph of my answer \$\endgroup\$ – realUser404 Feb 20 '17 at 17:31
  • \$\begingroup\$ Tried it, I keep getting a TypeError that it can't read property "0" of undefined. I'm going to tinker around with the logic and try to see what's going on. \$\endgroup\$ – Robert Feb 20 '17 at 17:34
  • \$\begingroup\$ So I found out that each player's isReshuffling is being set to true each time the play button is clicked for some reason \$\endgroup\$ – Robert Feb 20 '17 at 17:38
0
\$\begingroup\$

I found out the issue. As @realUser404 mentioned in his/her answer, the issue was in the logic. Regardless of whether the player was reshuffling or not, the play button was always getting a new card for each player, which meant, when one player was reshuffling, the player that wasn't was still playing, and therefore, discarding a card. Another issue was this block:

if(player1.currentCard == undefined){
    player1.isReshuffling = true;
}
if(player2.currentCard == undefined){
    player2.isReshuffling = true;
}

The player's hand is going to be undefined when play starts, so this was always being set to true the first time the play button was clicked, which called the ReshuffleDeck() function the first time. Rather than have a check on the current card, the if statements needed to be changed to:

if(player1.currentDeck.length == 0){
    player1.isReshuffling = true;
}
if(player2.currentDeck.length == 0){
    player2.isReshuffling = true;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.