Игра Жизни в Python: проблема с анимацией matplotlib - PullRequest
0 голосов
/ 10 января 2020

Моя функция анимации matplotlib не работает. Любые предложения очень ценятся. В результате должна быть запущена анимация от текущего к новому поколению (с использованием функции new_state).

«состояние» - текущий массив, который является случайным массивом. Это передается в функцию new_state и должно отображаться как анимация.

'''
The code should generate John Conway's Game of Life, resulting in an animation that represents a transition from current
state to new state. This update of generations are based on the rules found here https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life.

'''
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

'''This function creates an array of elements of zeros, with a specified width and height.'''
def dead_state(height, width):
    array = np.zeros((height,width), dtype=int)
    return array


'''This function generates an array with random elements of ones and zeroes, with a specified width and height.'''
def random_state(width, height):
    array = np.random.randint(0, high=2, size=(width, height), dtype=int)
    return array


'''This function plots the array.'''
def plot(array):
    plt.imshow(array)
    plt.show()


def new_state(array):
    array_padded = np.pad(array, 1)
    updated_array=array.copy()
    for x in range(1, array.shape[0]+1):
        for y in range(1, array.shape[1]+1):
            cell = array[x-1][y-1]
            neighbours = (array_padded[x-1][y-1], array_padded[x][y-1], array_padded[x+1][y-1],
                          array_padded[x+1][y], array_padded[x+1][y+1], array_padded[x][y+1],
                          array_padded[x-1][y+1], array_padded[x-1][y])
            neighbours_count = sum(neighbours)
            if cell == 1:
                if neighbours_count == 0 or neighbours_count == 1 or neighbours_count > 3:
                    updated_array[x-1,y-1]=0
                elif neighbours_count == 2 or neighbours_count == 3:
                    updated_array[x-1,y-1]=1
            elif cell == 0:
                if neighbours_count == 3:
                    updated_array[x-1,y-1]=1
    return updated_array


state = random_state(20,20)


im = plt.imshow(state)
plt.show()


def animate(frame):
    im.set_data(new_state(state))
    return im


"""Running the code below should generate the animation"""

fig = plt.figure()
animation.FuncAnimation(fig, animate, frames=200, interval=50)
plt.show()

1 Ответ

0 голосов
/ 10 января 2020

Я не эксперт по матплотлибам, но думаю, это ближе к тому, что вы хотели:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def dead_state(height, width):
    array = np.zeros((height,width), dtype=int)
    return array

def random_state(width, height):
    array = np.random.randint(0, high=2, size=(width, height), dtype=int)
    return array

def new_state(array):
    array_padded = np.pad(array, 1)
    updated_array=array.copy()
    for x in range(1, array.shape[0] + 1):
        for y in range(1, array.shape[1] + 1):
            cell = array[x - 1][y - 1]
            neighbours = (array_padded[x - 1][y - 1], array_padded[x][y - 1],
                          array_padded[x + 1][y - 1], array_padded[x + 1][y],
                          array_padded[x + 1][y + 1], array_padded[x][y + 1],
                          array_padded[x - 1][y + 1], array_padded[x - 1][y])
            neighbours_count = sum(neighbours)
            if cell == 1:
                if 0 <= neighbours_count <= 1 or neighbours_count > 3:
                    updated_array[x - 1,y - 1] = 0
                else:
                    updated_array[x - 1,y - 1] = 1
            elif cell == 0:
                if neighbours_count == 3:
                    updated_array[x - 1,y - 1] = 1
    return updated_array

state = random_state(20,20)
def animate(frame):
    global state
    state = new_state(state)
    plt.imshow(state)

fig = plt.figure()
anim = animation.FuncAnimation(fig, animate, frames=200, interval=50)
plt.show()
anim()
...