Conway's Game of Life — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Полностью удалено содержимое страницы)
 
(не показаны 3 промежуточные версии 2 участников)
Строка 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="Stop" 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]]
 

Текущая версия на 19:40, 30 мая 2016