Lifegame in Python.

Preface

happy New Year. I haven't posted a lot, but I look forward to working with you again this year.

I personally wanted to write a Lifegame-like program in Python, so I tried it during the New Year holidays. I also have the idea of ​​"at least one article before the dawn of the pine tree", so I will post a rough explanation and code. As in the past, I searched and wrote about sites here and there, muttered a soliloquy saying "I'm not cool" and corrected it, so there are some unsightly points, but please forgive me.

Environment

- Windows 10 Pro Build 19042.685 - Python 3.9.1 - matplotlib 3.3.3

Overview

--For more information on Lifegame, click here (https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0). (Wikipedia) --This time, I am drawing using the [scatter](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html) (scatter plot) class of matplotlib.pyplot. I don't think it's supposed to be used in this way. --Also, matplotlib.pyplot is used in [Interactive Mode](https://matplotlib.org/tutorials/introductory/usage.html#what-is-interactive-mode) to redraw each cell. --When you run the program, it will be drawn and the state of each cell will continue to be updated. Click the drawing area to end the program. You can also close it with the "x" at the top right of the window, but Traceback will be displayed. You can resize the window (for Windows 10) by dragging it "a little outside" at the edge of the window where the mouse cursor changes to an arrow. ――The process of calculating the state of each cell is a loop. Therefore, the larger the number of cells, the slower the progress. For reference, with Intel Core i7-8700K CPU @ 3.70GHz, drawing size 1000, interval 5 (the number of cells is 200x200 = 40000), it feels like it is updated at intervals of about 0.5 seconds. (Where you want to study a little more and speed up) ――The left and right and top and bottom of the drawing area are connected. Therefore, it may be something like "a moving group comes out from the right end and comes in from the left end". ――Each cell has a lifespan (1-9), and it disappears when it exceeds 9, but you can make it permanent as it is 9. ――The parameters related to various conditions are moved to the beginning of the code, so I think it would be a little fun to change them. I think that it is either annihilated or almost covered, but I wonder if it is possible to enjoy annihilation or prosperity by increasing / decreasing the initial value. ――The code has a set of comments, so I think it will be a hint for program analysis (although not so much). I don't use complicated calculations, so I think that if you have some linguistic knowledge, you can read it all.

code

It's a little long so it's folded.

lifegame.py


import time
import matplotlib.pyplot as plt
import random

#Interactive mode on
plt.ion()

#Setting of each variable
#Graph drawing size
sizeX = sizeY = 1000
#Cell spacing when drawing
#The number of cells on each axis is calculated by dividing the drawing size by the cell spacing.
space = 5
#Depopulation conditions
depop = 1
#Overcrowding conditions
overcrow = 4
#Occurrence condition(lower limit)
occurLower = 3
#Occurrence condition(upper limit)
occurUpper = 3
#Cell persistence flag
eternal = False
#Incidence of initial cells
occurInit = 20 # %
#Size factor when drawing cells
sizeFacter = 5

#Initialization of drawing area
fig, ax = plt.subplots()
ax.set_xlim(0, sizeX + space)
ax.set_ylim(0, sizeY + space)
ax.set_aspect('equal')
ax.grid(False)

#Initialization of cells and drawing data
cells =[]
x = []
y = []
color = []
scale = []
for i in range(1, int(sizeX / space) + 1, 1):
    tempCells = []
    for j in range(1, int(sizeY / space) + 1, 1):
        x.append(j * space)
        y.append(i * space)
        color.append('b')
        if random.randint(1, 100) <= occurInit:
            temp = random.randint(0,9)
        else:
            temp = 0
        tempCells.append(temp)
        scale.append(temp * sizeFacter)
    cells.append(tempCells)

# scatter(Scatter plot)Creating an object
sc = ax.scatter(x, y, c=color, s=scale, alpha=0.3, edgecolors='none')

#Setting an event to end with a mouse click
loop = True
def onclick(event):
    print('Program is over.')
    global loop
    loop = False

cid = fig.canvas.mpl_connect('button_press_event', onclick)

#Cell status check
def checkCell(cells, x, y):
    #Coordinate calculation of 8 cells around the cell
    cellsAxixes = []
    for i in range(-1,2,1):
        for j in range(-1,2,1):
            cellsAxixes.append({'x': x+i, 'y':y+j})
    #The center cell is itself and is not included in the calculation
    del cellsAxixes[4]

    #Top, bottom, left, right edge correction
    for i in cellsAxixes:
        if i['x'] < 0:
            i['x'] = int(sizeX/space) - 1
        elif i['x'] > int(sizeX/space) - 1:
            i['x'] = 0

        if i['y'] < 0:
            i['y'] = int(sizeY/space) - 1
        elif i['y'] > int(sizeY/space) - 1:
            i['y'] = 0

    #Count the number of living cells around
    check = 0
    for i in cellsAxixes:
        if cells[i['y']][i['x']] != 0:
            check += 1

    return check

# (Own)Cell calculation
def calcCells(cells):
    afterCells = []
    posY = 0
    for i in cells:
        posX = 0
        tempCells = []
        for j in i:
            status = checkCell(cells, posX, posY)
            #Confirmation of cell survival
            if j > 0 and j < 9:
                #Overcrowding, depopulation judgment
                if status >= overcrow or status <= depop:
                    j = 0
                else:
                    j += 1
            elif j == 9:
                #Permanent(eternal)If the flag is False. .. ..
                if not eternal:
                    #Die at the end of life
                    j = 0
            else:
                #Occurrence condition judgment
                if status <= occurUpper and status >= occurLower:
                    j = 1

            tempCells.append(j)
            posX += 1
        afterCells.append(tempCells)
        posY += 1
    return afterCells

#Main loop
while loop:
    #Sleep when processing is too fast and you are in trouble(Seconds)
    #time.sleep(0.01)
    newScale = []
    newColor = []
    cells = calcCells(cells)
    #Create drawing settings based on cell status
    for j in cells:
        for i in j:
            #size
            newScale.append(i * sizeFacter)

            #color
            if i > 0 and i < 4:
                newColor.append('b') #Blue
            elif i < 8:
                newColor.append('g') #Green
            else:
                newColor.append('r') #Red
    #Drawing settings and redrawing
    sc.set_sizes(newScale)
    sc.set_color(newColor)
    sc.figure.canvas.draw_idle()
    sc.figure.canvas.flush_events()

Postscript

I think Lifegame itself is a classic, but I think it's not a bad idea to work on it as a study because I have to incorporate all the basic elements of programming such as repetition and branching. If you want to modify the code, you can change the range of life, or weight the cells to make the conditions of depopulation, overcrowding, and occurrence finer, but this time it is because the energy does not continue. so.

Recommended Posts

Lifegame in Python.
Quadtree in Python --2
Python in optimization
CURL in python
Geocoding in python
SendKeys in Python
Meta-analysis in Python
Unittest in python
Epoch in Python
Discord in Python
Sudoku in Python
DCI in Python
quicksort in python
nCr in python
N-Gram in Python
Programming in python
Plink in Python
Constant in python
FizzBuzz in Python
Sqlite in python
StepAIC in Python
N-gram in python
LINE-Bot [0] in Python
Csv in python
Disassemble in Python
Reflection in Python
Constant in python
nCr in Python.
format in python
Scons in Python3
Puyo Puyo in python
python in virtualenv
PPAP in Python
Quad-tree in Python
Reflection in Python
Chemistry in Python
Hashable in python
DirectLiNGAM in Python
LiNGAM in Python
Flatten in python
flatten in python
Sorted list in Python
Daily AtCoder # 36 in Python
Clustering text in Python
Daily AtCoder # 2 in Python
Daily AtCoder # 32 in Python
Daily AtCoder # 6 in Python
Daily AtCoder # 18 in Python
Edit fonts in Python
Singleton pattern in Python
Read DXF in python
Daily AtCoder # 53 in Python
Use config.ini in Python
Daily AtCoder # 33 in Python
Solve ABC168D in Python
Logistic distribution in Python
Daily AtCoder # 7 in Python
LU decomposition in Python
One liner in Python
Simple gRPC in Python
Daily AtCoder # 24 in Python