セルオートマトン (コンウェイの人生ゲーム) を実装するための 100 行の Python コード

 イギリスの数学者ジョン・ホートン・コンウェイは1970年にセル・オートマトンを発明しました。セル・オートマトンは、いくつかの基本的なルールを設定することで画像の自己進化をシミュレートして表示するシミュレーション・プログラムで、生命の誕生と生殖のプロセスに非常に似ているため、セル・オートマトンと呼ばれています。 「人生ゲーム」。

完全な効果

使用されるサードパーティ ライブラリ

パイゲーム

基本的なルール

コンウェイのライフ ゲームはグリッド上で行われます. 塗りつぶされたグリッドは人生を表すか、セルとして理解されます. ゲームのルールは 4 つだけです:

1 周りに生きている細胞が1つしかないか、まったくない場合、元の生きている細胞は死の状態に入ります。(セルが少なすぎる)

2 周囲に生細胞が 2 ~ 3 個ある場合、グリッドはそのまま残ります。

3 周囲に4個以上の生存細胞がある場合、元の生存細胞も死の状態に入る。(細胞が混みすぎている)

4 周囲に 3 つの生細胞がある場合、空白のグリッドは生細胞になります。(新しい細胞の再生)

コード

最初に、セル (グリッド) の生または空白の状態を表す 2 つの定数を定義します。

ALIVE = (124, 252, 0)  # 绿色
EMPTY = (0, 0, 0)      # 黑色

次の pygame 表示では、ALIVE セルは緑で表され、EMPTY 領域は黒で表されるため、ここでトリックを取り、RGB カラーを直接使用してセルの生存または死の 2 つの状態を表します。

次の変数は、pygame で使用されるパラメーターで、画面のサイズ、x 方向と y 方向のグリッドの数、および 1 つのセルのサイズです。

SCREEN_WIDHT = 600
SCREEN_HEIGHT = 600
X = 100   # X方向的网格数量
Y = 100   # Y方向的网格数量
CELL_WIDTH = SCREEN_WIDHT / X
CELL_HEIGHT = SCREEN_HEIGHT / Y

次に、グリッドであるセルを定義しましょう。

import pygame
from pygame.locals import *


class Cell:
    '''单个细胞'''
    def __init__(self, x, y):
        self.state = EMPTY
        self.rect = Rect(x * CELL_WIDTH, y * CELL_HEIGHT, 
                         CELL_WIDTH, CELL_HEIGHT)

    def draw(self, screen):
        pygame.draw.rect(screen, self.state, self.rect)

セルの属性は非常に単純で、state は現在の状態を表し、各セルは最初は死んでいることをデフォルトとしています; rect 属性は、長方形の領域を表す pygame の Rect オブジェクトで構築されます。最後に、対応する画面に自分自身を「描画」できるメソッド draw があります。

 次にグリッド全体を定義します。

class Grid:
    def __init__(self, X, Y):
        self.X = X
        self.Y = Y
        self.rows = []
        for y in range(Y):
            self.rows.append([])
            for x in range(X):
                self.rows[y].append(Cell(x, y))

    def get_state(self, y, x):
        return self.rows[y % self.Y][x % self.X].state

    def set_state(self, y, x, state):
        self.rows[y % self.Y][x % self.X].state = state

    def draw(self, screen):
        for row in self.rows:
            for cell in row:
                cell.draw(screen)

グリッド オブジェクトの中核は、2 次元リストである行属性であり、リスト内の各位置はセル オブジェクトであり、座標 (x, y) で特定できます。また、get_state と set_state という 3 つのメソッドが定義されており、特定の座標におけるセルの状態を取得および変更するために使用されます。リストの添え字が超えている(つまり、screen.error を超えていることが原因)ため、リストの添字は単純に x,y を使うのではなく、元に戻せる効果があります。

次の 2 つのモジュール レベル関数は、ライフ ゲームのロジックを実装するために使用されます。

def count_neighbors(y, x, get_state):
    n_ = get_state(y - 1, x + 0)  # North
    ne = get_state(y - 1, x + 1)  # Northeast
    e_ = get_state(y + 0, x + 1)  # East
    se = get_state(y + 1, x + 1)  # Southeast
    s_ = get_state(y + 1, x + 0)  # South
    sw = get_state(y + 1, x - 1)  # Southwest
    w_ = get_state(y + 0, x - 1)  # West
    nw = get_state(y - 1, x - 1)  # Northwest
    neighbor_states = [n_, ne, e_, se, s_, sw, w_, nw]
    count = 0
    for state in neighbor_states:
        if state == ALIVE:
            count += 1
    return count

def next_state(state, neighbors):
    if state == ALIVE:
        if neighbors < 2:
            return EMPTY
        elif neighbors > 3:
            return EMPTY
    else:
        if neighbors == 3:
            return ALIVE
    return state

count_neighbors 関数は、座標と、その座標に隣接する隣接座標に残っているセルの数を計算するために使用される状態を取得する関数を受け取ります; next_state 関数は、ライフ ゲームのコア ルールを記述します。セルの状態と周囲の隣接座標での生存セルの数、次の状態を出力します。この 2 つの関数を使用すると、1 つのセルのロジックとグリッド全体の状態変更を記述できます。

次の 2 つのモジュール レベル関数は、単一のセルとグリッド全体の新しい状態を設定します。

def step_cell(y, x, get_state, set_state):
    state = get_state(y, x)
    neighbors = count_neighbors(y, x, get_state)
    new_state = next_state(state, neighbors)
    set_state(y, x, new_state)

def simulate(grid):
    new_grid = Grid(grid.X, grid.Y)
    for y in range(grid.Y):
        for x in range(grid.X):
            step_cell(y, x, grid.get_state, new_grid.set_state)
    return new_grid

その中で、step_cell は次のセルの状態を設定するために使用され、simulate は次世代グリッドを返すために使用されます。

メインコードが書かれ、以下でテストが開始されます。

if __name__ == "__main__":
    # pygame初始化的相关内容
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDHT, SCREEN_HEIGHT))
    pygame.display.set_caption('Game Of Live')
    framerate = pygame.time.Clock()

    # 设定网格的一个初始状态
    grid = Grid(X, Y)
    grid.set_state(2, 4, ALIVE)
    grid.set_state(2, 2, ALIVE)
    grid.set_state(3, 3, ALIVE)
    grid.set_state(3, 4, ALIVE)
    grid.set_state(4, 4, ALIVE)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        grid.draw(screen)      # 将网格画到屏幕上
        grid = simulate(grid)  # 获得下一代网格

        pygame.display.update()
        framerate.tick(10)     # 设置每秒10帧

ライフ ゲームを実現するための上記のコードは、非常に簡潔で明確である必要があります。コードは合計で約 100 行しかありません。pygame ライブラリの基本的な知識を習得している限り、この非常に魔法のような効果を実現できます。

おすすめ

転載: blog.csdn.net/weixin_49775731/article/details/126030305