イギリスの数学者ジョン・ホートン・コンウェイは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 ライブラリの基本的な知識を習得している限り、この非常に魔法のような効果を実現できます。