Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Processing:Примеры/Клеточный автомат Вольфрама

Материал из Онлайн справочника
Перейти к: навигация, поиск


Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Ambox content.png Черновик


Описание[1]

Простая демонстрация одномерного клеточного автомата Вольфрама. Достигнув нижней части экрана, система перезапускается с новым набором правил. Кроме того, перезапустить систему можно при помощи клика мышкой.

Пример

  1. CA ca;   // объект для описания
  2.          // простого клеточного автомата Вольфрама
  3.  
  4. void setup() {
  5.   size(640, 360);
  6.   int[] ruleset = {0,1,0,1,1,0,1,0};    // начальный набор правил
  7.   ca = new CA(ruleset);                 // инициализируем CA
  8.   background(0);
  9. }
  10.  
  11. void draw() {
  12.   ca.render();    // рисуем CA
  13.   ca.generate();  // генерируем новый уровень
  14.  
  15.   if (ca.finished()) {   // если закончили, очищаем экран,
  16.                          // берем новый набор правил и перезапускаем
  17.     background(0);
  18.     ca.randomize();
  19.     ca.restart();
  20.   }
  21. }
  22.  
  23. void mousePressed() {
  24.   background(0);
  25.   ca.randomize();
  26.   ca.restart();
  27. }
  28.  
  29.  
  30.  
  31. class CA {
  32.  
  33.   int[] cells;     // массив, состоящий из «0» и «1»
  34.   int generation;  // как много поколений?
  35.   int scl;         // какова высота/ширина каждой клетки (в пикселях)?
  36.  
  37.   int[] rules;     // массив для хранения набора правил;
  38.                    // например, {0,1,1,0,1,1,0,1}
  39.  
  40.   CA(int[] r) {
  41.     rules = r;
  42.     scl = 1;
  43.     cells = new int[width/scl];
  44.     restart();
  45.   }
  46.  
  47.   // задаем правила для CA:
  48.   void setRules(int[] r) {
  49.     rules = r;
  50.   }
  51.  
  52.   // создаем случайный набор правил:
  53.   void randomize() {
  54.     for (int i = 0; i < 8; i++) {
  55.       rules[i] = int(random(2));
  56.     }
  57.   }
  58.  
  59.   // сбрасываем поколение до 0:
  60.   void restart() {
  61.     for (int i = 0; i < cells.length; i++) {
  62.       cells[i] = 0;
  63.     }
  64.     cells[cells.length/2] = 1;    // начинаем с клетки,
  65.                                   // находящейся посередине экрана
  66.                                   // и имеющей состояние «1»
  67.     generation = 0;
  68.   }
  69.  
  70.   // процесс создания нового поколения:
  71.   void generate() {
  72.     // сначала создаем пустой массив для новых значений:
  73.     int[] nextgen = new int[cells.length];
  74.     // задаем новое состояние для каждой точки
  75.     // на основе ее текущего состояния и состояния «соседей»;
  76.     // (игнорируем края, где у пикселей только один «сосед»):
  77.     for (int i = 1; i < cells.length-1; i++) {
  78.       int left = cells[i-1];   // состояние соседа «слева»
  79.       int me = cells[i];       // текущее состояние
  80.       int right = cells[i+1];  // состояние соседа «справа»
  81.     // рассчитываем следующее поколение на основе набора правил:
  82.       nextgen[i] = executeRules(left,me,right);
  83.     }
  84.     // копируем массив «nextgen» в массив «cells»:
  85.     for (int i = 1; i < cells.length-1; i++) {
  86.       cells[i] = nextgen[i];
  87.     }
  88.     //cells = (int[]) nextgen.clone();
  89.     generation++;
  90.   }
  91.  
  92.   // здесь ничего сложного; просто рисуем клетки:
  93.   // цветовое значение «255» для «1», «0» для «0»:
  94.   void render() {
  95.     for (int i = 0; i < cells.length; i++) {
  96.       if (cells[i] == 1) {
  97.         fill(255);
  98.       } else {
  99.         fill(0);
  100.       }
  101.       noStroke();
  102.       rect(i*scl,generation*scl, scl,scl);
  103.     }
  104.   }
  105.  
  106.   // реализовываем правила Вольфрама;
  107.   // это можно сделать более лаконично,
  108.   // но этот способ наглядно объясняет, что мы делаем в каждом случае:
  109.   int executeRules (int a, int b, int c) {
  110.     if (a == 1 && b == 1 && c == 1) { return rules[0]; }
  111.     if (a == 1 && b == 1 && c == 0) { return rules[1]; }
  112.     if (a == 1 && b == 0 && c == 1) { return rules[2]; }
  113.     if (a == 1 && b == 0 && c == 0) { return rules[3]; }
  114.     if (a == 0 && b == 1 && c == 1) { return rules[4]; }
  115.     if (a == 0 && b == 1 && c == 0) { return rules[5]; }
  116.     if (a == 0 && b == 0 && c == 1) { return rules[6]; }
  117.     if (a == 0 && b == 0 && c == 0) { return rules[7]; }
  118.     return 0;
  119.   }
  120.  
  121.   // если CA достиг нижней части экрана, значит, он закончен:
  122.   boolean finished() {
  123.     if (generation > height/scl) {
  124.        return true;
  125.     } else {
  126.        return false;
  127.     }
  128.   }
  129. }

См.также

Внешние ссылки

  1. processing.org - Wolfram Cellular Automata by Daniel Shiffman.