|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 zltzlt 于 2020-8-18 14:45 编辑
在网上参考了好多代码,tkinter写的,求大神帮忙看看怎么改进下
嗯,能不能帮我先解决个问题,怎么发附件呢?
- # python 3.8
- # 2048游戏
- # 初学程序设计,定有许多不足,请高人帮忙看看,指导一下
- # 类还是搞不明白,已经第三版了,可能写的还是乱。
- import random,tkinter,tkinter.messagebox,copy
- class game():
- score = 0 # 分数
- list2048 = [[0]*4 for i in range(4)] # 主数组4*4,存储色块的值,0在页面中显示空
- allLabel = [[0]*4 for i in range(4)] # 存储每个色块的属性
- allColor = {0: "#cdc1b4", # 设置色块颜色,8192及以上就用8192的颜色,一般没人玩到。
- 2: "#eee4da",
- 4: "#ede0c8",
- 8: "#f2b179",
- 16: "#f59563",
- 32: "#f67c5f",
- 64: "#f65e3b",
- 128: "#edcf72",
- 256: "#edcc61",
- 512: "#e4c02a",
- 1024: "#e2ba13",
- 2048: "#ecc400",
- 4096: "#ae84a8",
- 8192: "#b06ca8"}
- keyRotate = {'Up': [3,1], # 根据按键进行数组旋转。为减少代码量,根据按键旋转数组,统一
- 'Down': [1,3], # 进行向左移动,然后将数组转回,字典键值对的第1个值是将数组转
- 'Left': [0,0], # 至向左移动需要转的次数,第2个是还原回原样需要转动的次数。数
- 'Right':[2,2]} # 组转动一圈需要顺时针转动4次。
- window = tkinter.Tk() # 开启一个图形窗口
- window.title("2048游戏") # 设置窗口标题
- window.resizable(width=False,height=False) # 不允许用户改变窗口大小
- for i in range(4): # 生成色块(Label组件),色块属性存放到allLabel数组中
- for j in range(4):
- allLabel[i][j] = tkinter.Label(window,width=6,heigh=3,font=("黑体",30,"bold"),bg=allColor[list2048[i][j]])
- allLabel[i][j].grid(row=i,column=j,padx=1,pady=1)
- tkinter.Label(window,text='分数:',height=2,font=("宋休",20,"bold")).grid(row=4,column=0,sticky='e') # 左下角显示score字样
- scoreLabel = tkinter.Label(window,text=score,height=2,font=("Arial",22,"bold")) # 用于记录分值
- scoreLabel.grid(row=4,column=1,columnspan=3,sticky='w')
- def main(self): # 主函数
- # 按钮放到外面,不知道为什么无法调用init_data函数
- btn = tkinter.Button(self.window,text='重新开始',font=("宋休",20,"bold"),command=self.init_data) # 重新开始的按钮
- btn.grid(row=4,column=1,columnspan=3,padx=8,sticky='e')
- self.init_data() # 调用初始化函数
- self.update_ui() # 刷新窗口页面
- self.window.focus_set() # 响应键盘
- self.window.bind("<Key>",self.key_down) #当按下键盘按键时,调用key_down函数
- self.window.mainloop() # 窗口循环
- def init_data(self): # 初始化函数
- self.score = 0 #分数清零
- self.list2048.clear() # 主数组清空,这个操作不知道是否正确?
- self.list2048 = [([0] * 4) for i in range(4)] # 主数组重新赋0值
- self.add_number() # 加入一个数,初始生成两个数
- self.add_number()
- self.update_ui() # 刷新窗口页面
- def add_number(self): # 判断是否生成一个新数
- randomList = [] # 用于存放0值的索引
- for i in range(4): # 将是0的索引存入新数组中
- for j in range(4):
- if self.list2048[i][j] == 0: # 判断为0时(色块空值)
- randomList.append([i,j]) # 将索引写入randomList数组中
- if len(randomList) > 0: # 大于0表示主数组list2048还有空间
- i = random.sample(randomList,1) # 在0值的索引中随机取出一个索引
- # 因上一步取出的随机数是双层数组,所以这里要用[i[0][0]][i[0][1]]
- self.list2048[i[0][0]][i[0][1]] = random.choice([2,2,2,2,4]) # 加入新的值
- self.update_ui()
- if len(randomList) <= 1: # 根据空格数量,调用判断结束游戏函数
- self.game_judeg()
- def update_ui(self): # 刷新页面函数
- for i in range(4):
- for j in range(4):
- # 0值用''替换
- self.allLabel[i][j]['text'] = '' if self.list2048[i][j]==0 else self.list2048[i][j]
- # 大于或等于8192后,前景颜色全部用8192的颜色(#b06ca8)
- self.allLabel[i][j]['bg'] = "#b06ca8" if self.list2048[i][j]>=8192 else self.allColor[self.list2048[i][j]]
- self.scoreLabel['text'] = self.score # 更新分数
- def game_judeg(self): # 判断游戏是否应该结束
- # 两个双层for循环分别判断横向和纵向相邻两个是否有相同的
- for i in range(4): # 横向
- for j in range(3):
- if self.list2048[i][j] == self.list2048[i][j+1]:
- return
- for i in range(3): # 纵向
- for j in range(4):
- if self.list2048[i][j] == self.list2048[i+1][j]:
- return
- # 如果横纵都没有相同的,游戏结束,弹出提示。
- gameOver = tkinter.messagebox.askyesno(title="游戏结束", message="游戏结束\n重新开始吗?")
- if not gameOver:
- self.window.quit()
- else:
- self.init_data()
- def array_rotate(self,times): # 数组顺时针每次旋转90度,times是旋转次数
- tempList = [[0]*4 for i in range(4)]
- for x in range(times): # 旋转times次
- temp = 3 # 用于索引,因为数组由0开始,所以索引最大值是4-1
- for i in range(4): # 数组顺时针旋转90度,原数组不变
- for j in range(4):
- tempList[j][temp] = self.list2048[i][j]
- temp -= 1
- self.list2048 = copy.deepcopy(tempList) # 用已旋转的数组更新原数组
-
- def key_down(self,event): # 按键处理函数
- if event.keysym == 'Up' or event.keysym == 'Down' or event.keysym == 'Left' or event.keysym == 'Right': # 判断是否按了方向键
- self.array_rotate(self.keyRotate[event.keysym][0]) # 根据按键转动数组
- for i in range(4):
- temp = 0
- for j in range(4): # 检查是否有可以相加的数
- for k in range(j+1,4):
- if self.list2048[i][k] == 0: # 如果该索引值是0,直接进行下一循环。
- continue
- elif self.list2048[i][j] == self.list2048[i][k]: # 如果两个值相同就相加
- self.list2048[i][j] += self.list2048[i][k] # 数值相加,也可以写成 self.list2048[i][j] *= 2
- self.score += self.list2048[i][j] # 更改得分数
- self.list2048[i][k] = 0
- break
- for j in range(4): # 向左移动
- if self.list2048[i][j] != 0:
- self.list2048[i][temp],self.list2048[i][j] = self.list2048[i][j],self.list2048[i][temp]
- temp += 1
- self.array_rotate(self.keyRotate[event.keysym][1]) # 旋转复原数组
- self.add_number() # 如果按了方向键,就调用生成新数的函数
- start = game()
- start.main()
复制代码 |
|