Reputation: 13583
Current logic works fine with 3x3 board because it is static. How can I convert it into NxN logic?
Win logic works by adding the row and column squares.
/*
* To determine a win condition, each square is "tagged" from left
* to right, top to bottom, with successive powers of 2. Each cell
* thus represents an individual bit in a 9-bit string, and a
* player's squares at any given time can be represented as a
* unique 9-bit value. A winner can thus be easily determined by
* checking whether the player's current 9 bits have covered any
* of the eight "three-in-a-row" combinations.
*
* 273 84
* \ /
* 1 | 2 | 4 = 7
* -----+-----+-----
* 8 | 16 | 32 = 56
* -----+-----+-----
* 64 | 128 | 256 = 448
* =================
* 73 146 292
*
*/
wins = [7, 56, 448, 73, 146, 292, 273, 84],
/*
* Returns whether the given score is a winning score.
*/
win = function (score) {
for (var i = 0; i < wins.length; i += 1) {
if ((wins[i] & score) === wins[i]) {
return true;
}
}
return false;
},
My fiddle is here
Upvotes: 3
Views: 4511
Reputation: 30099
So, to do it programatically, you can use classes to keep track of what "set" each cell is in, i.e. "row1" or "col1":
In i
/j
creation loops:
cell.addClass('col' + j); // The cell is in column j
cell.addClass('row' + i); // The cell is in row i
if (i == j) {
cell.addClass('dia0'); // The cell is in the down/right diagonal
}
if (j == SIZE - i - 1) {
cell.addClass('dia1'); // The cell is in the up/right diagonal
}
Then, in win()
, pass in the last cell clicked. For each class the cell belongs to, check if the number of cells with that class containing X
(or O
) is equal to the table size:
win = function (clicked) {
// Get all of the classes this cell belongs to
var memberOf = clicked[0].className.split(/\s+/);
// Check elements with the same class, and see if they contain "turn", i.e. X or O
for (var i=0; i<memberOf.length; i++) {
var testClass = '.'+memberOf[i];
// If the number of elements containing "turn" == SIZE,
// we have a winning condition
if( $('#tictactoe').find(testClass+':contains('+turn+')').length == SIZE) {
return true;
}
}
return false;
},
Upvotes: 2
Reputation: 50807
This matches your list for three, and I've checked two by hand. It certainly seems right, as the code is really dead simple, but you'll probably want to check it over:
var getWins = function(size) {
var val = 1, cells = [], wins = [];
for (var i = 0; i < size; i++) {
cells[i] = [];
for (var j = 0; j < size; j++) {
cells[i][j] = val;
val *= 2;
}
}
var rowWins = [], colWins = [], mainDiagWin = 0, antiDiagWin = 0;
for (i = 0; i < size; i++) {
rowWins[i] = 0;
colWins[i] = 0;
mainDiagWin += cells[i][i];
antiDiagWin += cells[i][size - i - 1];
for (j = 0; j < size; j++) {
rowWins[i] += cells[i][j];
colWins[i] += cells[j][i];
}
}
return rowWins.concat(colWins, mainDiagWin, antiDiagWin);
};
getWins(2);
//=> [3, 12, 5, 10, 9, 6]
getWins(3);
//=> [7, 56, 448, 73, 146, 292, 273, 84]
getWins(4)
//=> [15, 240, 3840, 61440, 4369, 8738, 17476, 34952, 33825, 4680]
Upvotes: 0