Игра "Жизнь" — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Строка 2: Строка 2:
  
 
Здесь расположена программа, представляющая из себя классическую игру [http://ru.wikipedia.org/wiki/Жизнь_(игра) "Жизнь"] Джона Конвея с возможностью рисовать курсором клетки на поле.
 
Здесь расположена программа, представляющая из себя классическую игру [http://ru.wikipedia.org/wiki/Жизнь_(игра) "Жизнь"] Джона Конвея с возможностью рисовать курсором клетки на поле.
<addscript src=CelAut_v2_release/>
+
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tcvetkov/CelAut/CelAut_v2_release/CelAut_v2_release.html |width=630 |height=650 |border=0 }}
<htmlet nocache="yes">CelAut_v2_TM</htmlet>
 
  
 
Скачать программу: [[Медиа:CelAut_v2_release.zip|CelAut_v2_release.zip]]
 
Скачать программу: [[Медиа:CelAut_v2_release.zip|CelAut_v2_release.zip]]
Строка 18: Строка 17:
 
     // *** Задание вычислительных параметров ***
 
     // *** Задание вычислительных параметров ***
  
     const fps = 5;                // frames per second - число кадров в секунду
+
     var fps = 5;                // frames per second - число кадров в секунду
  
 
     // Выполнение программы
 
     // Выполнение программы
  
     const w = canvas.width;     // ширина окна
+
     var w = canvas.width;     // ширина окна
     const h = canvas.height; // высота окна
+
     var h = canvas.height; // высота окна
     const n = 50;                  // количество клеток по горизонтали (желательно, делитель ширины окна)
+
     var n = 50;                  // количество клеток по горизонтали (желательно, делитель ширины окна)
     const m = 50;                  // количество клеток по горизонтали (желательно, делитель высоты окна)
+
     var m = 50;                  // количество клеток по горизонтали (желательно, делитель высоты окна)
     const cellW = w/n;              // ширина клетки
+
     var cellW = w/n;              // ширина клетки
     const cellH = h/m;              // высота клетки
+
     var cellH = h/m;              // высота клетки
  
 
     var pause = true;
 
     var pause = true;
Строка 33: Строка 32:
  
 
     // "Жизнь" Конвея: [B = 000100000, L = 001100000]
 
     // "Жизнь" Конвея: [B = 000100000, L = 001100000]
     const B = "000100000";            // геном рождения
+
     var B = "000100000";            // геном рождения
     const L = "001100000";            // геном выживания
+
     var L = "001100000";            // геном выживания
  
 
     // Работа с мышью
 
     // Работа с мышью
Строка 203: Строка 202:
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Программирование]]
 
[[Category: Программирование]]
[[Category: JavaScript]]
 

Версия 01:58, 6 ноября 2014

Виртуальная лаборатория > Игра "Жизнь"

Здесь расположена программа, представляющая из себя классическую игру "Жизнь" Джона Конвея с возможностью рисовать курсором клетки на поле.

Скачать программу: CelAut_v2_release.zip Текст программы на языке JavaScript (разработчик Цветков Денис): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "CelAut_v2_release.js"

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 = "Остановить";
    }

    function stopSystem() {
        pause = true;
        clearInterval(intervalID);
        document.getElementById('pause').value = "Запустить";
    }

    // Расчетная часть программы

    // функции, обеспечивающие периодичность системы
    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();

}

Файл "CelAut_v2_release.html"

<!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="Следующий шаг"/>
    <input type="button" name="" onclick="app.clear();return false;" value="Очистить поле"/>
    <script type="text/javascript">var app = new MainChain(document.getElementById('canvasCelAut'));</script>
</body>
</html>

</toggledisplay>

Здесь вы можете найти предыдущие версии программы.