Это мой первый пост, где я хочу рассказать про самый известный клеточный автомат «Игра жизнь», а также напишем её на 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()
А теперь сделаем список клеток и функцию определения кол-ва соседей
Как работает определение кол-ва соседей
-
Создаем систему соседства system
-
Создаем переменную счетчик count
-
Проходимся по каждому элементу системы
-
Если сосед клетки по системе «живой», увеличиваем counter.
-
Возвращаем 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
Все получилось, скорость тоже не расстраивает.
В следующих статьях попробуем реализовать модификации игры «Жизнь».
ссылка на оригинал статьи https://habr.com/ru/post/532732/
Добавить комментарий