重启功能会产生意外结果

时间:2013-06-11 03:21:34

标签: javascript jquery function variables

我正在创建一个简单的井字游戏,我有一个按钮,当点击它时会重置受clickHandler函数影响的所有变量并清除表格单元格中的元素,从而重新启动游戏。然而,当在游戏结束之前开始新游戏时,游戏开始说X和O已经到达相同的单元并且跳过转弯。这段代码有什么问题,为什么它会像这样? 如果你想直接测试结果,这是小提琴。 http://jsfiddle.net/YdRLg/

//Creates the variables needed to be manipulated later
var X = 'X';
var O = 'O';
var currentPlayer;
var turnCount = 0;
var xMoves = [];
var oMoves = [];
var cellTracker;
var winAlert;
var winConditions = [
    ['c1', 'c2', 'c3'],
    ['c4', 'c5', 'c6'],
    ['c7', 'c8', 'c9'],
    ['c1', 'c4', 'c7'],
    ['c2', 'c5', 'c8'],
    ['c3', 'c6', 'c9'],
    ['c1', 'c5', 'c9'],
    ['c3', 'c5', 'c7']
];
var button = $('button');

/*Set's the current player to X if turnCount is odd
And to O if turnCount is even*/
var setCurrentPlayer = function () {
    if (turnCount % 2 === 0) {
        currentPlayer = O;
    } else {
        currentPlayer = X;
    }
};

//Pushes cellTracker's value to the curent player's move variable
var storeMoves = function () {
    if (currentPlayer === X) {
        xMoves.push(cellTracker);
    } else if (currentPlayer === O) {
        oMoves.push(cellTracker);
    }
};

//Compares players moves with the winConditions to determine a winner
var determineWin = function (pMoves) {
    for (var i = 0; i < winConditions.length; i++) {
        if (winConditions[i].length > pMoves.length) {
            continue;
        }
        for (var j = 0; j < winConditions[i].length; j++) {
            winAlert = false;
            for (var k = 0; k < pMoves.length; k++) {
                if (pMoves[k] === winConditions[i][j]) {
                    winAlert = true;
                    break;
                }

            }
            if (!winAlert) break;
        }
        if (winAlert) {
            alert(currentPlayer + " wins!");
            break;
        }
    }
};

//Determines if the game is over
var determineEnd = function () {
    if (turnCount === 9 && winAlert === false) {
        alert("Tie game!");
    }
    if (winAlert === true) {
        $('td').off('click.mygame', clickHandler);
    }
};

//Calls the above functions to simulate the game
var clickHandler = function () {
    turnCount += 1;
    setCurrentPlayer();
    $(this).text(currentPlayer);
    cellTracker = $(this).attr('id');
    storeMoves();
    determineWin(currentPlayer == 'X' ? xMoves : oMoves);
    determineEnd();
    console.log(turnCount, xMoves, oMoves, winAlert);
};

//Calls the clickHandler function when a cell is clicked
$('td').one('click.mygame', clickHandler);

//Starts a new game when the New Game button is clicked
$('button').bind('click', function () {
    $('td').empty();
    turnCount = 0;
    xMoves = [];
    oMoves = [];
    winAlert = false;
    $('td').one('click.mygame', clickHandler);
});

1 个答案:

答案 0 :(得分:3)

这是因为你没有在重新启动游戏时删除所有事件处理程序

$('button').bind('click', function () {
    $('td').empty();
    turnCount = 0;
    xMoves = [];
    oMoves = [];
    winAlert = false;
    $('td').off('click.mygame')
    $('td').one('click.mygame', clickHandler);
});

ie:当你开始游戏时,你为所有tds注册clickHandler,然后你点击其中几个导致它们被移除但其他仍然存在于事件注册表中。然后通过向所有tds添加一组事件处理程序来重新启动游戏,这意味着现在一些tds已经注册了两个clickHandler。您可以在console.log('clicked')方法

中添加clickHandler来测试它

演示:Fiddle