康威生命游戏的简单动画与 FuncAnimation

Posted

技术标签:

【中文标题】康威生命游戏的简单动画与 FuncAnimation【英文标题】:Simple animation for Conway's Game of Life with FuncAnimation 【发布时间】:2021-12-29 07:47:32 【问题描述】:

我已经用 Python 制作了一个简单的 Conway 的生命游戏程序,我需要使用 matplotlib 制作动画的帮助,因为我非常迷茫,我似乎无法理解它是如何完成的。

我的代码如下所示:

import matplotlib.pyplot as plt
import numpy as np


def initialize(size):
    grid = np.random.choice([0, 1], size*size, p=[0.8, 0.2]).reshape(size, size)
    plt.imshow(grid)
    plt.show(block=False)
    plt.pause(0.2)
    return grid


def conway_step(grid, size):
    new_grid = np.zeros_like(grid)
    for x in range(size):
        for y in range(size):
            total = sum([grid[(x+i) % size, (y+j) % size] for i in range(-1, 2) for j in range(-1, 2)])
            if grid[x, y] == 1 and total-1 in (2, 3):
                new_grid[x, y] = 1
            elif grid[x, y] == 0 and total == 3:
                new_grid[x, y] = 1
            else:
                new_grid[x, y] = 0
    grid = np.copy(new_grid)
    return grid


def conway(random=True, size=100):
    grid = initialize(size)
    for i in range(30):
        grid = conway_step(grid, size)
        plt.imshow(grid)
        plt.show(block=False)
        plt.pause(0.2)
    return


if __name__ == "__main__":
    conway(size=100)

这很好用,但我想将其实现为动画,并可能获取一个 mp4 文件。我尝试过这样的事情:

def conway(size):
    grid = initialize(size)
    fig, ax = plt.subplots()
    img = ax.imshow(grid)
    ani = animation.FuncAnimation(fig, conway_step, fargs=(grid, size))
    plt.show()

但它不起作用。有什么帮助吗?

【问题讨论】:

【参考方案1】:

FuncAnimation 中的 step 函数通常会更新图形对象,该对象也应该返回(return 语句应该以逗号结尾,因为它需要是列表或元组的一部分)。

网格和图形对象(示例代码中的img_plot)需要是全局变量。如果要保存动画,FuncAnimation 需要一个frames= 参数以避免它无限期运行。

import matplotlib.pyplot as plt
from matplotlib import animation
from matplotlib.colors import ListedColormap
import numpy as np

grid, grid_size, img_plot = None, None, None

def initialize(size):
    grid = np.random.choice([0, 1], size * size, p=[0.8, 0.2]).reshape(size, size)
    return grid

def conway_step(frame):
    global grid, grid_size, img_plot
    if frame < 3:   # no movement for the first few steps
        new_grid = grid
    else:
        new_grid = np.zeros_like(grid)
        for x in range(grid_size):
            for y in range(grid_size):
                total = sum(
                    [grid[(x + i) % grid_size, (y + j) % grid_size] for i in range(-1, 2) for j in range(-1, 2)])
                if grid[x, y] == 1 and total - 1 in (2, 3):
                    new_grid[x, y] = 1
                elif grid[x, y] == 0 and total == 3:
                    new_grid[x, y] = 1
                else:
                    new_grid[x, y] = 0
        grid = new_grid
    img_plot.set_data(new_grid)
    return img_plot,

def conway(random=True, size=100):
    global grid, grid_size, img_plot
    grid_size = size
    grid = initialize(size)
    fig, ax = plt.subplots(figsize=(10, 10))
    img_plot = ax.imshow(grid, interpolation='nearest', cmap=ListedColormap(['darkturquoise', 'yellow']))
    ax.set_xticks([])
    ax.set_yticks([])
    ani = animation.FuncAnimation(fig, frames=100, func=conway_step, interval=100)
    plt.tight_layout()
    ani.save('testconway.gif')
    plt.show()
    return ani

conway(size=100)

【讨论】:

非常感谢!这很棒。但我有一个抱怨:​​如果我从一个文件中导入一个网格,动画开始太晚了两到三帧。我该如何解决这个问题? 我更新了代码,在最初的几个步骤中不开始移动。通常,if frame &lt; 1: 应该足够了,但由于您似乎失去了更多步骤,示例代码使用 if frame &lt; 3: 完美,非常感谢!

以上是关于康威生命游戏的简单动画与 FuncAnimation的主要内容,如果未能解决你的问题,请参考以下文章

为啥康威的生命游戏可以归类为万能机?

康威的生命游戏:为啥模式行为不正确?

这么简单的游戏还卡壳?神经网络在「生命游戏」里苦苦挣扎

优化康威的“生命游戏”

ruby 康威的生命游戏 - 版本1

ruby 康威的生命游戏