Теперь пришла пора написать код, который будет определять победу и выводить имя победителя.
Обдумав задачу, можно сообразить, что проверку на наличие победы следует выполнять в каждом ходу:
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);
// здесь мы должны проверять победу или ничью
i++;
});
}
}
Давайте сделаем функцию isVictory
,
которая параметром будет принимать массив
ячеек и возвращать true
, если на поле
есть победа, и false
, если нет. Мы
будем пользоваться этой функцией следующим
образом:
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('имя победителя');
}
i++;
});
}
}
Как же нам узнать имя победителя? Очевидно,
что его имя хранится в каждой из победивших
ячеек. Поясню: если у нас есть победа, то
это значит что некоторые 3
ячейки
по горизонтали, вертикали или диагонали содержат
одинаковое значение: либо крестик, либо нолик.
Очевидно, что значение любой из эти ячеек и есть имя победителя. Но можно пойти и другим, менее очевидным путем: так как мы определяем наличие победы каждый ход, то логично, что победителем будет игрок, совершивший последний ход. Имя этого игрока содержится в тексте кликнутой ячейки:
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); // выводим имя победителя
}
i++;
});
}
}
Реализация isVictory
Как же нам технически определить наличие победы на поле? Если хорошо все обдумать, то можно прийти к выводу, что на поле ограниченное количество троек ячеек.
То есть для проверки победы можно просто проверить все эти тройки. Нужно проверять на то, что тройки имеют одинаковые не пустые значения (то есть там либо крестик, либо нолик).
Сделаем двухмерный массив, в каждом подмассиве которого будут номера ячеек одной из троек:
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],
];
Напишем с помощью этого массива определение победы:
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;
}
Самостоятельно, не подсматривая в мой код, реализуйте описанное. Проверьте, как функционирует игровой процесс.
Попробуйте реализовать проверку ничьей. В следующем уроке будет разбор этого места.