Доброго времени чтения, уважаемые пользователи Хабра! Игра Жизнь предложена Джоном Конвеем в 1970 году, и неоднократно обсуждалась на habrahabr.ru. Основные использованные теги приведены в метках к данной статье.
Предлагается ряд изменений, которые могут привести к новому направлению в развитии.

Предложение 1. В оригинальной игре предложено бесконечное поле, однако в реализациях обычно используется правило развертки тора — горизонтали и вертикали замкнуты в циклы.
Предлагается вариант, при котором горизонтали прямоугольного поля конечного размера замкнуты в цилиндр, а вертикали попарно соединены с шагом в половину размера поля по горизонтали. Таким образом можно получить легкий для расчетов аналог сферы.
Для моделирования изотропии предлагается использовать треугольную сетку, которая в расчетах подменяется оценкой близости по горизонтали, вертикали, и одной из диагоналей.
Для изменения среды могут использоваться горизонтальные слои:
один слой высотой 20% у экватора — с хорошими условиями жизни (3-4 соседа для сохранения, 4 для зарождения)
два слоя по 10% — с плохими условиями для жизни (1-2 соседа для сохранения, 2 — для зарождения жизни)
для остальной части действуют обычные правила (2-3 соседа для сохранения, 3 — для зарождения жизни)
Предложение 2. Для организмов предлагается добавление уровней сложности, возможностей объединения, генетической модификации и обучения. Каждому организму назначается до 10-ти уровней сложности, каждый уровень представлен как в материальной, так и в абстрактной области.
Уровень сложности в материальной области влияет на максимальную скорость (количество клеток, на которые организм передвигается в одном направлении за один ход). Таким образом, организмы с первым уровнем сложности (индекс массива 0) неподвижны. Целостный организм передвигается целиком.
Уровень сложности в абстрактной области влияет на количество обозреваемых по прямой соседних клеток. Предлагается удвоенный по сравнению с возможностью перемещения радиус обзора: для первого уровня — 1, для второго уровня — 3 и т.д. Видимость определяется от самых крайних клеток организма.
Реализация подобных игр может быть интересна современным студентам, изучающим обработку больших данных и алгоритмы обучения. Собственного варианта реализации на данный момент нет.
Рекомендуется генетическая эволюция алгоритмов из верховного алгоритма
Upd: вариант в разрезе групп сложности туннельного моделирования https://habrahabr.ru/post/259291/:
в разрезе природных систем
вероятностный вывод (Байес) — хаотическое
генетический поиск (эволюция) — фрактальное
оптимизация с ограничениями (аналогии) — энергетическое
обратная дедукция (символисты) — информационное
градиентный спуск (коннекционисты) — статическое
далее системы начинают проявлять поведение, и цепочка повторяется на уровне живого:
вероятностный вывод (Байес) — динамическое (процессы)
генетический поиск (эволюция) — синергетическое (рынок)
оптимизация с ограничениями (аналогии) — корпоративное (роды)
обратная дедукция (символисты) — бюрократическое (регламенты)
градиентный спуск (коннекционисты) — экологическое
Литература: Педро Домингос, Верховный алгоритм. Как машинное обучение изменит наш мир.
Ссылки:
https://habr.com/ru/post/435670/ — Верховный алгоритм — распределение алгоритмов по уровням сложности
Исходники на Python:
life.py
import pygame import field import numpy as np running = True v = field.area() step=0 pygame.init() screen = pygame.display.set_mode([640, 550]) font = pygame.font.Font(None, 50) while running: screen.fill([0, 0, 0]) clr = 0 for r in range(1, v.height): for c in range(1, v.width): if v.val[r, c] != 0: clr=clr+64 if r % 2 == 0 and c % 2 == 0: if clr > 255: clr = 255 screen.set_at([r/2, c/2], [clr, clr, clr]) clr = 0 step_text = font.render(str(step),1, (255, 255, 0)) screen.blit(step_text, [10, 520]) pygame.display.flip() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False v.generate() step=step+1 pygame.quit() print "Done"
field.py
import numpy as np import random class area: def __init__(self): self.width = 1000 self.height = 1000 self.debug = False self.val = np.zeros((self.height, self.width), dtype = int) self.val1 = np.zeros((self.height, self.width), dtype = int) self.val[250, 140] = 1 self.val[250, 141] = 1 self.val[251, 140] = 1 self.val[251, 141] = 1 self.val[252, 140] = 1 self.val[252, 141] = 1 self.rw = range(1, self.width-2) self.rh = range(1, self.height-2) self.r3 = range(-1, 2) self.dh = int(self.height/10) self.h1 = [self.dh*2, self.height-self.dh*2] self.h2 = [self.dh, self.height-self.dh] def generate(self): for cnt in self.r3: c = random.randint(0, self.width-1) r = random.randint(0, self.height-1) self.val[r, c] = 1 c = random.randint(0, self.width-1) r = random.randint(0, self.height-1) self.val[r, c] = 0 for c in self.rw: for r in self.rh: self.val1[r, c] = 0 cnt = 0 for r1 in self.r3: for c1 in self.r3: if not ((r1 == 0) and (c1 == 0)) and not (r1==-1 and c1==1) and not (r1==1 and c1==-1): if self.val[r+r1, c+c1] != 0: cnt = cnt + 1 self.val1[r, c] = self.store_value(c, cnt, self.val[r, c]) for r in self.rh: for c in self.rw: self.val[r, c] = self.val1[r, c] for c in self.rh: if self.val[c, self.width-2] == 1: self.val[0, c] = self.val[self.width-2, c] if self.val[1, c] == 1: self.val[self.width-1, c] = self.val[2, c] def store_value(self, c, cnt, cur): val = 0 if self.h1[0] < c < self.h1[1]: if 1 <= cnt <= 4: val = 1 if cur == 1 and cnt < 3: val = 1 else: if self.h2[0] < c < self.h2[1]: if 2 <= cnt <= 3: val = 1 if cur == 1 and 2 <= cnt <= 3: val = 1 else: if cnt == 2: val = 1 if cur == 1 and 1 <= cnt <= 2: val = 1 return val
Результат:

