非常有趣的问题。+1 :) 这是我对此的看法。
检查我的小提琴http://jsfiddle.net/BuddhiP/J9bLC/以获得完整的解决方案。我将尝试解释这里的要点。
我从这样的板子开始。我使用 0 而不是 -1 因为它更容易。
var a = 'a', b = 'b';
var board = [
[a, 0, a],
[b, b, b],
[a, 0, a]
];
我的策略很简单。
- 检查任何行是否有相同的玩家(a 或 b),如果是,我们就有赢家。
- 否则,检查任何列是否具有相同的玩家
- 否则,检查对角线是否有玩家
这是三个获胜的案例。
首先,我创建了一个可以获取一组行的函数(例如:[a,0,b]),并检查整行是否包含相同的值,以及该值是否不为零(或在您的情况下为 -1)。
checkForWinner = function () {
lines = Array.prototype.slice.call(arguments);
// Find compact all rows to unique values.
var x = _.map(lines, function (l) {
return _.uniq(l);
});
// Find the rows where all threee fields contained the same value.
var y = _.filter(x, function (cl) {
return (cl.length == 1 && cl[0] !== 0);
});
var w = (y.length > 0) ? y[0] : null;
return w;
};
在这里我连续取唯一值,如果我只能找到一个不为零的唯一值,他就是赢家。
如果行中没有获胜者,我会检查列。为了重用我的代码,我使用 _.zip() 方法将列转换为行,然后使用上面相同的函数来检查我们是否有赢家。
var board2 = _.zip.apply(this, board);
winner = checkForWinner.apply(this, board2);
如果我仍然没有找到赢家,是时候检查对角线了。我编写了这个函数来从棋盘中提取两条对角线作为两行,并使用相同的 checkForWinner 函数来查看对角线是否被任何玩家控制。
extractDiagonals = function (b) {
var d1 = _.map(b, function (line, index) {
return line[index];
});
var d2 = _.map(b, function (line, index) {
return line[line.length - index - 1];
});
return [d1, d2];
};
最后,这是我实际检查董事会是否有获胜者的地方:
// Check rows
winner = checkForWinner.apply(this, board);
if (!winner) {
var board2 = _.zip.apply(this, board);
// Check columns, now in rows
winner = checkForWinner.apply(this, board2);
if (!winner) {
var diags = extractDiagonals(board);
// Check for the diagonals now in two rows.
winner = checkForWinner.apply(this, diags);
}
}
如果有人想知道为什么我使用 apply() 方法而不是直接调用函数,原因是 apply() 允许您将数组元素作为参数列表传递给函数。
我相信这也适用于 4x4 或更高的矩阵,尽管我没有测试它们。
我没有多少时间来测试解决方案,所以如果您发现任何错误,请告诉我。