Игра Жизнь — это клеточный автомат созданный в 1970 году Джоном Конвеем
Это не совсем игра, а просто симуляция клеток по определенным правилам.От игрока лишь требуется размещать эти клетки.
В этом посте мы сделаем «Игру Жизнь» на HTML странице при помощи CSS & JS
Правила
Клетка — она может быть либо живой (темной), либо мертвой (белой).
У клетки есть 8 соседей вокруг и могут влиять на нее.
Если клетка мертва и у нее есть 3 живых соседа, тогда она рождается.
Если клетка жива и у нее есть 2 или 3 соседа, то она остается живой.В противном случае умирает от перенаселения или одиночества
Пишем главную страницу:
Создаем базовый код HTML и подключаем к нему .css и .js
Обозначим главный блок div в котором будут находится все клетки:
<div class="mainBox"></div>
.mainBox { border: solid 3px #000000; display: flex; flex-wrap: wrap; width: 45%; height: 83%; margin: 4% 26%; position: fixed; justify-content: flex-start; }
Внутрь mainBox создаем 256 штук:
<div class="cellBox"></div>
Также сразу же даем класс deathCell и функцию onclick=»aliveButtons(this)» для того чтобы в будущем оживлять клетки на которые мы нажимаем
Должно выйти так:
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
Даем стили:
.cellBox { /* Стили клеток */ display: block; width: 5.77%; height: 5.75%; border: solid 2px #808080; background-color: #ffffff; } .deathCell { /* Класс мертвой клетки */ background-color: #ffffff; } .aliveCell { /* Класс живой клетки */ background-color: #2c2c2c; }
Делаем возможность оживлять/убивать кнопки:
В первую очередь сделаем визуальное выделение, чтобы пользователь знал, что на клетки можно нажимать
Для этого воспользуемся :hover
.cellBox:hover { background-color: #000000; cursor: pointer; }
Теперь перейдем на JS и воспользуемся нашими функциями aliveButtons(this)
function aliveButtons(obj) { // получаем через (this) нажатую клетку if (obj.classList.contains("deathCell")) { // проверяем мертва ли клетка // оживляем клетку obj.classList.add("aliveCell") // добавляем класс aliveCell obj.classList.remove("deathCell") // убираем класс deathCell } else if (obj.classList.contains("aliveCell")) { // тоже самое, только наоборот // убиваем клетку obj.classList.add("deathCell") obj.classList.remove("aliveCell") } }
Теперь мы можем оживлять и убивать клетки
Пишем JS скрипт:
Для начала стоит получить все наши клетки:
cellBoxes = document.querySelectorAll(".cellBox") // получаем всех через класс
Теперь сделаем главную функцию обновления кадров, чтобы мы могли управлять скоростью всей симуляции
function framesUpdate() { setTimeout(function () { // цикличная функция framesUpdate() // вызываем ее вновь }, 1000) // задержка 1-секунда } framesUpdate() // Вызов нашей функции при запуске. Вставляем в конце кода!
Теперь самое интересное.Создаем функцию для определения соседских клеток и заодно в нее засунем правила
function neighborCheck() {}
Задаем универсальный цикл для проверки всех клеток
function neighborCheck() { for (var i = 0; i < Object.keys(cellBoxes).length; i++) { // сравниваем i с общим кол-вом наших клеток } }
Т.к. наша переменная cellBoxes является многомерным массивом, мы можем обратиться в ее каждую клетку и работать с ними
Сейчас мы зададим еще одну переменную в каждой клетке используя цикл
cellBoxes[i].alivedNeighbor = 0 // вначале мы задаем ей значение 0, но в следующие разы просто обновляем ее
Проверяем соседей.Для этого просто будем использовать вычитание
if (i - 17 >= 0) { //Проверка, чтобы мы не проверяли если у блока нет соседей выше if (cellBoxes[i - 17].classList.contains("aliveCell")) // проверяем жива ли клетка { cellBoxes[i].alivedNeighbor += 1 // добавляем +1 к кол-ву живых соседей нашей клетки } } if (i - 16 >= 0) { // у нас клетки 16х16 размером, поэтому чтобы проверить верхнюю левую, надо вычислить 17 клеток назад, чтобы верхнюю 16 if (cellBoxes[i - 16].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i - 15 >= 0) {// тоже самое тут, но уже 15 и т.д. if (cellBoxes[i - 15].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i - 1 >= 0) { // чтобы полностью понять как это работает, попробуйте посмотреть соседей клетки через консоль введя cellBoxes[номер клетки - 17] if (cellBoxes[i - 1].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 1 <= 255) { //тут уже мы смотрим на соседей после самой клетки if (cellBoxes[i + 1].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 15 <= 255) { if (cellBoxes[i + 15].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 16 <= 255) { if (cellBoxes[i + 16].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 17 <= 255) { if (cellBoxes[i + 17].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } }
Проверку живых соседей мы сделали, теперь зададим правила
Задаем еще один такой же цикл, чтобы правила работали только после обнаружения у всех клеток, их соседей
for (i = 0; i < Object.keys(cellBoxes).length; i++) { // наш цикл, такой же как и прошлый if (cellBoxes[i].alivedNeighbor === 3) { // проверяем, если живы 3 соседа if (cellBoxes[i].classList.contains("deathCell")) { // если клетка уже мертва cellBoxes[i].classList.add("aliveCell") // оживляем ее cellBoxes[i].classList.remove("deathCell") } } else if (cellBoxes[i].classList.contains("aliveCell")) { // или же если клетка уже жива if (cellBoxes[i].alivedNeighbor === 2) { // если у нее есть 2 живых соседа cellBoxes[i].classList.add("aliveCell") // оставляем ее живой cellBoxes[i].classList.remove("deathCell") } else { // если у нее не 2 соседа, тогда она умирает cellBoxes[i].classList.add("deathCell") cellBoxes[i].classList.remove("aliveCell") } } else { // в любых других случаях if (cellBoxes[i].classList.contains("aliveCell")) { // если клетка жива cellBoxes[i].classList.add("deathCell") // убиваем ее cellBoxes[i].classList.remove("aliveCell") } } }
В нашу функцию framesUpdate() добавляем нашу проверку соседей
function framesUpdate() { setTimeout(function () { neighborCheck() // вот и проверка соседей framesUpdate() }, 1000) }
Весь код должен выглядить примерно таким:
cellBoxes = document.querySelectorAll(".cellBox") function aliveButtons(obj) { if (obj.classList.contains("deathCell")) { obj.classList.add("aliveCell") obj.classList.remove("deathCell") } else if (obj.classList.contains("aliveCell")) { obj.classList.add("deathCell") obj.classList.remove("aliveCell") } } function neighborCheck() { for (var i = 0; i < Object.keys(cellBoxes).length; i++) { cellBoxes[i].alivedNeighbor = 0 if (i - 17 >= 0) { if (cellBoxes[i - 17].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i - 16 >= 0) { if (cellBoxes[i - 16].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i - 15 >= 0) { if (cellBoxes[i - 15].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i - 1 >= 0) { if (cellBoxes[i - 1].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 1 <= 255) { if (cellBoxes[i + 1].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 15 <= 255) { if (cellBoxes[i + 15].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 16 <= 255) { if (cellBoxes[i + 16].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 17 <= 255) { if (cellBoxes[i + 17].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } } for (i = 0; i < Object.keys(cellBoxes).length; i++) { if (cellBoxes[i].alivedNeighbor === 3) { if (cellBoxes[i].classList.contains("deathCell")) { cellBoxes[i].classList.add("aliveCell") cellBoxes[i].classList.remove("deathCell") } } else if (cellBoxes[i].classList.contains("aliveCell")) { if (cellBoxes[i].alivedNeighbor === 2) { cellBoxes[i].classList.add("aliveCell") cellBoxes[i].classList.remove("deathCell") } else { cellBoxes[i].classList.add("deathCell") cellBoxes[i].classList.remove("aliveCell") } } else { if (cellBoxes[i].classList.contains("aliveCell")) { cellBoxes[i].classList.add("deathCell") cellBoxes[i].classList.remove("aliveCell") } } } } function framesUpdate() { setTimeout(function () { neighborCheck() framesUpdate() }, 1000) }
Основной код мы написали, но без интерфейса мы не можем им управлять
В HTML добавляем следующее (выше mainBox):
<div class="mainInterface"> <!-- главный блок интерфейса --> <button onclick="startAnim()" class="interfaceBtn">Start</button> <!-- кнопка старта --> <button onclick="resetToDefault()" class="interfaceBtn">Reset</button> <!-- кнопка для убийства всех блоков --> <input type="range" min="1" max="255" step="1" value="128" class="interfaceRange" id="genSpeedInput" oninput="setSpeedInput()"> <!-- Ползунок для управления скоростью --> <p class="interfaceTxt" id="genBySec">Поколений в секунду: 128</p> <!-- текст с нынешней скоростью --> <p class="interfaceTxt" id="genereationNumber">Поколение: 0</p> <!-- нынешнее поколение --> </div>
Стили для них:
.mainInterface { /* главный блок интерфейса */ position: fixed; /* Фиксация в левой верхнем углу */ left: 0; top: 0; background-color: rgba(73, 73, 73, 0.26); width: 11%; height: 25%; border-radius: 10px; padding: 20px; /* Чтобы блоки держались чуть дальше от границ */ } .interfaceBtn { /* Кнопки интерфейса */ width: 90%; margin: 10px auto; /* центрирование */ display: block; } .interfaceRange { /* Ползунок */ margin: 0 auto; /* центрирование */ display: block; }
Теперь у нас есть интерфейс в левом верхнем углу, но он не рабочий.
Переходим в JS
// просто framesUpdate(), заменяем на: function startAnim() { framesUpdate() }
Теперь у нас рабочий старт по кнопке
Добавляем следующие переменные вначале кода:
genNumberId = document.getElementById("genereationNumber") // По айди получаем текст с номером поколения genNumber = 0 // сам номер который будет изменяться genSpeedId = document.getElementById("genBySec") // получаем также по айди текст с текующей скоростью genBySec = 0 // значение скорости которое будет изменяться
Добавим ресет чтобы убить всех клеток:
function resetToDefault() { for (var i = 0; i < Object.keys(cellBoxes).length; i++) { // цикл обращается ко всем клеткам if (cellBoxes[i].classList.contains("aliveCell")) { // если клетка жива, то убивает ее cellBoxes[i].classList.add("deathCell") cellBoxes[i].classList.remove("aliveCell") } } }
Добавим управление скоростью:
function setSpeedInput() { genBySec = document.getElementById("genSpeedInput").value // Получаем значение с ползунка genSpeedId.innerHTML = "Поколений в секунду: " + genBySec // изменяем текст текущей скорости в интерфейсе }
Теперь нужно чтобы скорость изменялась, поэтому редактируем функцию framesUpdate()
function framesUpdate() { setTimeout(function () { neighborCheck() framesUpdate() }, 1000 / genBySec) // Делим секунду на выбранную скорость.Тоесть делим секунду на выбранное кол-во поколений }
Добавляем подсчет поколений в интерфейсе
В конце функции neighborCheck (вне циклов) добавляем следующее:
genNumber += 1 // изменяем значение текущего поколения genNumberId.innerHTML = "Поколение: " + genNumber // заменяем текст в интерфейсе
Мы закончили работать с интерфейсом
Весь код:
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Game Of Life</title> <link rel="stylesheet" href="style.css"> </head> <body> <main> <div class="mainInterface"> <button onclick="startAnim()" class="interfaceBtn">Start</button> <button onclick="resetToDefault()" class="interfaceBtn">Reset</button> <input type="range" min="1" max="255" step="1" value="128" class="interfaceRange" id="genSpeedInput" oninput="setSpeedInput()"> <p class="interfaceTxt" id="genBySec">Поколений в секунду: 128</p> <p class="interfaceTxt" id="genereationNumber">Поколение: 0</p> </div> <div class="mainBox"> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> <div class="cellBox deathCell" onclick="aliveButtons(this)"></div> </div> </main> <script src="script.js"></script> </body> </html>
CSS
* { font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } body { margin: 0; } .mainInterface { position: fixed; background-color: rgba(73, 73, 73, 0.26); width: 11%; height: 25%; border-radius: 10px; padding: 20px; } .interfaceBtn { width: 90%; margin: 10px auto; display: block; } .interfaceRange { margin: 0 auto; display: block; } .mainBox { border: solid 3px #000000; display: flex; flex-wrap: wrap; width: 45%; height: 83%; margin: 4% 26%; position: fixed; justify-content: flex-start; } .cellBox { display: block; width: 5.77%; height: 5.75%; border: solid 2px #808080; background-color: #ffffff; } .cellBox:hover { background-color: #000000; cursor: pointer; } .deathCell { background-color: #ffffff; } .aliveCell { background-color: #2c2c2c; }
JS
cellBoxes = document.querySelectorAll(".cellBox") genNumberId = document.getElementById("genereationNumber") genNumber = 0 genSpeedId = document.getElementById("genBySec") genBySec = 0 function aliveButtons(obj) { if (obj.classList.contains("deathCell")) { obj.classList.add("aliveCell") obj.classList.remove("deathCell") } else if (obj.classList.contains("aliveCell")) { obj.classList.add("deathCell") obj.classList.remove("aliveCell") } } function resetToDefault() { for (var i = 0; i < Object.keys(cellBoxes).length; i++) { if (cellBoxes[i].classList.contains("aliveCell")) { cellBoxes[i].classList.add("deathCell") cellBoxes[i].classList.remove("aliveCell") } } } function setSpeedInput() { genBySec = document.getElementById("genSpeedInput").value genSpeedId.innerHTML = "Поколений в секунду: " + genBySec } function neighborCheck() { for (var i = 0; i < Object.keys(cellBoxes).length; i++) { cellBoxes[i].alivedNeighbor = 0 if (i - 17 >= 0) { if (cellBoxes[i - 17].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i - 16 >= 0) { if (cellBoxes[i - 16].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i - 15 >= 0) { if (cellBoxes[i - 15].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i - 1 >= 0) { if (cellBoxes[i - 1].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 1 <= 255) { if (cellBoxes[i + 1].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 15 <= 255) { if (cellBoxes[i + 15].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 16 <= 255) { if (cellBoxes[i + 16].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } if (i + 17 <= 255) { if (cellBoxes[i + 17].classList.contains("aliveCell")) { cellBoxes[i].alivedNeighbor += 1 } } } for (i = 0; i < Object.keys(cellBoxes).length; i++) { if (cellBoxes[i].alivedNeighbor === 3) { if (cellBoxes[i].classList.contains("deathCell")) { cellBoxes[i].classList.add("aliveCell") cellBoxes[i].classList.remove("deathCell") } } else if (cellBoxes[i].classList.contains("aliveCell")) { if (cellBoxes[i].alivedNeighbor === 2) { cellBoxes[i].classList.add("aliveCell") cellBoxes[i].classList.remove("deathCell") } else { cellBoxes[i].classList.add("deathCell") cellBoxes[i].classList.remove("aliveCell") } } else { if (cellBoxes[i].classList.contains("aliveCell")) { cellBoxes[i].classList.add("deathCell") cellBoxes[i].classList.remove("aliveCell") } } } genNumber += 1 genNumberId.innerHTML = "Поколение: " + genNumber } function framesUpdate() { setTimeout(function () { neighborCheck() framesUpdate() }, 1000 / genBySec) } function startAnim() { framesUpdate() }
Спасибо за прочтение данной статьи.
Буду очень благодарен если заглянете на мой телеграм канал: https://t.me/blg_projects
ссылка на оригинал статьи https://habr.com/ru/post/689918/