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.
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 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. 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.
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.
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.
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%.
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.
It looks like a sandstorm. The cell ratio is 30%. Some time has passed. I feel that the color mixing (mating) is progressing nicely. 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.
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