小白教程

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

小白教程:制作Python数字华容道(可选择关卡)

[复制链接]

176

主题

185

帖子

663

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
663
发表于 2021-4-9 12:40:24 | 显示全部楼层 |阅读模式
  1. # coding:utf-8 #

  2. """
  3. #============================================================
  4. 作者:@Qss
  5. 2021年3月20日起草
  6. 2021年3月21日完工
  7. 2021年3月23日一次优化完成
  8. 2021年3月31日完成二次优化(关卡设计)
  9. 二次优化待解决漏洞:设计关卡后窗口不能自动显示,需手动切换
  10. 2021年4月1日三次优化完成,成功解决二次优化bug
  11. #============================================================
  12. """
  13. from random import *    #导入随机数模块
  14. from tkinter import *   #导入图形化用户界面模块
  15. step_number = 0     #设置步数的变量,初始值为0
  16. difficulty = int(input('请输入数字华容道列数(3/4/5):'))
  17. def Button_Click_1(x,y):      #按钮点击事件函数
  18.         """声明空白按钮行列号和步数的变量为全局变量"""
  19.         global row_of_space  
  20.         global col_of_space   
  21.         global step_number
  22.         """判断判断点击按钮旁是否为空白按钮,是则交换位置"""
  23.         if abs(x-row_of_space) + abs(y-col_of_space) == 1:  
  24.             step_number += 1    #将步数赋值
  25.             label_step_number['text'] = '步数:' + str(step_number)  #将步数变量导入label控件
  26.             """交换按钮位置"""
  27.             buttons[row_of_space,col_of_space]['text'] = buttons[x,y]['text']
  28.             buttons[x,y]['text']  = ' '  
  29.             row_of_space = x            
  30.             col_of_space = y
  31.             n = 0   
  32.             for row in range(3):
  33.                 for col in range(3):
  34.                     """对比所有按钮序列是否正确,不正确则跳出函数"""
  35.                     if buttons[row,col]['text'] != numbers[n]:  
  36.                         return
  37.                     n += 1
  38.             """所有按钮判断完毕赢得游戏胜利"""
  39.             label_welcomes['text'] = '你赢了'

  40. def Button_Click_2(x,y):      #按钮点击事件函数
  41.         """声明空白按钮行列号和步数的变量为全局变量"""
  42.         global row_of_space  
  43.         global col_of_space   
  44.         global step_number
  45.         """判断判断点击按钮旁是否为空白按钮,是则交换位置"""
  46.         if abs(x-row_of_space) + abs(y-col_of_space) == 1:  
  47.             step_number += 1    #将步数赋值
  48.             label_step_number['text'] = '步数:' + str(step_number)  #将步数变量导入label控件
  49.             """交换按钮位置"""
  50.             buttons[row_of_space,col_of_space]['text'] = buttons[x,y]['text']
  51.             buttons[x,y]['text']  = ' '  
  52.             row_of_space = x            
  53.             col_of_space = y
  54.             n = 0   
  55.             for row in range(4):
  56.                 for col in range(4):
  57.                     """对比所有按钮序列是否正确,不正确则跳出函数"""
  58.                     if buttons[row,col]['text'] != numbers[n]:  
  59.                         return
  60.                     n += 1
  61.             """所有按钮判断完毕赢得游戏胜利"""
  62.             label_welcomes['text'] = '你赢了'

  63. def Button_Click_3(x,y):      #按钮点击事件函数
  64.         """声明空白按钮行列号和步数的变量为全局变量"""
  65.         global row_of_space  
  66.         global col_of_space   
  67.         global step_number
  68.         """判断判断点击按钮旁是否为空白按钮,是则交换位置"""
  69.         if abs(x-row_of_space) + abs(y-col_of_space) == 1:  
  70.             step_number += 1    #将步数赋值
  71.             label_step_number['text'] = '步数:' + str(step_number)  #将步数变量导入label控件
  72.             """交换按钮位置"""
  73.             buttons[row_of_space,col_of_space]['text'] = buttons[x,y]['text']
  74.             buttons[x,y]['text']  = ' '  
  75.             row_of_space = x            
  76.             col_of_space = y
  77.             n = 0   
  78.             for row in range(5):
  79.                 for col in range(5):
  80.                     """对比所有按钮序列是否正确,不正确则跳出函数"""
  81.                     if buttons[row,col]['text'] != numbers[n]:  
  82.                         return
  83.                     n += 1
  84.             """所有按钮判断完毕赢得游戏胜利"""
  85.             label_welcomes['text'] = '你赢了'

  86. """创建华容道游戏窗口"""
  87. root = Tk()                      #创建图形化用户界面实例
  88. root.title('数字华容道')         #设置窗口标题
  89. root.geometry("400x400")    #将窗口大小设为高400宽400
  90. root.configure(bg = 'black') #将窗口背景设为黑色
  91. root.resizable(width = False,height = False)    #设置窗口为不可拉伸
  92. """设置欢迎语的label控件"""
  93. label_welcomes = Label(root,text = '欢迎来到数字华容道',bg = 'black',fg = 'red',font = ("Arial",13))    #设置label控件的属性
  94. label_welcomes.place(x = 20,y = 10,width = 250,height = 40)  #设置label控件位置
  95. """设置显示操作方式的label控件"""
  96. label_operation = Label(root,text = '单击数字',bg = 'black',fg = 'white',font = ("Arial",10))
  97. label_operation.place(x = 3,y = 40,width = 50,height = 30)
  98. label_operation_2 = Label(root,text = '移动方块',bg = 'black',fg = 'white',font = ("Arial",10))
  99. label_operation_2.place(x = 3,y = 60,width = 50,height = 30)
  100. """设置显示步数的label控件"""
  101. label_step_number = Label(root,text = '步数:' + str(step_number),bg = 'black',fg = 'yellow',font = ("Arial",10))
  102. label_step_number.place(x = 3,y = 20,width = 50,height = 30)

  103. if difficulty == 3:
  104.     root.attributes("-topmost", True)
  105.     row_of_space = 0    #存放空白按钮的行号
  106.     col_of_space = 0    #存放空白按钮的列号
  107.     buttons = {}      #存放数字按钮的数组
  108.     numbers = ['1','2','3','4','5','6','7','8',' '] #所有数字文本的列表
  109.     shuffle(numbers)     #打乱数字列表中的数字顺序
  110.     """制造数字华容道方阵"""
  111.     for row in range(3):
  112.         for col in range(3):
  113.             """创建数字按钮,并将行列号传入该按钮的点击事件函数"""
  114.             button = Button(root,command = lambda x = row,y = col:Button_Click_1(x,y),bg = 'black',fg = 'green',font = ("Arial",35))
  115.             buttons[row,col] = button   #将按钮导入数组
  116.             button['text'] = numbers.pop()    #设置按钮上的文本
  117.             button.place(x = 60 + col * 60,y = 60 + row * 60,width = 50,height = 50)    #设置数字按钮大小
  118.             if button['text'] == ' ':        #判断是否为空白按钮,如果是,则记录到空白按钮行列号变量
  119.                 row_of_space = row
  120.                 col_of_space = col
  121.     numbers = ['1','2','3','4','5','6','7','8',' ']   #还原数字列表
  122.     root.mainloop() #显示窗口
  123. elif difficulty == 4:
  124.     root.attributes("-topmost", True)
  125.     row_of_space = 0    #存放空白按钮的行号
  126.     col_of_space = 0    #存放空白按钮的列号
  127.     buttons = {}      #存放数字按钮的数组
  128.     numbers = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15',' '] #所有数字文本的列表
  129.     shuffle(numbers)     #打乱数字列表中的数字顺序
  130.     """制造数字华容道方阵"""
  131.     for row in range(4):
  132.         for col in range(4):
  133.             """创建数字按钮,并将行列号传入该按钮的点击事件函数"""
  134.             button = Button(root,command = lambda x = row,y = col:Button_Click_2(x,y),bg = 'black',fg = 'green',font = ("Arial",35))
  135.             buttons[row,col] = button   #将按钮导入数组
  136.             button['text'] = numbers.pop()    #设置按钮上的文本
  137.             button.place(x = 60 + col * 60,y = 60 + row * 60,width = 50,height = 50)    #设置数字按钮大小
  138.             if button['text'] == ' ':        #判断是否为空白按钮,如果是,则记录到空白按钮行列号变量
  139.                 row_of_space = row
  140.                 col_of_space = col
  141.     numbers = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15',' ']   #还原数字列表
  142.     root.mainloop() #显示窗口
  143. elif difficulty == 5:
  144.     root.attributes("-topmost", True)
  145.     row_of_space = 0    #存放空白按钮的行号
  146.     col_of_space = 0    #存放空白按钮的列号
  147.     buttons = {}      #存放数字按钮的数组
  148.     numbers = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24',' '] #所有数字文本的列表
  149.     shuffle(numbers)     #打乱数字列表中的数字顺序
  150.     for row in range(5):
  151.         for col in range(5):
  152.             """创建数字按钮,并将行列号传入该按钮的点击事件函数"""
  153.             button = Button(root,command = lambda x = row,y = col:Button_Click_3(x,y),bg = 'black',fg = 'green',font = ("Arial",35))
  154.             buttons[row,col] = button   #将按钮导入数组
  155.             button['text'] = numbers.pop()    #设置按钮上的文本
  156.             button.place(x = 60 + col * 60,y = 60 + row * 60,width = 50,height = 50)    #设置数字按钮大小
  157.             if button['text'] == ' ':        #判断是否为空白按钮,如果是,则记录到空白按钮行列号变量
  158.                 row_of_space = row
  159.                 col_of_space = col
  160.     numbers = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24',' ']   #还原数字列表
  161.     root.mainloop() #显示窗口
  162. else:
  163.     print('未完成此类关卡')
