現代算法可視化(一)、python實現生命遊戲(元胞自動機)

效果展示

在這裏插入圖片描述

規則介紹

基於二維元胞自動機的生命遊戲可視化實現
規則:藍色方塊代表生命

  1. 有顏色的方塊代表生命,無顏色的方塊代表死亡
  2. 一個細胞周圍有八個細胞,對於一個活細胞來說,如果它周圍的八個細胞中:
    如果只有一個或沒有一個是活的,那這個細胞就會死亡
    如果其中兩個或者三個細胞是活的,那這個細胞就能維持生命
    如果超過3個細胞是活着的,那這個細胞就會因爲過於擁擠而死亡
  3. 對於一個死細胞來說,如果這個細胞周圍如果有三個細胞存活,該將獲得新生。

附:所有規則都可以修改,種羣初始密度也可以修改。本實驗採用初始化人口隨機分佈,也可以自定義初始化人口分佈以及網格大小得到滑翔機,播種機等複雜美觀圖形。

源碼

'''
demoName:life simulation game
principle: cellular automata (two dimensional)
the rule of the game :
1. colored cell represents life, uncolored cell represents death
2. a cell has eight cells around it, to a live cell:
2.1 if only one or none of them are live, the cell will die
2.2 if two or three of them are live, the cell will sustain life
2.4 if more than three of them are live, the cell will die
3. to a dead cell, if there are three alive around it ,the cell will gain life
'''

import pygame
import sys 
import math 
import random
import copy

pygame.init()
chess_number=60					# 設置棋盤大小
LIVEDENSITY=0.3						#生命密度
TICK=10								#幀數
BG=(20,20,20)					#背景色
LINECOLOR=(52,53,46)				#網格色
LIFECOLOR=(31,97,189)				#活細胞的顏色
CELL_LENGTH=int(600/chess_number)	#每個格子的像素大小
LINE_WIDTH=4						#線的寬度
START_POSX=50
START_POSY=50
#239,60,57 紅色		79,167,47綠色		188,69,229 紫色
#224,90,9 橙色		252,61,63大紅
#188,69,229	紫色		239,60,57 紅
#39,202,149 天綠	31,97,189藍色		22,178,243 天藍




# 設置背景框大小
size = width, height = 2*START_POSX+chess_number*CELL_LENGTH,2*START_POSY+chess_number*CELL_LENGTH
# 設置幀率,返回clock 類
clock = pygame.time.Clock()
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Accelerator made")


#畫
def draw(livcell):
	'''
	進行一次繪畫操作,可以理解爲進行一幀操作所更新的畫面
	param:操作前活細胞圖
	return:操作後活細胞圖
	'''
	for i in range(chess_number+1):
		pygame.draw.line(screen, LINECOLOR, (START_POSX,START_POSY+i*CELL_LENGTH), (START_POSX+chess_number*CELL_LENGTH,START_POSY+i*CELL_LENGTH), LINE_WIDTH)#橫線
		pygame.draw.line(screen, LINECOLOR, (START_POSX+i*CELL_LENGTH,START_POSY),(START_POSX+i*CELL_LENGTH,START_POSY+chess_number*CELL_LENGTH), LINE_WIDTH)#豎線#
	#畫活細胞
	livcell=rule(livcell)
	print('drawnew',livcell)
	return livcell

def drawcell(i,j,cellkind):
	'''
	畫出一個具體的方塊
	param:行,列,方塊顏色種類
	'''
	pygame.draw.rect(screen,cellkind,[START_POSX+CELL_LENGTH*j+(LINE_WIDTH-1),START_POSY+CELL_LENGTH*i+(LINE_WIDTH-1),CELL_LENGTH-LINE_WIDTH,CELL_LENGTH-LINE_WIDTH],0)#終點.  Rect(left,top,width,height)
		
def creatlife(density):
	'''
	在初始狀態下創造生命
	param:所要求生成生命細胞的密度
	return:初始生命細胞的位置圖
	'''
	livcell=[[0]*chess_number for i in range(chess_number)]
	for i in range(chess_number):
		for j in range(chess_number):
			pwall=random.random()
			if pwall<density:
				livcell[i][j]=1
	return livcell
	
def neighborcell(pos):
	'''
	獲得一個細胞周圍的細胞位置,並且存入數組
	param:細胞的位置
	return:這個細胞所有的鄰居細胞
	'''
	neighborList=[]
	x=pos[0]
	y=pos[1]
	neighborList=[[x-1,y-1],[x-1,y],[x-1,y+1],[x,y-1],[x,y+1],[x+1,y-1],[x+1,y],[x+1,y+1]]
	realnList=copy.deepcopy(neighborList)
	for i in neighborList:
		if i[0]<0 or i[0]>chess_number-1 or i[1]<0 or i[1]>chess_number-1:
			realnList.remove(i)
	return realnList
	
def rule(livcell):
	'''
	制定生命遊戲的遊戲規則
	param:一次操作前所有活着細胞的位置
	return:一次操作後所有活着細胞的位置
	'''
	newlivcell=copy.deepcopy(livcell)
	print('livcell',livcell)
	for i in range(chess_number):
			for j in range(chess_number):
				if livcell[i][j]==1:
					drawcell(i,j,LIFECOLOR)
					alive=0
					for cell in neighborcell([i,j]):
						if livcell[cell[0]][cell[1]]==1:
							alive+=1
					if alive==0 or alive==1:
						newlivcell[i][j]=0
					elif alive==2 or alive==3:
						newlivcell[i][j]=1
					else:
						newlivcell[i][j]=0
				else:
					alive=0
					for cell in neighborcell([i,j]):
						if livcell[cell[0]][cell[1]]==1:
							alive+=1
					if alive==3:
						newlivcell[i][j]=1
	return newlivcell
					
def main():
	livcell=creatlife(LIVEDENSITY)
	while True:
		for event in pygame.event.get():
			# 查找關閉窗口事件
			if event.type == pygame.QUIT:
				sys.exit()
		# 填充背景色
		screen.fill(BG)
		livcell=draw(livcell)
		# 刷新圖s
		pygame.display.flip()
		clock.tick(TICK)

if __name__=="__main__":
	main()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章