Редактирование: Conway's Game of Life
Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
+ | [[Virtual laboratory]] > [[Conway's Game of Life]] <HR> | ||
+ | Here is the program, representing a classic game [http://ru.wikipedia.org/wiki/Жизнь_(игра) "Life"] by John Conway with the ability to draw the cells on the field with the help of cursor. | ||
+ | |||
+ | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tcvetkov/CelAut/CelAut_v2_release/CelAut_v2_release.html |width=630 |height=650 |border=0 }} | ||
+ | |||
+ | Download program: [[Медиа:CelAut_v2_release.zip|CelAut_v2_release.zip]] | ||
+ | <div class="mw-collapsible mw-collapsed" style="width:100%" > | ||
+ | '''The Text of the program is written in JavaScript (the developer is [[Цветков Денис]]):''' <div class="mw-collapsible-content"> | ||
+ | Файл '''"CelAut_v2_release.js"''' | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | function MainChain(canvas) { | ||
+ | |||
+ | // Предварительные установки | ||
+ | |||
+ | var context = canvas.getContext("2d"); // на context происходит рисование | ||
+ | document.oncontextmenu=function(e){return false}; // блокировка контекстного меню | ||
+ | |||
+ | // *** Задание вычислительных параметров *** | ||
+ | |||
+ | var fps = 5; // frames per second - число кадров в секунду | ||
+ | |||
+ | // Выполнение программы | ||
+ | |||
+ | var w = canvas.width; // ширина окна | ||
+ | var h = canvas.height; // высота окна | ||
+ | var n = 50; // количество клеток по горизонтали (желательно, делитель ширины окна) | ||
+ | var m = 50; // количество клеток по горизонтали (желательно, делитель высоты окна) | ||
+ | var cellW = w/n; // ширина клетки | ||
+ | var cellH = h/m; // высота клетки | ||
+ | |||
+ | var pause = true; | ||
+ | var intervalID; // для управления работой автомата | ||
+ | |||
+ | // "Жизнь" Конвея: [B = 000100000, L = 001100000] | ||
+ | var B = "000100000"; // геном рождения | ||
+ | var L = "001100000"; // геном выживания | ||
+ | |||
+ | // Работа с мышью | ||
+ | |||
+ | var mouseX; var mouseY; // координаты курсора мыши | ||
+ | |||
+ | canvas.onmousedown = function(e){ // функция при нажатии клавиши мыши | ||
+ | var life; | ||
+ | if (e.which == 1) life = true; // при нажатии левой клавиши мыши клетка рождается | ||
+ | else if (e.which == 3) life = false; // при нажатии правой клавиши мыши клетка умирает | ||
+ | else return; | ||
+ | |||
+ | setCell(e, life); | ||
+ | canvas.onmousemove = function(e) {setCell(e, life);}; // функция, выполняющаяся при перемещении курсора мыши | ||
+ | }; | ||
+ | |||
+ | document.onmouseup = function(e){ // функция при отпускании клавиши мыши | ||
+ | canvas.onmousemove = null; // когда клавиша отпущена - функции перемещения нету | ||
+ | }; | ||
+ | |||
+ | function refreshMouseCoords(e){ // процедура обновляет координаты в переменных mouseX и mouseY | ||
+ | var rect = canvas.getBoundingClientRect(); | ||
+ | mouseX = e.clientX - rect.left; | ||
+ | mouseY = e.clientY - rect.top; | ||
+ | } | ||
+ | |||
+ | // Работа с массивом | ||
+ | |||
+ | var cells; // массив клеток | ||
+ | var cellsBuf = []; // буфер для расчета следующего шага | ||
+ | for (var i = 0; i < n; i++) cellsBuf[i] = []; | ||
+ | function generateRandomField(n, m) { // каждая клетка заполняется случайным значением жива/мертва | ||
+ | cells = []; | ||
+ | for (var i = 0; i < n; i++) { | ||
+ | cells[i] = []; | ||
+ | for (var j = 0; j < m; j++) { | ||
+ | cells[i][j] = (Math.random() >= 0.5); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function setCell(e, life){ // придать клетке определенное состояние с нажатия клавиши мыши | ||
+ | refreshMouseCoords(e); // обновить координаты в переменных mouseX, mouseY | ||
+ | if (mouseX < 0 || mouseX >= w || mouseY < 0 || mouseY >= h) return; // проверка на ошибочные координаты | ||
+ | var i = Math.floor(mouseX/cellW); // получаем ячейку по горизонтали | ||
+ | var j = Math.floor(mouseY/cellH); // получаем ячейку по вертикали | ||
+ | if (cells[i][j] != life) { | ||
+ | cells[i][j] = life; | ||
+ | draw(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | MainChain.prototype.clear = function(){ | ||
+ | for (var i = 0; i < n; i++) | ||
+ | for (var j = 0; j < m; j++) | ||
+ | cells[i][j] = false; | ||
+ | draw(); | ||
+ | stopSystem(); | ||
+ | }; | ||
+ | |||
+ | // Управление работой автомата | ||
+ | |||
+ | function step() { | ||
+ | tick(); | ||
+ | draw(); | ||
+ | } | ||
+ | |||
+ | MainChain.prototype.changePauseState = function() { // кнопка паузы | ||
+ | if (!pause) stopSystem(); | ||
+ | else startSystem() | ||
+ | }; | ||
+ | |||
+ | MainChain.prototype.nextStep = function(){ // кнопка "Следующий шаг" | ||
+ | stopSystem(); | ||
+ | step(); | ||
+ | }; | ||
+ | |||
+ | function startSystem() { | ||
+ | pause = false; | ||
+ | intervalID = setInterval(step, 1000/fps); | ||
+ | document.getElementById('pause').value = "Stop"; | ||
+ | } | ||
+ | |||
+ | function stopSystem() { | ||
+ | pause = true; | ||
+ | clearInterval(intervalID); | ||
+ | document.getElementById('pause').value = "Next step"; | ||
+ | } | ||
+ | |||
+ | // Расчетная часть программы | ||
+ | |||
+ | // функции, обеспечивающие периодичность системы | ||
+ | function next(i, n) {if (i == (n-1)) return 0; else return i+1;} | ||
+ | function prev(i, n) {if (i == 0) return n-1; else return i-1;} | ||
+ | |||
+ | function tick(){ // то, что происходит каждый шаг времени | ||
+ | // копирование массива cells в cellsBuf | ||
+ | for (var i0 = 0; i0 < n; i0++) | ||
+ | for (var j0 = 0; j0 < m; j0++) | ||
+ | cellsBuf[i0][j0] = cells[i0][j0]; | ||
+ | |||
+ | for (var i = 0; i < n; i++) { | ||
+ | for (var j = 0; j < m; j++) { | ||
+ | |||
+ | // подсчет количества живых клеток вокруг рассматриваемой клетки | ||
+ | var near = 0; | ||
+ | if (cellsBuf[prev(i, n)] [prev(j, m)]) near++; | ||
+ | if (cellsBuf[prev(i, n)] [j]) near++; | ||
+ | if (cellsBuf[prev(i, n)] [next(j, m)]) near++; | ||
+ | if (cellsBuf[i] [prev(j, m)]) near++; | ||
+ | if (cellsBuf[i] [next(j, m)]) near++; | ||
+ | if (cellsBuf[next(i, n)] [prev(j, m)]) near++; | ||
+ | if (cellsBuf[next(i, n)] [j]) near++; | ||
+ | if (cellsBuf[next(i, n)] [next(j, m)]) near++; | ||
+ | |||
+ | if (cellsBuf[i][j]) // рассматриваемая клетка жива | ||
+ | cells[i][j] = (L[near] == '1'); // проверка условия выживания по биному L | ||
+ | else // рассматриваемая клетка мертва | ||
+ | cells[i][j] = (B[near] == '1'); // проверка условия рождения по биному B | ||
+ | |||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Рисование | ||
+ | |||
+ | function draw(){ | ||
+ | context.clearRect(0, 0, w, h); // очистить экран | ||
+ | for (var i = 0; i < n; i++){ | ||
+ | for (var j = 0; j < m; j++){ | ||
+ | if (cells[i][j]){ | ||
+ | context.beginPath(); | ||
+ | context.rect(i*cellW, j*cellH, cellW, cellH); | ||
+ | context.closePath(); | ||
+ | context.fill(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Запуск системы | ||
+ | generateRandomField(n, m); // сгенероровать поле | ||
+ | startSystem(); | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Файл '''"CelAut_v2_release.html"''' | ||
+ | <syntaxhighlight lang="html5" line start="1" enclose="div"> | ||
+ | <!DOCTYPE html> | ||
+ | <html> | ||
+ | <head> | ||
+ | <title>Cellular automaton</title> | ||
+ | <script src="CelAut_v2_release.js"></script> | ||
+ | </head> | ||
+ | <body> | ||
+ | <canvas id="canvasCelAut" width="600" height="600" style="border:1px solid #000000;"></canvas><br> | ||
+ | <input id="pause" type="button" name="" style="width: 100px" onclick="app.changePauseState();return false;"/> | ||
+ | <input type="button" name="" onclick="app.nextStep();return false;" value="Next step"/> | ||
+ | <input type="button" name="" onclick="app.clear();return false;" value="Clear the field"/> | ||
+ | <script type="text/javascript">var app = new MainChain(document.getElementById('canvasCelAut'));</script> | ||
+ | </body> | ||
+ | </html> | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | [[JavaScript - Клеточный автомат|Here]] you can find the previous versions of the program. | ||
+ | |||
+ | [[Category: Virtual Laboratory]] | ||
+ | [[Category: Programming]] |