2048是一个休闲游戏。规则:每次控制所有方块向一个方向移动,若有两个数字相同,则合并(即得到和)。每次操作后,会在随机在一个空白的方格处随机生成一个2或者4。若玩家凑出2048的方块,则游戏胜利。如果16个格子(4*4)全部填满且无法合并,则游戏结束。
# -*- coding: utf-8 -*- # @Time : 2020/12/15 16:02 # @Author : Zhenghui Lyu # @File : myfunction.py # @Software: PyCharm import random from tkinter import * from tkinter import messagebox as msgbox v = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] def align(vlist, direction): """沿着direction方向对齐vlist中数字""" for i in range(vlist.count(0)): vlist.remove(0) # 移除列表中0元素 zeros = [0 for x in range(4 - len(vlist))] # 空位补几个0数量 if direction == 'left': # 右侧补若干个0 vlist.extend(zeros) else: vlist[:0] = zeros # 左侧补若干个0 def addsame(vlist, direction): """查找相邻数字,相同则合并,原数字翻倍,原数字旁元素变0""" score = 0 if direction == 'left': # 左合并 for i in [0, 1, 2]: if vlist[i] == vlist[i + 1] != 0: vlist[i] *= 2 vlist[i + 1] = 0 score += vlist[i] return {'bool': True, 'score': score} else: for i in [3, 2, 1]: # 右合并 if vlist[i] == vlist[i - 1] != 0: vlist[i] *= 2 vlist[i - 1] = 0 score += vlist[i] return {'bool': True, 'score': score} return {'bool': False, 'score': score} # 无合并 def handle(vlist, direction): """处理一行数据,调用align对齐,调用addsame合并与算此次得分,""" increment = 0 align(vlist, direction) result = addsame(vlist, direction) increment += result['score'] align(vlist, direction) # 游戏机制,对齐合并后,在对齐一次 return increment def isover(): """判断游戏是否结束:1矩阵中无0(没有空白块),且没有相同元素可以合并""" N = 0 # 统计0的个数 global v for q in v: # v为矩阵 N += q.count(0) if N != 0: return False else: for row in range(4): flag = islistover(v[row]) if flag == False: return False for col in range(4): # 判断列 vlist = [v[row][col] for row in range(4)] # 列复制到列表中处理 flag = islistover(vlist) if flag == False: return False return True def islistover(vlist): """判断列表是否还可以合并,若有相同元素还可以合并,则False""" for i in [0, 1, 2]: if vlist[i] == vlist[i + 1] and vlist[i + 1] != 0: return False return True def addelement(N): """将随机数num,添加到随机k区域""" num = random.choice([2, 2, 2, 4]) k = random.randrange(1, N + 1) n = 0 for i in range(4): for j in range(4): if v[i][j] == 0: n += 1 if n == k: v[i][j] = num break def operation(v, op): # v是矩阵,op是移动方向 totalscore = 0 gameover = False direction = 'left' print(op) if op == 'Left': direction = 'left' for row in range(4): totalscore += handle(v[row], direction) elif op == 'Right': direction = 'right' for row in range(4): totalscore += handle(v[row], direction) elif op == 'Up': direction = 'left' for col in range(4): vList = [v[row][col] for row in range(4)] totalscore += handle(vList, direction) for row in range(4): v[row][col] = vList[row] elif op == 'Down': direction = 'right' for col in range(4): vList = [v[row][col] for row in range(4)] totalscore += handle(vList, direction) for row in range(4): v[row][col] = vList[row] N = 0 for q in v: N += q.count(0) if N != 0: addelement(N) if isover(): gameover = True return {'游戏状态': gameover, '得分': totalscore} def init(v): for i in range(4): v[i] = [random.choice([0, 0, 0, 2, 2, 4]) for x in v[i]] def drawgameimage(): global x, y for i in range(0, 4): for j in range(0, 4): m = v[i][j] n = 0 while m > 1: n += 1 m = m / 2 img1 = imgs[n] cv.create_image((j * 120 + 70, i * 120 + 70), image=img1) cv.pack() def callback(event): global score print('按下键:', event.char) KeyCode = event.keysym result = operation(v, KeyCode) drawgameimage() score += result['得分'] root.title('得分:' + str(score)) if result['游戏状态']: print('游戏结束,你是失败了') msgbox.showinfo('游戏结束', '你总得分是:' + str(score)) else: if score >= 2048: print('游戏结束,你赢了!') msgbox.showinfo('游戏结束', '你赢了!!') init(v) score = 0 root = Tk() root.title('2048') imgs = [PhotoImage(file=x) for x in ["0.gif", "2.gif", "4.gif", "8.gif", "16.gif", "32.gif", "64.gif", "128.gif", "256.gif", "512.gif", "1024.gif", "2048.gif", "4096.gif"]] cv = Canvas(root, bg='green', width=500, height=500) drawgameimage() cv.bind('<KeyPress>', callback) cv.pack() cv.focus_set() root.mainloop()
注意图片要转换gif格式,tkinter只支持gif格式。
浙公网安备 33010602011771号