Pregunta muy interesante. +1 :) Aquí está mi opinión sobre esto.
Compruebe mi violín http://jsfiddle.net/BuddhiP/J9bLC/ para la solución completa. Trataré de explicar los puntos principales aquí.
Empiezo con una placa como esta. He usado 0 en lugar de -1 porque es más fácil.
var a = 'a', b = 'b';
var board = [
[a, 0, a],
[b, b, b],
[a, 0, a]
];
Mi estrategia es simple.
- Comprueba si alguna de las filas tiene el mismo jugador (aob), de ser así tenemos un ganador.
- Else, Compruebe si alguna de las columnas tiene el mismo jugador
- Else, Compruebe si diagonales tiene un jugador
Esos son los tres casos ganadores.
Primero creé una función que puede tomar un conjunto de filas (Ej: [a, 0, b]), y verifico si toda la fila contiene el mismo valor, y si ese valor no es cero (o -1 en su caso).
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;
};
Aquí toman valores únicos en una fila, y si puedo encontrar un solo valor único que no es cero, el que es el ganador.
Si no hay ningún ganador en las filas, entonces verifico si hay columnas. Para reutilizar mi código, uso el método _.zip() para transformar columnas en filas y luego uso la misma función anterior para verificar si tenemos un ganador.
var board2 = _.zip.apply(this, board);
winner = checkForWinner.apply(this, board2);
Si todavía no encuentro un ganador, es hora de consultar las diagonales. He escrito esta función para extraer dos diagonales del tablero como dos filas, y uso la misma función checkForWinner para ver si las diagonales están dominadas por cualquiera de los jugadores.
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];
};
Por último, este es el que realmente comprobar la junta para un ganador:
// 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);
}
}
Si alguno de ustedes se preguntan por qué uso apply() método en lugar de llamar directamente a la función, la razón es aplicar () le permite pasar elementos de una matriz como una lista de argumentos a una función.
Creo que esto debería funcionar para 4x4 o superior MATRICS también, aunque no he probado ellos.
tenía muy poco tiempo para probar la solución, así que por favor, hágamelo saber si usted encuentra algún error.
que suponer, por un tic-tac-dedo del pie, en los 'patrones disoluciones para que no desea para que coincida con ceros, pero las celdas vacías. – akuhn
puede tratar de convertir las matrices a 1 nivel de profundidad para facilitar la comparación. Pero no sé fragmento de cualquier matriz superficial ... :( – ajax333221