运行几次后未定义的索引

时间:2014-03-25 13:28:43

标签: javascript arrays undefined

因此,我试图在javascript中创建自己的二十一点用于学习目的,即使代码整体有效,我也遇到了一个奇怪的错误。

点击调用函数Deal的{​​{1}} html按钮后,我会在第114或118行收到deal()playerHand[i] undefined未定义错误,分别在下面发布的代码。

我注意到如果因为某种原因我非常快地点击按钮也会发生这种情况。 我怀疑它与内存优化有关,所以我使用dealerHand[i]命令在游戏转弯之间重置这些数组,但错误仍然存​​在。

那么,为什么我的数组在使用后会中断?

感谢。

JS:

delete

CSS:

var deck = [];

var dealerHand = [];
var playerHand = [];

var dscore = 0;
var pscore = 0;

var turn = 0;

function Card(suit, src) {
    this.src = src;
    this.suit = getSuit(suit);
    this.value = getValue(src);
};

function getSuit(suit) {
    if (suit == 1) return "Clubs";
    if (suit == 2) return "Diamonds";
    if (suit == 3) return "Hearts";
    if (suit == 4) return "Spades";
};

function getValue(src) {
    if (src == 1) return 11;
    if (src < 10) return src;
    else return 10;
};

function createDeck() {
    for (i=1; i<=4; i++) {
        for(j=1; j<=13; j++) {
            var card = new Card(i, j);
            deck.push(card);
        };
    };
};

function getCard() {
    var rand = Math.floor(Math.random()*deck.length);
    deck.splice(rand,1);
    return deck[rand];
};

function deal() {
    if(turn == 0) {
        dealerHand.push(getCard());
        playerHand.push(getCard());
    };
    dealerHand.push(getCard());
    playerHand.push(getCard());
};

function stand() {
    dealerHand.push(getCard());
};

function clearBoard () {
    $('#player').html("");
    $('#dealer').html("");
};

function resetDeck () {
    delete deck;
    deck = [];
};

function resetHands () {
    delete dealerHand;
    delete playerHand;
    dealerHand = [];
    playerHand = [];
};

function resetScore () {
    pscore = 0;
    dscore = 0;
};

function isAce (arr) {
    for(i=0; i<arr.length; i++) {
        if (arr[i].src == 1) return true;
        else return false;
    };
}

function updateScore() {
    resetScore();

    if (playerHand.length > 0 && dealerHand.length > 0) {
        for(i=0; i<playerHand.length; i++) {
            pscore += playerHand[i].value;
        };

        for(i=0; i<dealerHand.length; i++) {
            dscore += dealerHand[i].value;
        };

        //Regra do Às
        if(pscore > 21 && isAce(playerHand)) {
            pscore -= 10;
        };

        if(dscore > 21 && isAce(dealerHand)) {
            dscore -= 10;
        };
    } else {
        pscore = 0;
        dscore = 0;
    };
};

function showScore () {
    $('#pscore').html("<p>Player Score: " + pscore + "</p>");
    $('#dscore').html("<p>Dealer Score: " + dscore + "</p>");
};

function showCards () {
    for(i=0; i<playerHand.length; i++) {
        var div = $("<div>");
        var img = $("<img>");
        img.attr('src', 'img/cards/' + playerHand[i].suit + '/' + playerHand[i].src + '.png');
        div.append(img);

        $('#player').append(div);
    };

    for(i=0; i<dealerHand.length; i++) {
        var div = $("<div>");
        var img = $("<img>");
        img.attr('src', 'img/cards/' + dealerHand[i].suit + '/' + dealerHand[i].src + '.png');
        div.append(img);

        $('#dealer').append(div);
    };
};

function cleanUp () {
    if (pscore == 21) {
        alert("Blackjack!");
        newGame();
    };

    if (pscore > 21) {
        alert("Bust!");
        newGame();
    };

    if (dscore == 21) {
        alert("You lost!");
        newGame();
    };

    if (dscore > 21) {
        alert("You won!");
        newGame();
    };
};

function newGame () {
    turn = 0;
    clearBoard();
    resetHands();
    resetScore();
    showScore();
    resetDeck();
    createDeck();
};

function gameTurn () {
    clearBoard();
    updateScore();
    showCards();
    showScore();
    cleanUp();
    turn++;
};

$(document).ready(function() {
    newGame();

    $('#deal').on('click', function(){
        deal();
        gameTurn();
    });

    $('#stand').on('click', function(){
        stand();
        gameTurn();
    });
});

HTML:

body {
    background: url(../img/greenbg.png);
}

.holder { 
    width:800px;
    margin:auto;
}

.clearfix { 
    clear:both;
}

#pscore, #dscore {
    color: white;
    margin: 10px;
    display: block;
    font-size: 1.2rem;
    text-shadow: 0 0 5px #000;
}

.container {
    width: 600px;
    height: 300px;
    margin: 10px;
}

div img {
    float: left;
    margin: 10px;
}

div button {
    margin: 10px;
}

1 个答案:

答案 0 :(得分:4)

您在此功能中遇到问题,这可能是罪魁祸首:

function getCard() {
    var rand = Math.floor(Math.random()*deck.length);
    deck.splice(rand,1);
    return deck[rand];
};

如上所述,它正在移除一张卡片,然后将卡片现在返回到卡片中。如果rand是数组中的最后一个元素,则该位置不再存在卡片,因此它将返回undefined

您应该返回已删除卡片本身的价值,这是splice电话结果的一部分:

function getCard() {
    var rand = Math.floor(Math.random() * deck.length);
    var pick = deck.splice(rand, 1);
    return pick[0];
};

P.S。值得为数组学习现代ES5实用程序功能。例如,您的isAce函数可以被重写,从而避免在测试第一个元素后始终return的错误:

function isAce(arr) {
    return arr.some(function(n) {
        return n === 1;
    });
};

或更干净:

function isAce(card) {
    return card === 1;        // test a single card
};

function holdsAce(hand) {
    return hand.some(isAce);  // test an array (or hand) of cards
};