ライフゲームを作る(2)

Pygameを使ってライフゲームを作った。ライフゲームがどういうものかはリンク先を参照のこと。

  • 使用方法
    • Conway.pywを実行する。
    • 升目が表示されるので、適当な升を選んでクリックすると黒くなる。黒は生命が存在している状態、白は生命なしを表す。初期の分布を決める。
    • ある程度の升目をクリックして分布が決まったら、sキーで時間の進行がスタートする。
    • あとは見てるだけ。時間が進み分布が変わっていく。
    • 止めたいときはESCキーを押す。
  • 実行例


図1:例えばこんな初期分布を設定する。

図2:どんどん分布が変わる。

図3:こんな感じにもなる。

図4:最終的にこんな分布に落ち着いた。

本当に正しく動いているか検証の必要あり。

ソースコードconway.pywは次の通り。

#!/bin/env python
# coding: utf-8
# ------------------------------------------------------------------
# Conway's Game of Life  ver.1.0
#                                               2008/11/10
import pygame
import sys
from pygame.locals import *

WDTH = 13   # 盤上に並べるタイルの幅
TNUM = 50   # 一辺のタイルの数:総数はTNUM*TNUMになる
DEAD  = 0
ALIVE = 1

SCR_W = WDTH * TNUM      # ウィンドウの大きさ(幅)
SCR_H = WDTH * TNUM      # ウィンドウの大きさ(縦)
WPOS = WDTH*(TNUM-1)

""" 初期設定 """
pygame.init()
screen = pygame.display.set_mode( (SCR_W, SCR_H) )
image1 = pygame.image.load('dead.bmp')
image2 = pygame.image.load('alive.bmp')
image1 = image1.convert()
image2 = image2.convert()
imagerect1 = image1.get_rect()
imagerect2 = image2.get_rect()

komacolor = [[DEAD for x in range(TNUM+2)] for x in range(TNUM+2)]
komacolor2 = [[DEAD for x in range(TNUM+2)] for x in range(TNUM+2)]

clock = pygame.time.Clock()

def evolv(x,y):
    """ 周囲の状態により次の世代の自分の状態を決める
        自分の位置は、x+1,y+1                    """
    sumalive = 0
    sumalive += komacolor[x][y]
    sumalive += komacolor[x][y+1]
    sumalive += komacolor[x][y+2]
    sumalive += komacolor[x+1][y]
    sumalive += komacolor[x+2][y]
    sumalive += komacolor[x+2][y+1]
    sumalive += komacolor[x+1][y+2]
    sumalive += komacolor[x+2][y+2]
    if komacolor[x+1][y+1] == DEAD and sumalive == 3:
        return ALIVE
    elif komacolor[x+1][y+1] == ALIVE and (sumalive ==2 or
                                         sumalive ==3):
        return ALIVE
    else:
        return DEAD    
    
def main():
    screen.fill((255,255,255))
    pygame.display.set_caption("Conway's Game of Life")
    pygame.mouse.set_visible(True)

    """ 初期画面を描画 """
    for i in xrange(0, WPOS+1, WDTH):
        for j in xrange(0, WPOS+1, WDTH):
            screen.blit(image1, imagerect1.move(i,j))
    pygame.display.flip()

    """ 初期のコマの配置を決める """
    while 1:
        for event in pygame.event.get():
            if event.type == MOUSEBUTTONDOWN:
                xpos = int(pygame.mouse.get_pos()[0]/WDTH)
                ypos = int(pygame.mouse.get_pos()[1]/WDTH)
                screen.blit(image2, imagerect2.move(WDTH*xpos,WDTH*ypos))
                komacolor[xpos+1][ypos+1] = ALIVE
            pygame.display.flip()
            
        if (event.type == KEYDOWN and
                event.key == K_ESCAPE):  # ESCで終了
                pygame.quit()
                sys.exit()
        if (event.type == KEYDOWN and
            event.key == K_s):
            print "Evolution has started."
            break

    """ 進化 """
    while 1:
        clock.tick(200000)  
        for i in xrange(TNUM):
            for j in xrange(TNUM):
                if evolv(i,j):
                    screen.blit(image2, imagerect2.move(WDTH*i,WDTH*j))
                    komacolor2[i+1][j+1] = ALIVE
                else:
                    screen.blit(image1, imagerect1.move(WDTH*i,WDTH*j))
                    komacolor2[i+1][j+1] = DEAD
        pygame.display.flip()

    """ komacolor = komacolor2 としたら動かなかった """
        for i in xrange(TNUM):
            for j in xrange(TNUM):
                komacolor[i][j] = komacolor2[i][j]
        
        for event in pygame.event.get():
            if (event.type == KEYDOWN and
                event.key == K_ESCAPE):
                pygame.quit()
                sys.exit()

if __name__ == '__main__':
    main()

最後の部分で、

for i in xrange(TNUM):
    for j in xrange(TNUM):
        komacolor[i][j] = komacolor2[i][j]

のところを

komacolor = komacolor2

としていたので、最初動かなかった。なんか納得いかない。