0

我正在用 Javascript 开发一个简单的井字游戏。现在,为了检查获胜者,我有一个函数,它首先轮到谁,然后找到他们在板上有 X 或 O 的地方。他们拥有的空格被编号(1-8)并添加到数组中。到现在为止还挺好。

现在我正在尝试比较另一个数组,即包含所有获胜组合的数组:

var winningCombinations = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];

使用测试数组,它应该会成为赢家,因为它包含 2、5 和 8。

我的测试来源:

<script>

    var test = [2,4,5,8]
    var winningCombinations = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];

    for(var x=0; x<winningCombinations.length; x++) {

        if (winningCombinations[x].indexOf(test) > -1) {
            alert("Win!");
        } else {
            alert ("No win.");
        }

    }

</script>

我认为现在它只是测试 [2,4,5,8] 作为一个完整的值 - 而不是内部单个数字的实例。这就是我难过的地方。如何检查测试数组是否以任何顺序匹配任何获胜组合值?

4

4 回答 4

2

试试这个:

var test = [2,4,5,8]
var winningCombinations = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];
var combLength = 0;
for (var i in winningCombinations) {
    combLength = winningCombinations.length;
    for (var j in winningCombinations[i]) {
        if (-1 == test.indexOf(winningCombinations[i][j])) {
            break;
        }
    }

    if (combLength - 1 == j) {
        alert("Win!");
    }
}

在第一个if语句中,我们正在检查当前循环数组中的当前循环项(我知道这看起来很混乱)是否存在于test数组中。如果不是,我们已经知道该test阵列不是获胜阵列。

此外,我建议将所有这些东西包装在这样的函数中:

function isWinner(playerNumbers, winningCombinations) {
    var combLength = 0;
    for (var i in winningCombinations) {
        combLength = winningCombinations.length;
        for (var j in winningCombinations[i]) {
            if (-1 == playerNumbers.indexOf(winningCombinations[i][j]) {
                break;
            }
        }

        if (combLength - 1 == j) {
            return true;
        }
    }

    return false;
}

var test = [2,4,5,8]
var winningCombinations = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];

if (isWinner(test, winningCombinations)) {
    alert("Win!");
} else {
    alert ("No win.");
}
于 2013-10-08T14:36:38.313 回答
1

您真的不是在检查相等性,而是在检查一个数组是否是另一个数组的子集。为此,我建议将 test 更改为 {2: 1, 4: 1, 5: 1, 8: 1} 形式的对象。那些只是为了评估真实,它们并不重要。重要的是关键。

function checkSubset(a, b) {
    //returns true if EVERY element in the array causes the next function to return true
    return a.every(function(e) {
        return !!b[e]; //returns true if b contains e
    });
}

然后调用 checkSubset(winningCombinations[x], test)。话虽如此,有更好的方法来评估井字棋的状态。

于 2013-10-08T14:38:05.057 回答
1

天真的方法只会检查每个组合并确保test包含其中一个组合的每个元素:

var winner = false;

for (var i = 0; i < winningCombinations.length && !winner; i++) {
    var matches = true;

    for(var j = 0; j < winningCombinations[i].length && matches; j++)
        if(test.indexOf(winningCombinations[i][j]) == -1)
            matches = false;

    if(matches)
        winner = true;
}

如果将这些封装在函数中并返回matcheswinner则可以摆脱丑陋的循环条件:

function matchesCombination(test, combination)
{
    for(var i = 0; i < combination.length; i++)
        if(text.indexOf(combination[i]) == -1)
            return false;

    return true;
}

function isWinner(test, combinations)
{
    for(var i = 0; i < combinations.length; i++)
        if(matchesCombination(test, combinations[i])
            return true;

    return false;
}
于 2013-10-08T14:38:29.103 回答
0

这可能不是最好的答案,但在我脑海中,您可以遍历获胜条件中的值并执行一个 if 语句,要求所有 3 个 indexOfs 都为 != -1。

即,对于获胜组合中的每个数组,循环遍历数组中的每个值并执行 test.indexOf(value) 并检查它是否不是-1。如果所有 3 个值都返回不等于 -1,那么您就有获胜条件。

于 2013-10-08T14:34:23.333 回答