Как стать автором
Обновить

Conways Game of life на Python

Время на прочтение 3 мин
Количество просмотров 27K

Это мой первый пост, где я хочу рассказать про самый известный клеточный автомат "Игра жизнь", а также напишем её на Python с использованием графики Pygame.

Conways Game of life ( по русски 'Игра жизнь' ) - клеточный автомат, придуманный Джоном Конвеем в далеком 1970 году.

Правила очень просты, вся игра происходит в 2D пространстве (плоскости) на которой могут быть 2 типа клеток "Живые" - 0 и "Пустые" -1. Основные правила жизни клетки таковы Birth3 Survive23, что значит клетка рождается при трёх соседях и выживает при двух или трёх, иначе умирает.

Определения кол-ва соседей происходит по соседству Мура.

Небольшая предыстория создания с Википедии.

Джон Конвей заинтересовался проблемой, предложенной в 1940-х годах известным математиком Джоном фон Нейманом, который пытался создать гипотетическую машину, которая может воспроизводить сама себя. Джону фон Нейману удалось создать математическую модель такой машины с очень сложными правилами. Конвей попытался упростить идеи, предложенные Нейманом, и в конце концов ему удалось создать правила, которые стали правилами игры «Жизнь».

Впервые описание этой игры было опубликовано в октябрьском (1970 год) выпуске журнала Scientific American, в рубрике «Математические игры» Мартина Гарднера (Martin Gardner)

Уверен, вам надоела вся эта теория, приступаем к написанию симуляции на Python/Pygame

Надеюсь у вас уже установлен Python, если же нет то вперёд устанавливать.

Для графики скачайте библиотеку pygame с помощью команды в терминале "pip install pygame" или же "pip3 install pygame" (если у вас высвечивается ошибка "pip не является внешней или внутренней командой" используя каждую команду ,скорее всего вы не поставили PATH при установке Python)

Для тестирования графики попробуем данный код, создающий сетку во всё окно

# Импорты
import pygame as p
from pygame.locals import *

# Константы цветов RGB
BLACK = (0 , 0 , 0)
WHITE = (255 , 255 , 255)
# Создаем окно
root = p.display.set_mode((1000 , 500))
# Основной цикл
while 1:
    # Заполняем экран белым цветом
    root.fill(WHITE)
    
    # Рисуем сетку
    for i in range(0 , root.get_height() // 20):
        p.draw.line(root , BLACK , (0 , i * 20) , (root.get_width() , i * 20))
    for j in range(0 , root.get_width() // 20):
        p.draw.line(root , BLACK , (j * 20 , 0) , (j * 20 , root.get_height()))
    # Нужно чтобы виндовс не думал что программа "не отвечает"
    for i in p.event.get():
        if i.type==	QUIT:
          quit()
    p.display.update()

А теперь сделаем список клеток и функцию определения кол-ва соседей

Как работает определение кол-ва соседей
  1. Создаем систему соседства system

  2. Создаем переменную счетчик count

  3. Проходимся по каждому элементу системы

  4. Если сосед клетки по системе "живой", увеличиваем counter.

  5. Возвращаем count

# 2х мерный список с помощью генераторных выражений
cells=[ [0 for j in range(root.get_width()//20)] for i in range(root.get_height()//20)]
cells2=cells
# Функция определения кол-ва соседей
def near(pos: list , system=[[-1 , -1] , [-1 , 0] , [-1 , 1] , [0 , -1] , [0 , 1] , [1 , -1] , [1 , 0] , [1 , 1]]):
    count = 0
    for i in system:
        if cells[(pos[0] + i[0]) % len(cells)][(pos[1] + i[1]) % len(cells[0])]:
            count += 1
    return count

И так, теперь сделаем основную логику.

    # Проходимся по всем клеткам
    for i in range(len(cells)):
        for j in range(len(cells[0])):
            # Если клетка жива
            if cells[i][j]:
                # Если у соседей не 2 или 3 соседа
                if near([i , j]) not in (2 , 3):
                    cells2[i][j] = 0
                    continue
                # В ином случае
                cells2[i][j] = 1
                continue
            # Если клетка мертва и у неё 3 соседа    
            if near([i , j]) == 3:
                cells2[i][j] = 1
                continue
            # В противном случае    
            cells2[i][j] = 0
    cells = cells2
Полный код
# Импорты
import time

import pygame as p
import random
from pygame.locals import *

# Константы цветов RGB
BLACK = (0 , 0 , 0)
WHITE = (255 , 255 , 255)
# Создаем окно
root = p.display.set_mode((1000 , 500))
# 2х мерный список с помощью генераторных выражений
cells = [[random.choice([0 , 1]) for j in range(root.get_width() // 20)] for i in range(root.get_height() // 20)]


# Функция определения кол-ва соседей
def near(pos: list , system=[[-1 , -1] , [-1 , 0] , [-1 , 1] , [0 , -1] , [0 , 1] , [1 , -1] , [1 , 0] , [1 , 1]]):
    count = 0
    for i in system:
        if cells[(pos[0] + i[0]) % len(cells)][(pos[1] + i[1]) % len(cells[0])]:
            count += 1
    return count


# Основной цикл
while 1:
    # Заполняем экран белым цветом
    root.fill(WHITE)

    # Рисуем сетку
    for i in range(0 , root.get_height() // 20):
        p.draw.line(root , BLACK , (0 , i * 20) , (root.get_width() , i * 20))
    for j in range(0 , root.get_width() // 20):
        p.draw.line(root , BLACK , (j * 20 , 0) , (j * 20 , root.get_height()))
   # Нужно чтобы виндовс не думал что программа "не отвечает"
    for i in p.event.get():
        if i.type == QUIT:
            quit()
    # Проходимся по всем клеткам

    for i in range(0 , len(cells)):
        for j in range(0 , len(cells[i])):
            print(cells[i][j],i,j)
            p.draw.rect(root , (255 * cells[i][j] % 256 , 0 , 0) , [i * 20 , j * 20 , 20 , 20])
    # Обновляем экран
    p.display.update()
    cells2 = [[0 for j in range(len(cells[0]))] for i in range(len(cells))]
    for i in range(len(cells)):
        for j in range(len(cells[0])):
            if cells[i][j]:
                if near([i , j]) not in (2 , 3):
                    cells2[i][j] = 0
                    continue
                cells2[i][j] = 1
                continue
            if near([i , j]) == 3:
                cells2[i][j] = 1
                continue
            cells2[i][j] = 0
    cells = cells2

Проверка кода
Проверка кода

Все получилось, скорость тоже не расстраивает.

В следующих статьях попробуем реализовать модификации игры "Жизнь".

Теги:
Хабы:
0
Комментарии 11
Комментарии Комментарии 11

Публикации

Истории

Работа

Python разработчик
130 вакансий
Data Scientist
66 вакансий

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн