<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
由劍橋大學約翰·何頓·康威設計的計算機程式。美國趣味數學大師馬丁·加德納(Martin Gardner,1914-2010)通過《科學美國人》雜誌,將康威的生命遊戲介紹給學術界之外的廣大瀆者,一時吸引了各行各業一大批人的興趣,這時細胞自動機課題才吸引了科學家的注意。
用一個二維表格表示“生存空間”,空間的每個方格中都可放置一個生命細胞,每個生命細胞只有兩種狀態:“生”或“死”。用綠色方格表示該細胞為“生”,空格(白色)表示該細胞為“死”。或者說方格網中綠色部分表示某個時候某種“生命”的分佈圖。生命遊戲想要模擬的是:隨著時間的流逝,這個分佈圖將如何一代一代地變化。死亡太沉重,我想稱它為“湮滅”狀態。
生存空間的每個方格都存在一個細胞,它的周邊緊鄰的8個方格上的稱為鄰居細胞。
(1)當前細胞為湮滅狀態時,當週圍有3個存活細胞時,則迭代後該細胞變成存活狀態(模擬繁殖)。
(2)當前細胞為存活狀態時,當週圍的鄰居細胞少於2個存活時,該細胞變成湮滅狀態(數量稀少)。
(3)當前細胞為存活狀態時,當週圍有3個以上的存活細胞時,該細胞變成湮滅狀態(數量過多)。
(4)當前細胞為存活狀態時,當週圍有2個或3個存活細胞時,該細胞保持原樣。
簡單來說,活細胞Cell看作是‘1’,死Cell看作‘0’,8個鄰居的累加和Sum決定了下一輪的狀態:
“繁殖”:死Cell=0,若Sum=3,則Cell=1。
“稀少”:活Cell=1,若Sum<2,則Cell=0。
“過多”:活Cell=1,若Sum>3,則Cell=0。
“正常”:活Cell=1,若Sum=2或3,則Cell=1。
生存空間中生命的繁殖和湮滅,如下圖所示:
在遊戲進行中,雜亂無序的細胞會逐漸演化出各種精緻、有形的圖形結構;這些結構往往有很好的對稱性,而且每一代都在變化形狀。一些形狀一經鎖定就不會逐代變化。有時,一些已經成形的結構會因為一些無序細胞的“入侵”而被破壞。但是形狀和秩序經常能從雜亂中產生出來。
通常會有以下四種狀態:
不動點(fixed points):變化終結於恆定影象
交替態(alternation):影象出現週期性變化
隨機態(randomness):影象變化近乎隨機
複雜態(complexity):影象存在某種複雜規律
常見的不動結構:
週期變化的結構:
逐步趨向湮滅的結構:
由一根10個連續細胞演化出來的週期結構:
動態變化後全部湮滅的結構:
移動的飛船:週期變化且逐漸向右平移
飛船到了邊界變成向對角線移動的“滑翔者”,滑翔者到了邊界成為不動的方塊。
更多有趣的圖形結構有待發現,用程式碼來輔助這項工作還是比較方便的.....
用tkinter庫實現了軟體介面,畫布、按鈕、標籤等控制元件都是配角,全是為表現生命繁殖演化的核心程式碼類方法 Lifes.reproduce() 作幫手的,原始碼lifegame.pyw如下:
from tkinter import messagebox as msgbox import tkinter as tk import webbrowser import random class Lifes: def __init__(self, rows=38, cols=38): self.row = rows self.col = cols self.items = [[0]*self.col for _ in range(self.row)] self.histroy = [] self.histroySize = 30 self.running = False self.runningSpeed = 100 def rndinit(self, rate=0.1): self.histroy = [] for i in range(self.row): for j in range(self.col): rnd = random.random() if rnd > 1-rate: self.items[i][j]=1 def reproduce(self): new = [[0]*self.col for _ in range(self.row)] self.add_histroy() if len(self.histroy) > self.histroySize: self.histroy.pop(0) for i in range(self.row): for j in range(self.col): if i*j==0 or i==self.row-1 or j==self.col-1: new[i][j]=0 else: lifes=0 for m in range(i-1,i+2): for n in range(j-1,j+2): if m==i and n==j: continue lifes += self.items[m][n] if self.items[i][j]: if lifes==2 or lifes==3: new[i][j]=1 else: new[i][j]=0 else: if lifes==3: new[i][j]=1 for idx,narray in enumerate(new): self.items[idx] = narray def is_stable(self): if len(self.histroy)<self.histroySize: return False arr = [] for i in self.histroy: if i not in arr: arr.append(i) if len(arr)<10: return True def add_histroy(self, Items=None): arr = [] if Items==None: Items=self.items[:] for item in Items: b = 0 for i,n in enumerate(item[::-1]): b += n*2**i arr.append(b) self.histroy.append(arr) def drawCanvas(): global tv,rect tv = tk.Canvas(win, width=win.winfo_width(), height=win.winfo_height()) tv.pack(side = "top") for i in range(36): coord = 40, 40, 760, i*20 + 40 tv.create_rectangle(coord) coord = 40, 40, i*20 + 40, 760 tv.create_rectangle(coord) coord = 38, 38, 760, 760 tv.create_rectangle(coord,width=2) coord = 39, 39, 760, 760 tv.create_rectangle(coord,width=2) coord = 38, 38, 762, 762 tv.create_rectangle(coord,width=2) R,XY = 8,[50+i*20 for i in range(36)] rect = [[0]*36 for _ in range(36)] for i,x in enumerate(XY): for j,y in enumerate(XY): rect[i][j] = tv.create_rectangle(x-R,y-R,x+R,y+R,tags=('imgButton1')) tv.itemconfig(rect[i][j],fill='lightgray',outline='lightgray') tv.tag_bind('imgButton1','<Button-1>',on_Click) def drawLifes(): R,XY = 8,[50+i*20 for i in range(36)] if Life.running: for i,x in enumerate(XY): for j,y in enumerate(XY): if Life.items[i+1][j+1]: tv.itemconfig(rect[i][j],fill='green',outline='green') else: tv.itemconfig(rect[i][j],fill='lightgray',outline='lightgray') tv.update() Life.reproduce() if Life.is_stable(): Life.running = False if sum(sum(Life.items,[])): msgbox.showinfo('Message','生命繁殖與湮滅進入穩定狀態!!!') else: msgbox.showinfo('Message','生命全部湮滅,進入死亡狀態!!!') win.after(Life.runningSpeed, drawLifes) def StartLife(): if sum(sum(Life.items,[])): Life.histroy = [] Life.running = True else: msgbox.showinfo('Message','請點選小方塊填入生命細胞,或者使用隨機功能!') def BreakLife(): Life.running = not Life.running if Life.running: Life.histroy.clear() Life.add_histroy() def RandomLife(): Life.rndinit() Life.running = True def ClearLife(): Life.running = False Life.histroy = [] Life.items = [[0]*38 for _ in range(38)] for x in range(36): for y in range(36): tv.itemconfig(rect[x][y],fill='lightgray',outline='lightgray') def on_Enter(event): tCanvas.itemconfig(tVisit, fill='magenta') def on_Leave(event): tCanvas.itemconfig(tVisit, fill='blue') def on_Release(event): url = 'https://blog.csdn.net/boysoft2002?type=blog' webbrowser.open(url, new=0, autoraise=True) def on_Click(event): x,y = (event.x-40)//20,(event.y-40)//20 if not Life.running: if Life.items[x+1][y+1]: tv.itemconfig(rect[x][y],fill='lightgray',outline='lightgray') else: tv.itemconfig(rect[x][y],fill='red',outline='red') Life.items[x+1][y+1] = not Life.items[x+1][y+1] def on_Close(): if msgbox.askokcancel("Quit","Do you want to quit?"): Life.running = False print(Copyright()) win.destroy() def Introduce(): txt = '''【生命遊戲】nn生存定律: (1)當前細胞為湮滅狀態時,當週圍有3個存活細胞時,則迭代後該細胞變成存活狀態(模擬繁殖)。 (2)當前細胞為存活狀態時,當週圍的鄰居細胞少於2個存活時,該細胞變成湮滅狀態(數量稀少)。 (3)當前細胞為存活狀態時,當週圍有3個以上的存活細胞時,該細胞變成湮滅狀態(數量過多)。 (4)當前細胞為存活狀態時,當週圍有2個或3個存活細胞時,該細胞保持原樣。''' return txt def Copyright(): return 'Lifes Game Ver1.0nWritten by HannYang, 2022/08/01.' if __name__ == '__main__': win = tk.Tk() X,Y = win.maxsize() W,H = 1024,800 winPos = f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}' win.geometry(winPos) win.resizable(False, False) win.title('生命遊戲 Ver1.0') win.update() drawCanvas() Life = Lifes() drawLifes() tLabel = tk.Label(win, width=30, height=20, background='lightgray') tLabel.place(x=780, y=38) tLabel.config(text='nnn'.join((Introduce(),Copyright()))) tLabel.config(justify=tk.LEFT,anchor="nw",borderwidth=10,wraplength=210) bX,bY,dY = 835, 458, 50 tButton0 = tk.Button(win, text=u'開始', command=StartLife) tButton0.place(x=bX, y=bY+dY*0 ,width=120,height=40) tButton1 = tk.Button(win, text=u'暫停', command=BreakLife) tButton1.place(x=bX, y=bY+dY*1 ,width=120,height=40) tButton2 = tk.Button(win, text=u'隨機', command=RandomLife) tButton2.place(x=bX, y=bY+dY*2 ,width=120,height=40) tButton3 = tk.Button(win, text=u'清空', command=ClearLife) tButton3.place(x=bX, y=bY+dY*3 ,width=120,height=40) tCanvas = tk.Canvas(win, width=200, height=45) tCanvas.place(x=800,y=716) tVisit = tCanvas.create_text((88, 22), text=u"點此存取Hann's CSDN主頁!") tCanvas.itemconfig(tVisit, fill='blue', tags=('btnText')) tCanvas.tag_bind('btnText','<Enter>',on_Enter) tCanvas.tag_bind('btnText','<Leave>',on_Leave) tCanvas.tag_bind('btnText','<ButtonRelease-1>',on_Release) win.protocol("WM_DELETE_WINDOW", on_Close) win.mainloop()
編譯命令
D:> pyinstaller -F lifegame.pyw --noconsole
在生存空間裡點選方格種植細胞(甚至可以畫出你要表達的圖形),然後點選開始;點下暫停鍵,則可以任意編輯生命圖形,再點開始繼續執行;點隨機鍵則由軟體隨機生成細胞位置;清空鍵可以在任何時候清空生存空間,進入暫停編輯狀態。
Lifes類預留了histroy屬性,後續可以增加回退功能;程式碼缺點是生存空間的行列被我寫死了,以後版本中可以改進成任意定義行列數;另一個缺點是對穩定狀態的判斷比較簡單,之後可以增加計算變化週期的功能。
優點就是可以任意編輯你的圖形,最後以一張自己的網名畫的圖作收尾:
前部分介紹性文字來源於百度百科等網路資源
以上就是Python實現生命遊戲的範例程式碼(tkinter版)的詳細內容,更多關於Python 生命遊戲的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45