基于python做一個(gè)2048小游戲
邏輯設(shè)計(jì)
2048的邏輯無非是操作4 × 4 的方格,每個(gè)方格中有一個(gè)數(shù),這些數(shù)可以移動(dòng),如果兩個(gè)相同的數(shù)字在移動(dòng)時(shí)相撞了,就可以彼此合并。
而這個(gè)4 × 4的方格,無非是一個(gè)矩陣。只需設(shè)計(jì)好移動(dòng)邏輯,再用PyGame將這個(gè)方格表現(xiàn)出來就算大功告成。
2048只有四個(gè)手勢(shì)動(dòng)作,即上下左右,這四個(gè)動(dòng)作所引發(fā)的結(jié)果都可以歸結(jié)為對(duì)單行或者單列的操作,進(jìn)而歸結(jié)為對(duì)一個(gè)列表的操作。
首先,對(duì)列表進(jìn)行操作時(shí),先排除0的影響,在排除0的影響之后,若相鄰元素相等,即可合并。例如對(duì)于[ 0 , 2 , 2 , 0 ],如果向左合并則輸出為[ 4 , 0 , 0 , 0 ]。
def mergeLst(lst): lst = [x for x in lst if x] # 刪除lst中的0 newLst = [] N, i = len(lst), 0 while i < N: if i<N-1 and lst[i] == lst[i+1]: newLst.append(lst[i]*2) i += 2 else: newLst.append(lst[i]) i += 1 return newLst + (4-len(newLst))*[0]
測(cè)試如下
mergeLst([0,2,2,0]) # [4, 0, 0, 0] mergeLst([2,2,2,2]) # [4, 4, 0, 0] mergeLst([2,2,8,4]) # [4, 8, 4, 0]
相應(yīng)地,對(duì)一個(gè)矩陣進(jìn)行合并,只需針對(duì)每一行進(jìn)行操作即可
[mergeLst(x) for x in mat]
對(duì)于上下左右不同按鍵的操作,可以先將矩陣旋轉(zhuǎn),然后再進(jìn)行合并操作,合并之后再逆轉(zhuǎn)回來。
def rotate(mat): newMat = [[[] for _ in mat] for b in mat[0]] for i,row in enumerate(mat, 1): for j,r in enumerate(row, 0): newMat[j][-i] = r return newMat
在實(shí)際操作中,左、下、右、上分別對(duì)應(yīng)旋轉(zhuǎn)0,1,2,3次,即
KEY_DCT = { pygame.K_LEFT:0, pygame.K_DOWN:1, pygame.K_RIGHT:2, pygame.K_UP:3 }
從而游戲的總挪動(dòng)邏輯如下
def updateMat(mat, key): N = KEY_DCT[key] for _ in range(N): mat = rotate(mat) mat = [mergeLst(x) for x in mat] for _ in range(4-N): mat = rotate(mat) # 旋轉(zhuǎn)回來 return mat
2048游戲在開始之前,需要初始化一個(gè)4x4
的矩陣,然后每次操作之前,需要在矩陣中為0的位置隨機(jī)生成一個(gè)數(shù)。隨機(jī)生成的數(shù)的取值范圍決定了游戲的難度,所以生成方式也比較靈活,下面給出一種普通的生成方法
from itertools import product from random import sample, randint def addNew(mat): ijs = [] for i,j in product(range(4), range(4)): if mat[i][j] == 0: ijs.appen((i,j)) if len(ijs) == 0: return False i, j = sample(ijs, 1)[0] # 挑選一個(gè)不為0的點(diǎn) x = randint(1,100) x = 7 - np.floor(np.log2(x)) mat[i,j] = int(2**x) return True
繪圖邏輯
這個(gè)游戲的繪圖邏輯比較簡單,只需為矩陣中每個(gè)元素賦予一個(gè)顏色即可。
GRAY = (205, 205, 205) WHITE = (255, 255, 255) GREEN = (0, 255, 0) SIZE = 80 def setColor(N): if N == 0: return (233, 233, 233) n = int(math.log2(N)) delta = int(255/15) return (255-n*delta, n*delta, (128+n*delta)%255) def draw(win, font, mat): for i,j in product(range(4), range(4)): ch = str(mat[i][j]) rect = (j*SIZE, i*SIZE, SIZE, SIZE) c = setColor(mat[i][j]) pygame.draw.rect(win, c, rect) pygame.draw.rect(win, GRAY, rect, 5) txt = font.render(ch, True, GREEN) offset = (0.5 - len(ch)/10)*SIZE xy = (j*SIZE+offset, (i+0.3)*SIZE) win.blit(txt, xy)
主循環(huán)
最后,實(shí)現(xiàn)游戲的主循環(huán)如下
def gui(): pygame.init() win = pygame.display.set_mode( (4 * SIZE, 4 * SIZE)) pygame.display.set_caption("迷宮游戲") font.init() f = font.Font('C:\\WINDOWS\\Fonts\\ARLRDBD.TTF', 32) running = True mat = [[0]*4 for _ in range(4)] addNew(mat) while running: win.fill(WHITE) for evt in pygame.event.get(): if evt.type == pygame.QUIT: return if evt.type == pygame.KEYDOWN and evt.key in KEY_DCT: newMat = updateMat(mat, evt.key) if newMat!=mat: mat = newMat running = addNew(mat) draw(win, f, mat) # 判斷玩家是否到達(dá)出口 if max([max(x) for x in mat])==2048: print("恭喜通關(guān)") running = False if min([min(x) for x in mat])>0: print("游戲失敗") running = False pygame.display.update()
游戲效果如下
以上就是基于python做一個(gè)2048小游戲的詳細(xì)內(nèi)容,更多關(guān)于python 2048小游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python清除指定目錄內(nèi)所有文件中script的方法
這篇文章主要介紹了python清除指定目錄內(nèi)所有文件中script的方法,涉及Python針對(duì)文件、字符串及正則匹配操作的相關(guān)技巧,需要的朋友可以參考下2015-06-06Python使用BeautifulSoup和Scrapy抓取網(wǎng)頁數(shù)據(jù)的具體教程
在當(dāng)今信息爆炸的時(shí)代,數(shù)據(jù)無處不在,如何有效地抓取、處理和分析這些數(shù)據(jù)成為了許多開發(fā)者和數(shù)據(jù)科學(xué)家的必修課,本篇博客將深入探討如何使用Python中的兩個(gè)強(qiáng)大工具:BeautifulSoup和Scrapy來抓取網(wǎng)頁數(shù)據(jù),需要的朋友可以參考下2025-01-01利用20行Python 代碼實(shí)現(xiàn)加密通信
這篇文章主要介紹了利用Python 代碼實(shí)現(xiàn)加密通信,本文用 20 行 Python 代碼來演示加密、解密、簽名、驗(yàn)證的功能。大家依樣畫葫蘆,不僅能理解加密技術(shù),更能自己實(shí)現(xiàn)一套加密通信機(jī)制,需要的朋友可以參考一下2022-03-03關(guān)于python3?opencv?圖像二值化的問題(cv2.adaptiveThreshold函數(shù))
這篇文章主要介紹了python3?opencv?圖像二值化cv2.adaptiveThreshold函數(shù)的相關(guān)知識(shí),結(jié)合示例代碼介紹了adaptiveThreshold方法的用法,需要的朋友可以參考下2022-04-04使用Python高效獲取網(wǎng)絡(luò)數(shù)據(jù)的操作指南
網(wǎng)絡(luò)爬蟲是一種自動(dòng)化程序,用于訪問和提取網(wǎng)站上的數(shù)據(jù),Python是進(jìn)行網(wǎng)絡(luò)爬蟲開發(fā)的理想語言,擁有豐富的庫和工具,使得編寫和維護(hù)爬蟲變得簡單高效,本文將詳細(xì)介紹如何使用Python進(jìn)行網(wǎng)絡(luò)爬蟲開發(fā),包括基本概念、常用庫、數(shù)據(jù)提取方法、反爬措施應(yīng)對(duì)以及實(shí)際案例2025-03-03Python調(diào)整數(shù)組形狀如何實(shí)現(xiàn)
這篇文章主要介紹了Python調(diào)整數(shù)組形狀如何實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-12-12Python函數(shù)式編程指南(二):從函數(shù)開始
這篇文章主要介紹了Python函數(shù)式編程指南(二):從函數(shù)開始,本文講解了定義一個(gè)函數(shù)、使用函數(shù)賦值、閉包、作為參數(shù)等內(nèi)容,需要的朋友可以參考下2015-06-06