Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Conway's Game of Life ด้วย Python

นักคณิตศาสตร์ชาวอังกฤษ สร้าง "Game of Life" ในปี 1970 ซึ่งเป็นชุดกฎที่จำลองการเติบโตของอาณานิคมสิ่งมีชีวิต แม้จะดูไม่มีระเบียบแต่ก็มีรูปแบบที่สวยงาม เกมนี้เป็นกริด 2 มิติ ประกอบด้วยเซลล์ "มีชีวิต" (on) และ "ตาย" (off)

กฎของ Game of Life

  • Overpopulation (ประชากรหนาแน่น): เซลล์ตาย หากรอบๆ มีเซลล์มีชีวิตมากกว่า 3 ตัว
  • Static (คงที่): เซลล์มีชีวิตต่อ หากรอบๆ มีเซลล์มีชีวิต 2 หรือ 3 ตัว
  • Underpopulation (ประชากรน้อย): เซลล์ตาย หากรอบๆ มีเซลล์มีชีวิตน้อยกว่า 2 ตัว
  • Reproduction (การสืบพันธุ์): เซลล์ตายกลายเป็นมีชีวิต หากรอบๆ มีเซลล์มีชีวิตพอดี 3 ตัว

ขั้นตอนการนำไปใช้

  1. สร้างจักรวาลว่างเปล่า
  2. เติมเมล็ดพันธุ์ (seed) เริ่มต้น
  3. คำนวณว่าเซลล์ปัจจุบันจะรอดชีวิตไปรอบต่อไปหรือไม่ โดยดูจากเพื่อนบ้าน
  4. ทำซ้ำขั้นตอนที่ 3 สำหรับทุกเซลล์ในจักรวาล
  5. ทำซ้ำขั้นตอน 3-4 ตามจำนวนรุ่นที่ต้องการ

การติดตั้ง

$ pip install numpy matplotlib

โค้ดตัวอย่าง

import numpy as np
import matplotlib.pyplot as plt
import argparse
import time

class Board(object):
    def __init__(self, size, seed='Random'):
        if seed == 'Random':
            self.state = np.random.randint(2, size=size)
        self.engine = Engine(self)
        self.iteration = 0
    
    def animate(self):
        i = self.iteration
        im = None
        plt.title("Conway's Game of Life")
        while True:
            if i == 0:
                plt.ion()
                im = plt.imshow(self.state, vmin=0, vmax=2, cmap=plt.cm.gray)
            else:
                im.set_data(self.state)
            i += 1
            self.engine.applyRules()
            print('Life Cycle: {} Birth: {} Survive: {}'.format(i, self.engine.nBirth, self.engine.nSurvive))
            plt.pause(0.01)
            yield self

class Engine(object):
    def __init__(self, board):
        self.state = board.state
    
    def countNeighbors(self):
        state = self.state
        n = (state[0:-2,0:-2] + state[0:-2,1:-1] + state[0:-2,2:] +
             state[1:-1,0:-2] + state[1:-1,2:] + state[2:,0:-2] +
             state[2:,1:-1] + state[2:,2:])
        return n
    
    def applyRules(self):
        n = self.countNeighbors()
        state = self.state
        birth = (n == 3) & (state[1:-1,1:-1] == 0)
        survive = ((n == 2) | (n == 3)) & (state[1:-1,1:-1] == 1)
        state[...] = 0
        state[1:-1,1:-1][birth | survive] = 1
        nBirth = np.sum(birth)
        self.nBirth = nBirth
        nSurvive = np.sum(survive)
        self.nSurvive = nSurvive
        return state

def main():
    ap = argparse.ArgumentParser(add_help=False)
    ap.add_argument('-h', '--height', help='Board Height', default=256)
    ap.add_argument('-w', '--width', help='Board Width', default=256)
    args = vars(ap.parse_args())
    bHeight = int(args['height'])
    bWidth = int(args['width'])
    board = Board((bHeight, bWidth))
    for _ in board.animate():
        pass

if __name__ == '__main__':
    main()

ผลลัพธ์

โปรแกรมจะแสดงแอนิเมชันในหน้าต่าง matplotlib และพิมพ์สถิติในคอนโซล:

Life Cycle: 1 Birth: 7166 Survive: 10621
Life Cycle: 2 Birth: 7930 Survive: 8409
...

กด Ctrl-C เพื่อหยุดโปรแกรม

คุณสมบัติเพิ่มเติม

  • สามารถปรับขนาดกริดผ่านอาร์กิวเมนต์ `-h` และ `-w`
  • แสดงกราฟิกสวยงามแบบ real-time
  • ใช้ NumPy สำหรับการคำนวณเมทริกซ์ที่รวดเร็ว