Python生命游戲?qū)崿F(xiàn)原理及過程解析(附源代碼)
1. 生命游戲是什么
生命游戲是英國數(shù)學(xué)家約翰·何頓·康威在1970年發(fā)明的細(xì)胞自動(dòng)機(jī)。它包括一個(gè)二維矩形世界,這個(gè)世界中的每個(gè)方格居住著一個(gè)活著的或死了的細(xì)胞。一個(gè)細(xì)胞在下一個(gè)時(shí)刻生死取決于相鄰八個(gè)方格中活著的或死了的細(xì)胞的數(shù)量。如果相鄰方格活著的細(xì)胞數(shù)量過多,這個(gè)細(xì)胞會因?yàn)橘Y源匱乏而在下一個(gè)時(shí)刻死去;相反,如果周圍活細(xì)胞過少,這個(gè)細(xì)胞會因太孤單而死去。
規(guī)則看起來很簡單,但卻能演繹出無窮無盡的內(nèi)容。
滑翔者:每4個(gè)回合"它"會向右下角走一格。雖然細(xì)胞早就是不同的細(xì)胞了,但它能保持原本的形態(tài)。
輕量級飛船:它的周期是4,每2個(gè)回合會向右邊走一格。
脈沖星:它的周期為3,看起來像一顆周期爆發(fā)的星星。
更復(fù)雜的圖案。
來體會一下這些作品的腦洞以及震撼:
史詩般的生命游戲 http://www.iqiyi.com/w_19rsq435c9.html
用生命游戲?qū)崿F(xiàn)生命游戲:http://www.bilibili.com/video/av616329/index.html
2. Console版:一個(gè)簡單的Python實(shí)現(xiàn)
生命游戲的規(guī)則其實(shí)很簡單。我們可以把計(jì)算機(jī)中的宇宙想象成是一堆方格子構(gòu)成的封閉空間,尺寸為N的空間就有N*N個(gè)格子。
而每一個(gè)格子都可以看成是一個(gè)生命體,每個(gè)生命都有生和死兩種狀態(tài),如果該格子生就顯示藍(lán)色,死則顯示白色。每一個(gè)格子旁邊都有鄰居格子存在,如果我們把3*3的9個(gè)格子構(gòu)成的正方形看成一個(gè)基本單位的話,那么這個(gè)正方形中心的格子的鄰居就是它旁邊的8個(gè)格子。
每個(gè)格子的生死遵循下面的原則:
1. 如果一個(gè)細(xì)胞周圍有3個(gè)細(xì)胞為生(一個(gè)細(xì)胞周圍共有8個(gè)細(xì)胞),則該細(xì)胞為生(即該細(xì)胞若原先為死,則轉(zhuǎn)為生,若原先為生,則保持不變) 。
2. 如果一個(gè)細(xì)胞周圍有2個(gè)細(xì)胞為生,則該細(xì)胞的生死狀態(tài)保持不變;
3. 在其它情況下,該細(xì)胞為死(即該細(xì)胞若原先為生,則轉(zhuǎn)為死,若原先為死,則保持不變)
設(shè)定圖像中每個(gè)像素的初始狀態(tài)后依據(jù)上述的游戲規(guī)則演繹生命的變化,由于初始狀態(tài)和迭代次數(shù)不同,將會得到令人嘆服的優(yōu)美圖案。
我們用#代表活的細(xì)胞,空格表示死的細(xì)胞,那么我們可以用控制臺打印字符、清屏來模擬生命游戲。我的代碼在github上:
https://github.com/Pleiades0428/GameOfLife/blob/master/Demo/gameOfLife.py
游戲世界尺寸為60x20,隨機(jī)生成初始狀態(tài),循環(huán)邊界,按任意鍵進(jìn)入下一幀,q退出。
單純的看這段程序,好像并沒有什么問題,代碼邏輯正確、清晰。
效果圖:
3. Python列表生成式
我們來嘗試一些python的高級特性,比如列表生成式。
例如,在生成初始值時(shí),我們一般這樣寫:
screen = [] width = 60 height = 20 def Init(): for i in range(height): line = [] for j in range(width): if random.random() > 0.8: line.append('#') else: line.append(' ') screen.append(line)
如果用列表生成式,我們可以這樣寫:
def Init(): global screen screen = [['#' if random.random() > 0.8 else ' ' for i in range(width)] for j in range(height)]
注意這里必須用global聲明,否則screen將默認(rèn)作為函數(shù)內(nèi)的局部變量。這里用了兩層列表生成式來生成一個(gè)二維數(shù)組。
列表生成式很好很強(qiáng)大,如果用好能大大提高效率。但會犧牲一定的可讀性,如果單個(gè)表達(dá)式寫的過于復(fù)雜,那就變成write-only了。尤其是在團(tuán)隊(duì)開發(fā)情況下,可讀性日益重要。
重寫后的代碼:
https://github.com/Pleiades0428/GameOfLife/blob/master/Demo/gameOfLife.1.py
如果僅僅是作為練習(xí),這樣就已經(jīng)足夠好了,簡潔易讀。
4. 重構(gòu):面向?qū)ο笈c重用
可是我們還不能滿足,我們來給生命插上面向?qū)ο蟮某岚?,在模塊化的天空中翱翔。對,就是讓他跟別的模塊搞對象!
先來定義一個(gè)類GameOfLifeWorld,之前那些丑陋的全局變量,讓他們統(tǒng)統(tǒng)變成成員變量,再也不能在外興風(fēng)作浪。
class GameOfLifeWorld: width = 100 height = 100 cells = [] …略
然后把UI層剝離,只保留游戲的核心邏輯。
代碼:
https://github.com/Pleiades0428/GameOfLife/blob/master/Demo/gameOfLifeWorld.py
5. GUI:Tkinter的調(diào)用
有了上一步的鋪墊,我們終于可以讓Tkinter粉墨登場了。Tkinter是著名的UI庫,Python自帶的Tkinter是一個(gè)精簡版,不過也夠我們用的了。
我們這里用到的主要是Canvas,Button控件。Canvas畫布用來繪制游戲區(qū),Button用來交互。
代碼:
https://github.com/Pleiades0428/GameOfLife/blob/master/Demo/gameOfLifeWorld.py
效果:
以上就是這樣,項(xiàng)目我還會繼續(xù)改進(jìn),希望大家喜歡。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
pytorch之關(guān)于PyTorch結(jié)構(gòu)介紹
這篇文章主要介紹了pytorch之關(guān)于PyTorch結(jié)構(gòu)的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09淺談keras中自定義二分類任務(wù)評價(jià)指標(biāo)metrics的方法以及代碼
這篇文章主要介紹了淺談keras中自定義二分類任務(wù)評價(jià)指標(biāo)metrics的方法以及代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06python遠(yuǎn)程連接服務(wù)器MySQL數(shù)據(jù)庫
這篇文章主要為大家詳細(xì)介紹了python遠(yuǎn)程連接服務(wù)器MySQL數(shù)據(jù)庫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07磁盤垃圾文件清理器python代碼實(shí)現(xiàn)
幾行Python代碼打造自己的磁盤垃圾文件清理器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03Python中使用PyQt把網(wǎng)頁轉(zhuǎn)換成PDF操作代碼實(shí)例
這篇文章主要介紹了Python中使用PyQt把網(wǎng)頁轉(zhuǎn)換成PDF操作代碼實(shí)例,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-04-04Windows上使用virtualenv搭建Python+Flask開發(fā)環(huán)境
在自己本機(jī)的開發(fā)環(huán)境下,我們完全可以使用virtualenv來hold住多個(gè)Python環(huán)境,這樣就可以留出一個(gè)專門服役于Flask框架,哈哈,這里我們就來看看如何在Windows系統(tǒng)上使用virtualenv搭建Python+Flask開發(fā)環(huán)境2016-06-06使用python查找windows系統(tǒng)中所有程序的安裝信息
這篇文章主要為大家介紹了使用python查找windows系統(tǒng)中所有程序的安裝信息示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07