Now it's time to write the code that will determine the win and display the name of the winner.
Thinking about the problem, you can realize that the check for win should be performed in each turn:
function init(selector) {
let cells = document.querySelectorAll('#field td');
let i = 0;
for (let cell of cells) {
cell.addEventListener('click', function step() {
this.textContent = ['X', 'O'][i % 2];
this.removeEventListener('click', step);
// here we have to check for win or draw
i++;
});
}
}
Let's make the isVictory
function that
accepts an array of cells as a parameter and
returns true
if there is a victory on
the field, and false
if not. We will
use this function as follows:
function start(cells) {
let i = 0;
for (let cell of cells) {
cell.addEventListener('click', function step() {
this.textContent = ['X', 'O'][i % 2];
this.removeEventListener('click', step);
if (isVictory(cells)) {
alert('winner name');
}
i++;
});
}
}
How do we know the name of the winner? Obviously,
his name is stored in each of the winning cells.
Let me explain: if we have a win, then this means
that some 3
cells horizontally, vertically
or diagonally contain the same value: either an
X or an O mark.
Obviously, the value of any of these cells is the name of the winner. But we can go in another, less obvious way: since we determine the presence of a win every move, it is logical that the winner will be the player who made the last move. The name of this player is contained in the text of the clicked cell:
function start(cells) {
let i = 0;
for (let cell of cells) {
cell.addEventListener('click', function step() {
this.textContent = ['X', 'O'][i % 2];
this.removeEventListener('click', step);
if (isVictory(cells)) {
alert(this.textContent); // displays the winner name
}
i++;
});
}
}
Implementation of isVictory
How can we technically determine the presence of a victory on the field? If you think it over well, then you can come to the conclusion that there is a limited number of cell triplets on the field.
That is, to check for a victory, you can simply check all these triplets. It is necessary to check that the triples have the same non-empty values (that is, there is either a cross or a zero).
Let's make a two-dimensional array, in each subarray of which there will be cell numbers of one of the triples:
let combs = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
Let's write the definition of victory using this array:
function isVictory(cells) {
let combs = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let comb of combs) {
if (
cells[comb[0]].textContent == cells[comb[1]].textContent &&
cells[comb[1]].textContent == cells[comb[2]].textContent &&
cells[comb[0]].textContent != ''
) {
return true;
}
}
return false;
}
On your own, without looking into my code, implement the described. Check how the gameplay works.
Try to implement a draw check. The next lesson will analyze this issue.