Implementation of life game in Python

at first

I implemented the program using Pygame for the first time in a long time. This time, I implemented the life game a little away from the game. (The name includes a game, but it's not a game, so it's safe.) The difficulty of implementation is not that high.

What is a life game?

Conway's Game of Life is simply a simulation of life. You can observe how organisms are born and die over time. There are just a few rules in Conway's Game of Life, and the number of blocks called cells is updated accordingly.

Life game rules

Life game update rules are divided into birth, survival, and death. Birth is when a cell is dead, a cell that lives in an adjacent cell is born, but when there are three new cells that live in that cell are born. On the other hand, a living cell survives when the number of adjacent living cells is 3 or 4, and dies at other times. The death here corresponds to the depopulation and overcrowding of the real world. Here, in the figure below, the rules of birth, survival, death (depopulation), and death (overcrowding) are applied to the central cell from the left, respectively. Screenshot from 2019-11-09 00-49-25.png You are free to decide how many cells you need for the rule to apply. This time, I used the number explained above, which is often used.

Implementation

Basically, I implemented it as explained. It is important to note that when updating cells, if they are updated sequentially, the cells may die at once. Therefore, when updating a cell, it is necessary to hold the updated cell state in another location once and update it all at once after all the updated states are obtained. (I got stuck when I first implemented Conway's Game of Life) In addition, we have added some functions this time.

Color display

Most life games display cells in one color, but this time I used multicolored cells. Specifically, we started with four types of white, green, red, and blue in the initial state, and when the birth process is performed, cells with the average color of adjacent cells are born.

Key input

The arrow keys can be used to fast forward and slow forward the passage of time, and the number keys can be used to initialize at any time. If the initial digit key pressed is n, it will be initialized so that the cell ratio is n0%.

Program body

import pygame
from pygame.locals import *
import sys

display = [1010, 1010]
world_size = [100, 100]
num_key = [K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9]

class World:
    def __init__(self):
        self.speed = 1 #Drawing speed
        self.world = np.zeros(tuple(world_size + [3]))
        self.color = np.asarray([[255.0, 255.0, 255.0], [255.0, 0.0, 0.0], [0.0, 255.0, 0.0], [0.0, 0.0, 255.0], [0.0, 0.0, 0.0]])
        
    #Random initialization flag=If True, the color is also random
    def random_init(self, p, color_flag=False):
        for i in range(world_size[0]):
            for j in range(world_size[1]):
                if random.random() > p:
                    continue
                
                if color_flag:
                    color = self.color[random.randint(0, 3)]
                else:
                    color = self.color[0]
                self.world[i, j] = color
        
    def draw(self, screen):
        for i in range(world_size[0]):
            for j in range(world_size[1]):
                pygame.draw.rect(screen, tuple(self.world[i, j]), Rect(10*j + 10, 10*i + 10, 10, 10))
        
    def update(self):
        next_world = np.zeros(tuple(world_size + [3]))
        flags = self.world.sum(axis=2) > 0
        
        for i in range(world_size[0]):
            for j in range(world_size[1]):
                min_x = max(0, j-1)
                max_x = min(world_size[1], j+2)
                min_y = max(0, i-1)
                max_y = min(world_size[0], i+2)
                count = np.sum(flags[min_y:max_y, min_x:max_x])
                if flags[i, j] == 0: #Dead cell
                    if count == 3: #birth
                        area = self.world[min_y:max_y, min_x:max_x]
                        next_world[i, j] = area.reshape(-1, 3).sum(axis=0) / count
                else:
                    if 3 < count < 6: #not depopulated or overcrowded
                        next_world[i, j] = self.world[i, j]
                        
        self.world = next_world

def main():
    pygame.init()
    screen = pygame.display.set_mode(display)
    pygame.display.set_caption("Lifegame")
    
    world = World()
    world.random_init(0.3, True)
    counter = 0
    
    while(1):
        screen.fill((0, 0, 0))
        
        world.draw(screen)
        pygame.display.update()
        pygame.time.wait(5)
        
        counter += 1
        if counter > world.speed:
            world.update()
            counter = 0

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()      
                if event.key == K_DOWN:
                    world.speed = world.speed+1
                if event.key == K_UP:
                    world.speed = max(0, world.speed-1)
                if event.key in num_key:
                    world.random_init((num_key.index(event.key)+1.0)*0.1, True)
                
if __name__ == "__main__":
    main()

It's a lot shorter than the last Tetris.

Output screen

It looks like a sandstorm. The cell ratio is 30%. Screenshot from 2019-11-09 01-05-36.png Some time has passed. I feel that the color mixing (mating) is progressing nicely. Screenshot from 2019-11-09 01-05-56.png As expected, there are many dirty colors that survive at the end of life. It seems that the color mixing has progressed that much. At first there were so many. Screenshot from 2019-11-09 01-06-02.png

in conclusion

This is the end of the implementation of Life Game. To tell the truth, I wanted to add a little more functionality, but I gave up because the processing speed of Python was suspicious. Maybe I'll reimplement it using C ++. See you again

Recommended Posts

Implementation of life game in Python
Implementation of quicksort in Python
Life game with Python! (Conway's Game of Life)
Implementation of original sorting in Python
ValueObject implementation in Python
SVM implementation in python
Explanation of edit distance and implementation in Python
Equivalence of objects in Python
Implementation of game theory-Prisoner's dilemma-
Python implementation of particle filters
Neural network implementation in python
Maximum likelihood estimation implementation of topic model in python
Overview of generalized linear models and implementation in Python
Variational Bayesian inference implementation of topic model in python
A reminder about the implementation of recommendations in Python
Pixel manipulation of images in Python
Sorting algorithm and implementation in Python
HMM parameter estimation implementation in python
Python implementation of self-organizing particle filters
Mixed normal distribution implementation in python
Implementation of login function in Django
Division of timedelta in Python 2.7 series
MySQL-automatic escape of parameters in python
Handling of JSON files in Python
Waveform display of audio in Python
Implementation of desktop notifications using Python
Python implementation of non-recursive Segment Tree
Implementation of Light CNN (Python Keras)
Law of large numbers in python
Study, number guessing game in Python
Implementation of Dijkstra's algorithm with python
Reversible scrambling of integers in Python
I tried to implement blackjack of card game in Python
Save the result of the life game as a gif with python
Conversion of string <-> date (date, datetime) in Python
(Bad) practice of using this in Python
General Theory of Relativity in Python: Introduction
Output tree structure of files in Python
Display a list of alphabets in Python 3
Implementation module "deque" in queue and Python
Comparison of Japanese conversion module in Python3
It's an implementation of ConnectionPool in redis.py
Summary of various for statements in Python
The result of installing python in Anaconda
Gang of Four (GoF) Patterns in Python
The basics of running NoxPlayer in Python
Bulk replacement of strings in Python arrays
Project Euler # 16 "Sum of Powers" in Python
Traffic Safety-kun: Recognition of traffic signs in Python
Summary of built-in methods in Python list
Non-logical operator usage of or in python
In search of the fastest FizzBuzz in Python
Practical example of Hexagonal Architecture in Python
Project Euler # 17 "Number of Characters" in Python
Double pendulum equation of motion in python
Get rid of DICOM images in Python
Non-recursive implementation of extended Euclidean algorithm (Python)
Python implementation of continuous hidden Markov model
Status of each Python processing system in 2020
Project Euler # 1 "Multiples of 3 and 5" in Python
Meaning of using DI framework in Python