非常に興味深い質問です。+1:)これが私の見解です。
完全な解決策については、私のフィドルhttp://jsfiddle.net/BuddhiP/J9bLC/を確認してください。ここで要点を説明しようと思います。
私はこのようなボードから始めます。簡単なので、-1ではなく0を使用しました。
var a = 'a', b = 'b';
var board = [
[a, 0, a],
[b, b, b],
[a, 0, a]
];
私の戦略は単純です。
- いずれかの行に同じプレーヤー(aまたはb)があるかどうかを確認します。同じプレーヤーがいる場合は、勝者がいます。
- それ以外の場合は、列のいずれかに同じプレーヤーがあるかどうかを確認します
- それ以外の場合は、対角線にプレーヤーがいるかどうかを確認します
これらが3つの勝利事例です。
最初に、行のセット(例:[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;
};
ここでは、一意の値を続けて取得します。ゼロではない一意の値が1つだけ見つかった場合は、彼が勝者です。
行に勝者がいない場合は、列を確認します。コードを再利用するために、_。zip()メソッドを使用して列を行に変換してから、上記と同じ関数を使用して勝者がいるかどうかを確認します。
var board2 = _.zip.apply(this, board);
winner = checkForWinner.apply(this, board2);
それでも勝者が見つからない場合は、対角線を確認してください。この関数は、ボードから2つの対角線を2行として抽出し、同じ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以上のマトリックスでも機能するはずだと思います。
ソリューションをテストする時間がほとんどなかったので、エラーが見つかった場合はお知らせください。