Pythonでライフゲームをやってみました。
初期状態を与えるとGIFを生成します。
初期状態を与えない場合はランダムになります。
描画にはPillowを使いました。
from PIL import Image, ImageDraw
import random
def main():
size = 10 # 1マスのピクセル
margin = 5 # 余白のピクセル
num_cols = 20
num_rows = 20
color_bg = "white"
color_life = "black"
num_pages = 200
# 初期状態を指定する場合
cells_start = [
[0, 0, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 1, 1, 1]
]
# 初期状態をランダムにセットする場合
cells_start = make_start_cells(num_cols, num_rows)
width = size * num_cols + margin * 2
height = size * num_rows + margin * 2
images = []
cells = [[0] * num_cols for i in range(num_rows)]
# 初期状態を反映。
for r in range(num_rows):
for c in range(num_cols):
if r < len(cells_start) and c < len(cells_start[r]):
cells[r][c] = cells_start[r][c]
for x in range(num_pages):
im = Image.new('RGB', (width, height), color_bg)
draw = ImageDraw.Draw(im)
cells = make_next_cells(cells)
for r in range(num_rows):
for c in range(num_cols):
item = cells[r][c]
if item == 1:
x0 = margin + size * c
y0 = margin + size * r
x1 = x0 + size
y1 = y0 + size
draw.rectangle((x0, y0, x1, y1), fill = color_life, outline = None, width = 0)
images.append(im)
images[0].save('lifegame.gif',
save_all = True,
append_images = images[1 : ],
optimize = False,
duration = 100,
loop = 1 # 0だと無限
)
def make_next_cells(cells):
num_rows = len(cells)
num_cols = len(cells[0])
cells_next = [[0] * num_cols for i in range(num_rows)]
for r in range(num_rows):
for c in range(num_cols):
num_lives = 0
for j in range( - 1, 2):
for i in range( - 1, 2):
if not (i == 0 and j == 0):
a = (c + i) % num_cols
b = (r + j) % num_rows
if cells[b][a] == 1:
num_lives += 1
if cells[r][c] == 0 and num_lives == 3 : # 誕生
cells_next[r][c] = 1
elif cells[r][c] == 1 and 2 <= num_lives <= 3 : # 生存
cells_next[r][c] = 1
elif cells[r][c] == 1 and (num_lives <= 1 or 4 <= num_lives) : # 過疎、過密
cells_next[r][c] = 0
return cells_next
def make_start_cells(num_cols, num_rows):
num_lives_to_set = int(num_cols * num_rows * 0.5) # 0.5はマスの半分を埋める。
cells = [[0] * num_cols for i in range(num_rows)]
for i in range(num_lives_to_set):
r = random.randint(0, num_rows - 1)
c = random.randint(0, num_cols - 1)
cells[r][c] = 1
return cells
if __name__ == "__main__":
main()
import random
def main():
size = 10 # 1マスのピクセル
margin = 5 # 余白のピクセル
num_cols = 20
num_rows = 20
color_bg = "white"
color_life = "black"
num_pages = 200
# 初期状態を指定する場合
cells_start = [
[0, 0, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 1, 1, 1]
]
# 初期状態をランダムにセットする場合
cells_start = make_start_cells(num_cols, num_rows)
width = size * num_cols + margin * 2
height = size * num_rows + margin * 2
images = []
cells = [[0] * num_cols for i in range(num_rows)]
# 初期状態を反映。
for r in range(num_rows):
for c in range(num_cols):
if r < len(cells_start) and c < len(cells_start[r]):
cells[r][c] = cells_start[r][c]
for x in range(num_pages):
im = Image.new('RGB', (width, height), color_bg)
draw = ImageDraw.Draw(im)
cells = make_next_cells(cells)
for r in range(num_rows):
for c in range(num_cols):
item = cells[r][c]
if item == 1:
x0 = margin + size * c
y0 = margin + size * r
x1 = x0 + size
y1 = y0 + size
draw.rectangle((x0, y0, x1, y1), fill = color_life, outline = None, width = 0)
images.append(im)
images[0].save('lifegame.gif',
save_all = True,
append_images = images[1 : ],
optimize = False,
duration = 100,
loop = 1 # 0だと無限
)
def make_next_cells(cells):
num_rows = len(cells)
num_cols = len(cells[0])
cells_next = [[0] * num_cols for i in range(num_rows)]
for r in range(num_rows):
for c in range(num_cols):
num_lives = 0
for j in range( - 1, 2):
for i in range( - 1, 2):
if not (i == 0 and j == 0):
a = (c + i) % num_cols
b = (r + j) % num_rows
if cells[b][a] == 1:
num_lives += 1
if cells[r][c] == 0 and num_lives == 3 : # 誕生
cells_next[r][c] = 1
elif cells[r][c] == 1 and 2 <= num_lives <= 3 : # 生存
cells_next[r][c] = 1
elif cells[r][c] == 1 and (num_lives <= 1 or 4 <= num_lives) : # 過疎、過密
cells_next[r][c] = 0
return cells_next
def make_start_cells(num_cols, num_rows):
num_lives_to_set = int(num_cols * num_rows * 0.5) # 0.5はマスの半分を埋める。
cells = [[0] * num_cols for i in range(num_rows)]
for i in range(num_lives_to_set):
r = random.randint(0, num_rows - 1)
c = random.randint(0, num_cols - 1)
cells[r][c] = 1
return cells
if __name__ == "__main__":
main()
コメント