鱼C论坛

 找回密码
 立即注册
查看: 2005|回复: 0

[作品展示] 新人写的2048游戏,130行,几乎每行都有注释,请各位帮我改进一下

[复制链接]
发表于 2020-8-18 14:27:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zltzlt 于 2020-8-18 14:45 编辑

在网上参考了好多代码,tkinter写的,求大神帮忙看看怎么改进下
嗯,能不能帮我先解决个问题,怎么发附件呢?

  1. # python 3.8
  2. # 2048游戏
  3. # 初学程序设计,定有许多不足,请高人帮忙看看,指导一下
  4. # 类还是搞不明白,已经第三版了,可能写的还是乱。

  5. import random,tkinter,tkinter.messagebox,copy
  6. class game():
  7.     score = 0                             # 分数
  8.     list2048 = [[0]*4 for i in range(4)]  # 主数组4*4,存储色块的值,0在页面中显示空
  9.     allLabel = [[0]*4 for i in range(4)]  # 存储每个色块的属性
  10.     allColor = {0:    "#cdc1b4",          # 设置色块颜色,8192及以上就用8192的颜色,一般没人玩到。
  11.                 2:    "#eee4da",
  12.                 4:    "#ede0c8",
  13.                 8:    "#f2b179",
  14.                 16:   "#f59563",
  15.                 32:   "#f67c5f",
  16.                 64:   "#f65e3b",
  17.                 128:  "#edcf72",
  18.                 256:  "#edcc61",
  19.                 512:  "#e4c02a",
  20.                 1024: "#e2ba13",
  21.                 2048: "#ecc400",
  22.                 4096: "#ae84a8",
  23.                 8192: "#b06ca8"}

  24.     keyRotate = {'Up':   [3,1],   # 根据按键进行数组旋转。为减少代码量,根据按键旋转数组,统一
  25.                  'Down': [1,3],   # 进行向左移动,然后将数组转回,字典键值对的第1个值是将数组转
  26.                  'Left': [0,0],   # 至向左移动需要转的次数,第2个是还原回原样需要转动的次数。数
  27.                  'Right':[2,2]}   # 组转动一圈需要顺时针转动4次。

  28.     window = tkinter.Tk()  # 开启一个图形窗口
  29.     window.title("2048游戏")  # 设置窗口标题
  30.     window.resizable(width=False,height=False) # 不允许用户改变窗口大小
  31.     for i in range(4):     # 生成色块(Label组件),色块属性存放到allLabel数组中
  32.         for j in range(4):
  33.             allLabel[i][j] = tkinter.Label(window,width=6,heigh=3,font=("黑体",30,"bold"),bg=allColor[list2048[i][j]])
  34.             allLabel[i][j].grid(row=i,column=j,padx=1,pady=1)
  35.     tkinter.Label(window,text='分数:',height=2,font=("宋休",20,"bold")).grid(row=4,column=0,sticky='e')  # 左下角显示score字样
  36.     scoreLabel = tkinter.Label(window,text=score,height=2,font=("Arial",22,"bold"))  # 用于记录分值
  37.     scoreLabel.grid(row=4,column=1,columnspan=3,sticky='w')

  38.     def main(self):  # 主函数
  39.         # 按钮放到外面,不知道为什么无法调用init_data函数
  40.         btn = tkinter.Button(self.window,text='重新开始',font=("宋休",20,"bold"),command=self.init_data) # 重新开始的按钮
  41.         btn.grid(row=4,column=1,columnspan=3,padx=8,sticky='e')
  42.         self.init_data()  # 调用初始化函数
  43.         self.update_ui()  # 刷新窗口页面
  44.         self.window.focus_set()  # 响应键盘
  45.         self.window.bind("<Key>",self.key_down) #当按下键盘按键时,调用key_down函数
  46.         self.window.mainloop()  # 窗口循环

  47.     def init_data(self):  # 初始化函数
  48.         self.score = 0  #分数清零
  49.         self.list2048.clear()  # 主数组清空,这个操作不知道是否正确?
  50.         self.list2048 = [([0] * 4) for i in range(4)] # 主数组重新赋0值
  51.         self.add_number()  # 加入一个数,初始生成两个数
  52.         self.add_number()
  53.         self.update_ui()  # 刷新窗口页面

  54.     def add_number(self):  # 判断是否生成一个新数
  55.         randomList = []  # 用于存放0值的索引
  56.         for i in range(4):  # 将是0的索引存入新数组中
  57.             for j in range(4):
  58.                 if self.list2048[i][j] == 0:  # 判断为0时(色块空值)
  59.                     randomList.append([i,j])  # 将索引写入randomList数组中
  60.         if len(randomList) > 0:  # 大于0表示主数组list2048还有空间
  61.             i = random.sample(randomList,1)  # 在0值的索引中随机取出一个索引
  62.             # 因上一步取出的随机数是双层数组,所以这里要用[i[0][0]][i[0][1]]
  63.             self.list2048[i[0][0]][i[0][1]] = random.choice([2,2,2,2,4])  # 加入新的值
  64.             self.update_ui()
  65.         if len(randomList) <= 1:  # 根据空格数量,调用判断结束游戏函数
  66.             self.game_judeg()

  67.     def update_ui(self):  # 刷新页面函数
  68.         for i in range(4):
  69.             for j in range(4):
  70.                 # 0值用''替换
  71.                 self.allLabel[i][j]['text'] = '' if self.list2048[i][j]==0 else self.list2048[i][j]
  72.                 # 大于或等于8192后,前景颜色全部用8192的颜色(#b06ca8)
  73.                 self.allLabel[i][j]['bg'] = "#b06ca8" if self.list2048[i][j]>=8192 else self.allColor[self.list2048[i][j]]
  74.                 self.scoreLabel['text'] = self.score  # 更新分数

  75.     def game_judeg(self):  # 判断游戏是否应该结束
  76.         # 两个双层for循环分别判断横向和纵向相邻两个是否有相同的
  77.         for i in range(4):  # 横向
  78.             for j in range(3):
  79.                 if self.list2048[i][j] == self.list2048[i][j+1]:
  80.                     return
  81.         for i in range(3):  # 纵向
  82.             for j in range(4):
  83.                 if self.list2048[i][j] == self.list2048[i+1][j]:
  84.                     return
  85.         # 如果横纵都没有相同的,游戏结束,弹出提示。
  86.         gameOver = tkinter.messagebox.askyesno(title="游戏结束", message="游戏结束\n重新开始吗?")
  87.         if not gameOver:
  88.             self.window.quit()
  89.         else:
  90.             self.init_data()

  91.     def array_rotate(self,times):  # 数组顺时针每次旋转90度,times是旋转次数
  92.         tempList = [[0]*4 for i in range(4)]
  93.         for x in range(times): # 旋转times次
  94.             temp = 3  # 用于索引,因为数组由0开始,所以索引最大值是4-1
  95.             for i in range(4):  # 数组顺时针旋转90度,原数组不变
  96.                 for j in range(4):
  97.                     tempList[j][temp] = self.list2048[i][j]
  98.                 temp -= 1
  99.             self.list2048 = copy.deepcopy(tempList) # 用已旋转的数组更新原数组
  100.             
  101.     def key_down(self,event):  # 按键处理函数
  102.         if event.keysym == 'Up' or event.keysym == 'Down' or event.keysym == 'Left' or event.keysym == 'Right': # 判断是否按了方向键
  103.             self.array_rotate(self.keyRotate[event.keysym][0]) # 根据按键转动数组
  104.             for i in range(4):
  105.                 temp = 0
  106.                 for j in range(4):  # 检查是否有可以相加的数
  107.                     for k in range(j+1,4):
  108.                         if self.list2048[i][k] == 0:  # 如果该索引值是0,直接进行下一循环。
  109.                             continue
  110.                         elif self.list2048[i][j] == self.list2048[i][k]:  # 如果两个值相同就相加
  111.                             self.list2048[i][j] += self.list2048[i][k]  # 数值相加,也可以写成 self.list2048[i][j] *= 2
  112.                             self.score += self.list2048[i][j]  # 更改得分数
  113.                             self.list2048[i][k] = 0
  114.                         break
  115.                 for j in range(4):  # 向左移动
  116.                     if self.list2048[i][j] != 0:
  117.                         self.list2048[i][temp],self.list2048[i][j] = self.list2048[i][j],self.list2048[i][temp]
  118.                         temp += 1
  119.             self.array_rotate(self.keyRotate[event.keysym][1]) # 旋转复原数组
  120.             self.add_number() # 如果按了方向键,就调用生成新数的函数

  121. start = game()
  122. start.main()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-25 20:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表