ihfvgggidt 发表于 2020-8-18 14:27:52

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

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

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

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

import random,tkinter,tkinter.messagebox,copy
class game():
    score = 0                           # 分数
    list2048 = [*4 for i in range(4)]# 主数组4*4,存储色块的值,0在页面中显示空
    allLabel = [*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':   ,   # 根据按键进行数组旋转。为减少代码量,根据按键旋转数组,统一
               'Down': ,   # 进行向左移动,然后将数组转回,字典键值对的第1个值是将数组转
               'Left': ,   # 至向左移动需要转的次数,第2个是还原回原样需要转动的次数。数
               'Right':}   # 组转动一圈需要顺时针转动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 = tkinter.Label(window,width=6,heigh=3,font=("黑体",30,"bold"),bg=allColor])
            allLabel.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 = [( * 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 == 0:# 判断为0时(色块空值)
                  randomList.append()# 将索引写入randomList数组中
      if len(randomList) > 0:# 大于0表示主数组list2048还有空间
            i = random.sample(randomList,1)# 在0值的索引中随机取出一个索引
            # 因上一步取出的随机数是双层数组,所以这里要用]]
            self.list2048]] = random.choice()# 加入新的值
            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['text'] = '' if self.list2048==0 else self.list2048
                # 大于或等于8192后,前景颜色全部用8192的颜色(#b06ca8)
                self.allLabel['bg'] = "#b06ca8" if self.list2048>=8192 else self.allColor]
                self.scoreLabel['text'] = self.score# 更新分数

    def game_judeg(self):# 判断游戏是否应该结束
      # 两个双层for循环分别判断横向和纵向相邻两个是否有相同的
      for i in range(4):# 横向
            for j in range(3):
                if self.list2048 == self.list2048:
                  return
      for i in range(3):# 纵向
            for j in range(4):
                if self.list2048 == self.list2048:
                  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 = [*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 = self.list2048
                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) # 根据按键转动数组
            for i in range(4):
                temp = 0
                for j in range(4):# 检查是否有可以相加的数
                  for k in range(j+1,4):
                        if self.list2048 == 0:# 如果该索引值是0,直接进行下一循环。
                            continue
                        elif self.list2048 == self.list2048:# 如果两个值相同就相加
                            self.list2048 += self.list2048# 数值相加,也可以写成 self.list2048 *= 2
                            self.score += self.list2048# 更改得分数
                            self.list2048 = 0
                        break
                for j in range(4):# 向左移动
                  if self.list2048 != 0:
                        self.list2048,self.list2048 = self.list2048,self.list2048
                        temp += 1
            self.array_rotate(self.keyRotate) # 旋转复原数组
            self.add_number() # 如果按了方向键,就调用生成新数的函数

start = game()
start.main()
页: [1]
查看完整版本: 新人写的2048游戏,130行,几乎每行都有注释,请各位帮我改进一下