Игра Жизнь — клеточный автомат на HTML

Игра Жизнь — это клеточный автомат созданный в 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/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *