非常有趣的問題。 +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()方法,而不是直接調用該函數,原因是應用( )允許您將數組元素作爲參數列表傳遞給函數。
我相信這應該適用於4x4或更高的matrics,儘管我沒有測試它們。
我沒有多少時間來測試解決方案,所以請讓我知道,如果你發現任何錯誤。
我假設,對於tic-tac-toe,在「解決方案」模式中,你不想匹配零而是空單元格。 – akuhn 2012-11-23 19:18:37
您可以嘗試將數組轉換爲1級深度以使比較更容易。但是我不知道任何數組的淺薄片段...... :( – ajax333221 2012-11-24 17:38:12