Python實戰(zhàn)之實現(xiàn)康威生命游戲
前言
康威生命游戲設(shè)計并不難,我的思路就是借助pygame進(jìn)行外觀的展示,最近一段時間的游戲項目都是使用pygame進(jìn)行的,做起來比較順利。內(nèi)部代碼的實現(xiàn)也比較簡單根據(jù)他的規(guī)則我們需要的是多次的計算和判斷,再刷新數(shù)組。
一、康威生命游戲規(guī)則
當(dāng)周圍僅有1個或沒有存活細(xì)胞時, 原來的存活細(xì)胞進(jìn)入死亡狀態(tài)。(模擬生命數(shù)量稀少)當(dāng)周圍有2個或3個存活細(xì)胞時, 網(wǎng)格保持原樣。當(dāng)周圍有4個及以上存活細(xì)胞時,原來的存活細(xì)胞亦進(jìn)入死亡狀態(tài)。(模擬生命數(shù)量過多)當(dāng)周圍有3個存活細(xì)胞時,空白網(wǎng)格變成存活細(xì)胞。(模擬繁殖)
二、設(shè)計流程
1. 引入庫
代碼如下(示例):
import sys import random import numpy as np import pygame
2. 設(shè)計思路
在這篇博客里面我們實現(xiàn)了下面第一個圖的內(nèi)容。
感興趣的朋友也可以加下面的思路:
3. 設(shè)計窗口
首先我們借用了之前的pygame窗口的代碼,實現(xiàn)窗口的調(diào)用。與之前有所不同的變化是,我們在展開窗口之前首先確定大小。
我們實現(xiàn)了游戲大小的自定義,窗口大小的自定義,可以與后面游戲設(shè)計增加統(tǒng)一性,增加美觀性。
中間的部分代碼是一些顏色的調(diào)出,和窗口的填充。
import sys import random import numpy as np import pygame pygame.init()#初始化init()及設(shè)置 n=int(input("請輸入階數(shù):")) size=width,height=50*n+2,50*n+2 screen=pygame.display.set_mode(size)#窗口大小 pygame.display.set_caption("康威生命游戲")#窗口名字 icon=pygame.image.load("Icon.jpg") pygame.display.set_icon(icon) BLACK=pygame.Color("black") GAINSBORO=pygame.Color("gainsboro") MOCCASIN=pygame.Color("moccasin") WHITE=pygame.Color("white") screen.fill(MOCCASIN) fps=5 fclock=pygame.time.Clock()#創(chuàng)建一個Clock對象用于操作時間 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: # 點擊了退出 sys.exit() # 退出 pygame.display.update() # 對顯示窗口進(jìn)行更新,默認(rèn)窗口全部重繪 fclock.tick(fps) # 窗口刷新速度,每秒3次
三、初始生命矩陣
我們通過循環(huán)產(chǎn)生隨機(jī)數(shù)來產(chǎn)生隨機(jī)的初始生命。
random.randint(a,b)
:產(chǎn)生一個位于a-b之間的隨機(jī)整數(shù),包括a,b。
## 生成初始生命 a=[] for i in range(0,n): a.append([]) for j in range(0,n): a[i].append(random.randint(0,1))
四、周圍生命的檢測
我們將生命周圍八個位置的索引差值存放在一個列表中,通過循環(huán)檢測有效位置上生命的個數(shù),存放入列表中。
包含兩個判斷。
1.首先要判斷位置的有效性
2.另一個是判斷是否有生命
direction = [[-1, -1], [0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0]] c = [] # 計算周圍生命個數(shù) for i in range(0, n): c.append([]) for j in range(0, n): count = 0 # 每一個方格 for o in direction: ide = np.array([i, j]) + np.array(o) # 保證判斷的位置在范圍內(nèi),針對邊界方格 if 0 <= ide[0] < n and 0 <= ide[1] < n: if a[ide[0]][ide[1]] == 1: count += 1 c[i].append(count)
五、生命的變化
將每個位置上的生命根據(jù)計數(shù)列表進(jìn)行更新,更新生命矩陣。
## 按照生命的發(fā)展規(guī)律進(jìn)行新一輪的生面變化 for i in range(0, n): for j in range(0, n): if c[i][j] <= 1 or c[i][j] >= 4:#當(dāng)生命稀少或者過多時生命死亡 a[i][j] = 0 elif c[i][j] == 3:#當(dāng)生命的周圍有三個生命時,生成新生命 a[i][j] = 1
六、生命的展示
畫出生命的方格很簡單,我們調(diào)用pygame的繪制圖形代碼:
pygame.draw.rect(screen, BLACK, (i*50, j*50, 50, 50)):這樣展示出來的是一個填充的矩形,展示在:screen上,初始位置為:(i * 50, j * 50),大小為:(50, 50),顏色為:black,默認(rèn)邊框為0,即全部填充的矩形,當(dāng)后面添加一個數(shù)字時,代表無填充,框線為數(shù)字大小的矩形,如:pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2)代表不填充,框線為2
通過畫圖重疊,我們實現(xiàn)每個生命之間的間隔的樣式,增強(qiáng)渲染效果。
for i in range(0, n): for j in range(0, n): if a[i][j]==1: #先畫一個滿填充的方格,有生命方格 pygame.draw.rect(screen, BLACK, (i*50, j*50, 50, 50)) #再畫一個不填充,框線為2的方格,套在上面的方格上面 pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2) else:#無生命方格 pygame.draw.rect(screen, WHITE, (i*50, j*50, 50, 50)) pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2)
七、完整代碼
""" # -*- coding: utf-8 -*- # @Time : 2021/4/23 0023 17:14 # @Author : 源來很巧 # @FileName: 康威生命游戲2.py # @Software: PyCharm # @Blog :https://blog.csdn.net/qq_44793283 """ import sys import random import numpy as np import pygame pygame.init()#初始化init()及設(shè)置 n=int(input("請輸入階數(shù):")) size=width,height=50*n+2,50*n+2 screen=pygame.display.set_mode(size)#窗口大小 pygame.display.set_caption("康威生命游戲")#窗口名字 icon=pygame.image.load("Icon.jpg") pygame.display.set_icon(icon) BLACK=pygame.Color("black") GAINSBORO=pygame.Color("gainsboro") MOCCASIN=pygame.Color("moccasin") WHITE=pygame.Color("white") screen.fill(MOCCASIN) fps=1 fclock=pygame.time.Clock()#創(chuàng)建一個Clock對象用于操作時間 ## 生成初始生命 a=[] for i in range(0,n): a.append([]) for j in range(0,n): a[i].append(random.randint(0,1)) ## 八個方位的索引變化 direction = [[-1, -1], [0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0]] while True: for event in pygame.event.get(): if event.type == pygame.QUIT: # 點擊了退出 sys.exit() # 退出 c = [] # 計算周圍生命個數(shù) for i in range(0, n): c.append([]) for j in range(0, n): count = 0 # 每一個方格 for o in direction: ide = np.array([i, j]) + np.array(o) # 保證判斷的位置在范圍內(nèi),針對邊界方格 if 0 <= ide[0] < n and 0 <= ide[1] < n: if a[ide[0]][ide[1]] == 1: count += 1 c[i].append(count) ## 按照生命的發(fā)展規(guī)律進(jìn)行新一輪的生面變化 for i in range(0, n): for j in range(0, n): if c[i][j] <= 1 or c[i][j] >= 4:#當(dāng)生命稀少或者過多時生命死亡 a[i][j] = 0 elif c[i][j] == 3:#當(dāng)生命的周圍有三個生命時,生成新生命 a[i][j] = 1 for i in range(0, n): for j in range(0, n): if a[i][j]==1: #先畫一個滿填充的方格,有生命方格 pygame.draw.rect(screen, BLACK, (i*50, j*50, 50, 50)) #再畫一個不填充,框線為2的方格,套在上面的方格上面 pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2) else:#無生命方格 pygame.draw.rect(screen, WHITE, (i*50, j*50, 50, 50)) pygame.draw.rect(screen, GAINSBORO, (i*50, j*50, 50, 50),2) print(np.array(a)) pygame.display.update() # 對顯示窗口進(jìn)行更新,默認(rèn)窗口全部重繪 fclock.tick(fps) # 窗口刷新速度,每秒3次
總結(jié)
這個游戲的實際設(shè)計并不是很困難,我們需要將具體的思路理順,哪一步首先進(jìn)行,需要我們準(zhǔn)備哪些存儲的矩陣等等。唯一的彎路是周圍生命個數(shù)的檢測,我的方法是窮舉法,將每個位置索引只差手動計算存儲起來。在小的計算量下,這層循環(huán)計算并不會浪費很多時間,如果您對此有好的建議歡迎交流。也歡迎對后面的游戲結(jié)束進(jìn)行交流,后續(xù)我可以補上結(jié)束游戲的方法。
到此這篇關(guān)于Python實戰(zhàn)之實現(xiàn)康威生命游戲的文章就介紹到這了,更多相關(guān)Python實現(xiàn)康威生命游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
selenium + python 獲取table數(shù)據(jù)的示例講解
今天小編就為大家分享一篇selenium + python 獲取table數(shù)據(jù)的示例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10python3.7 openpyxl 在excel單元格中寫入數(shù)據(jù)實例
這篇文章主要介紹了python3.7 openpyxl 在excel單元格中寫入數(shù)據(jù)實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09python使用socket制作聊天室詳細(xì)源碼(可以直接運行)
Python是一個非常靈活的編程語言,我們現(xiàn)在到處可見用Python編寫的應(yīng)用程序,下面這篇文章主要給大家介紹了關(guān)于python使用socket制作聊天室的相關(guān)資料,文中的代碼可以直接運行,需要的朋友可以參考下2023-12-12python 實現(xiàn)的發(fā)送郵件模板【普通郵件、帶附件、帶圖片郵件】
這篇文章主要介紹了python 實現(xiàn)的發(fā)送郵件模板,包含Python發(fā)送普通郵件、帶附件及帶圖片郵件相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2019-07-07解決python DataFrame 打印結(jié)果不換行問題
這篇文章主要介紹了解決python DataFrame 打印結(jié)果不換行問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04Python連接數(shù)據(jù)庫學(xué)習(xí)之DB-API詳解
在沒有 Python DB-API 之前,各數(shù)據(jù)庫之間的應(yīng)用接口非?;靵y,實現(xiàn)各不相同。如果項目需要更換數(shù)據(jù)庫時,則需要做大量的修改,非常不便。Python DB-API 的出現(xiàn)就是為了解決這樣的問題。本文主要介紹了Python連接數(shù)據(jù)庫之DB-API的相關(guān)資料,需要的朋友可以參考。2017-02-02