复制代码
下面是程序运行结果
三阶华容道加胜利




接下来说一下代码原理
首先看下这一段
  1. def Button_Click_1(x,y):      #按钮点击事件函数
  2.         """声明空白按钮行列号和步数的变量为全局变量"""
  3.         global row_of_space  
  4.         global col_of_space   
  5.         global step_number
  6.         """判断判断点击按钮旁是否为空白按钮,是则交换位置"""
  7.         if abs(x-row_of_space) + abs(y-col_of_space) == 1:  
  8.             step_number += 1    #将步数赋值
  9.             label_step_number['text'] = '步数:' + str(step_number)  #将步数变量导入label控件
  10.             """交换按钮位置"""
  11.             buttons[row_of_space,col_of_space]['text'] = buttons[x,y]['text']
  12.             buttons[x,y]['text']  = ' '  
  13.             row_of_space = x            
  14.             col_of_space = y
  15.             n = 0   
  16.             for row in range(3):
  17.                 for col in range(3):
  18.                     """对比所有按钮序列是否正确,不正确则跳出函数"""
  19.                     if buttons[row,col]['text'] != numbers[n]:  
  20.                         return
  21.                     n += 1
  22.             """所有按钮判断完毕赢得游戏胜利"""
  23.    
复制代码
这段是自定义了三个按钮的点击事件函数,不过三个都差不多,就是range后面的数字换了(应对不同的阶级)。这个函数在注释上已经写明了,是判断点击按钮旁是否有空白按钮的,有则交换位置。后面运用循环嵌套对比序列中的数字和矩阵上的是否一一对应,不对应就跳出循环,对应则判定为赢得游戏。
  1. """创建华容道游戏窗口"""
  2. root = Tk()                      #创建图形化用户界面实例
  3. root.title('数字华容道')         #设置窗口标题
  4. root.geometry("400x400")    #将窗口大小设为高300宽300
  5. root.configure(bg = 'black') #将窗口背景设为黑色
  6. root.resizable(width = False,height = False)    #设置窗口为不可拉伸
  7. """设置欢迎语的label控件"""
  8. label_welcomes = Label(root,text = '欢迎来到数字华容道',bg = 'black',fg = 'red',font = ("Arial",13))    #设置label控件的属性
  9. label_welcomes.place(x = 20,y = 10,width = 250,height = 40)  #设置label控件位置
  10. """设置显示操作方式的label控件"""
  11. label_operation = Label(root,text = '单击数字',bg = 'black',fg = 'white',font = ("Arial",10))
  12. label_operation.place(x = 3,y = 40,width = 50,height = 30)
  13. label_operation_2 = Label(root,text = '移动方块',bg = 'black',fg = 'white',font = ("Arial",10))
  14. label_operation_2.place(x = 3,y = 60,width = 50,height = 30)
  15. """设置显示步数的label控件"""
  16. label_step_number = Label(root,text = '步数:' + str(step_number),bg = 'black',fg = 'yellow',font = ("Arial",10))
  17. label_step_number.place(x = 3,y = 20,width = 50,height = 30)
复制代码
这一段创建了图形化用户界面,具体每行代码做什么用的注释上我都标清楚了。

接着说一下,由于时间有限,只做了在壳窗口内选择几阶级数字华容道的版本。是用输入数字来判定的。其他的都是些简单玩意,比如说按钮创建,调用函数和循环嵌套,代码的注释上都写了一些大概意思,有点tkinter基础的应该都能看懂


本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|小白教程 ( 粤ICP备20019910号 )

GMT+8, 2024-9-20 14:46 , Processed in 0.179395 second(s), 24 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

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