Python实现数字华容道:支持3/4/5阶及完整源码解析

叶初
叶初
发布时间:2026-10-14| 4人浏览过
原创

本文详细介绍使用Python和tkinter模块开发数字华容道游戏的全过程。程序支持3阶、4阶及5阶关卡选择,通过随机数模块生成初始状态,利用按钮点击事件实现数字与空白格的交换逻辑。文章包含完整代码、运行结果截图及核心算法解析,涵盖步数统计、胜利判定及界面布局,适合Python初学者参考学习。

Python数字华容道项目概述

本文分享一个使用Python编写的数字华容道游戏项目,支持用户自定义选择关卡难度,供广大开发者参考交流。

为满足特定比赛需求,本项目实现了包含3阶、4阶及5阶三种难度的数字华容道。游戏启动时,用户在命令行窗口中选择关卡等级,程序调用random模块生成随机初始状态,并使用tkinter模块构建图形化用户界面。

完整源代码展示

以下是该程序的完整源代码。


# coding:utf-8 #

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

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

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

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

if difficulty == 3:
    root.attributes("-topmost", True)
    row_of_space = 0    #存放空白按钮的行号 
    col_of_space = 0    #存放空白按钮的列号
    buttons = {}      #存放数字按钮的数组
    numbers = ['1','2','3','4','5','6','7','8',' '] #所有数字文本的列表 
    shuffle(numbers)     #打乱数字列表中的数字顺序
    """制造数字华容道方阵"""
    for row in range(3): 
        for col in range(3):
            """创建数字按钮,并将行列号传入该按钮的点击事件函数"""
            button = Button(root,command = lambda x = row,y = col:Button_Click_1(x,y),bg = 'black',fg = 'green',font = ("Arial",35))
            buttons[row,col] = button   #将按钮导入数组
            button['text'] = numbers.pop()    #设置按钮上的文本
            button.place(x = 60 + col * 60,y = 60 + row * 60,width = 50,height = 50)    #设置数字按钮大小
            if button['text'] == ' ':        #判断是否为空白按钮,如果是,则记录到空白按钮行列号变量
                row_of_space = row
                col_of_space = col
    numbers = ['1','2','3','4','5','6','7','8',' ']   #还原数字列表 
    root.mainloop() #显示窗口
elif difficulty == 4:
    root.attributes("-topmost", True)
    row_of_space = 0    #存放空白按钮的行号 
    col_of_space = 0    #存放空白按钮的列号
    buttons = {}      #存放数字按钮的数组
    numbers = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15',' '] #所有数字文本的列表 
    shuffle(numbers)     #打乱数字列表中的数字顺序
    """制造数字华容道方阵"""
    for row in range(4): 
        for col in range(4):
            """创建数字按钮,并将行列号传入该按钮的点击事件函数"""
            button = Button(root,command = lambda x = row,y = col:Button_Click_2(x,y),bg = 'black',fg = 'green',font = ("Arial",35))
            buttons[row,col] = button   #将按钮导入数组
            button['text'] = numbers.pop()    #设置按钮上的文本
            button.place(x = 60 + col * 60,y = 60 + row * 60,width = 50,height = 50)    #设置数字按钮大小
            if button['text'] == ' ':        #判断是否为空白按钮,如果是,则记录到空白按钮行列号变量
                row_of_space = row
                col_of_space = col
    numbers = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15',' ']   #还原数字列表 
    root.mainloop() #显示窗口
elif difficulty == 5:
    root.attributes("-topmost", True)
    row_of_space = 0    #存放空白按钮的行号 
    col_of_space = 0    #存放空白按钮的列号
    buttons = {}      #存放数字按钮的数组
    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',' '] #所有数字文本的列表 
    shuffle(numbers)     #打乱数字列表中的数字顺序
    for row in range(5): 
        for col in range(5):
            """创建数字按钮,并将行列号传入该按钮的点击事件函数"""
            button = Button(root,command = lambda x = row,y = col:Button_Click_3(x,y),bg = 'black',fg = 'green',font = ("Arial",35))
            buttons[row,col] = button   #将按钮导入数组
            button['text'] = numbers.pop()    #设置按钮上的文本
            button.place(x = 60 + col * 60,y = 60 + row * 60,width = 50,height = 50)    #设置数字按钮大小
            if button['text'] == ' ':        #判断是否为空白按钮,如果是,则记录到空白按钮行列号变量
                row_of_space = row
                col_of_space = col
    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',' ']   #还原数字列表 
    root.mainloop() #显示窗口
else:
    print('未完成此类关卡')

程序运行效果展示

以下是程序运行后的界面截图。

展示三阶数字华容道的游戏界面及胜利状态。

展示四阶数字华容道的游戏界面及胜利状态。

五阶数字华容道的实现逻辑与上述版本一致,此处不再赘述。

核心代码原理与逻辑解析

接下来对程序的核心代码原理进行详细解析。

首先分析以下关键代码片段。


def Button_Click_1(x,y):      #按钮点击事件函数
        """声明空白按钮行列号和步数的变量为全局变量"""
        global row_of_space  
        global col_of_space    
        global step_number
        """判断判断点击按钮旁是否为空白按钮,是则交换位置"""
        if abs(x-row_of_space) + abs(y-col_of_space) == 1:  
            step_number += 1    #将步数赋值
            label_step_number['text'] = '步数:' + str(step_number)  #将步数变量导入label控件
            """交换按钮位置"""
            buttons[row_of_space,col_of_space]['text'] = buttons[x,y]['text']
            buttons[x,y]['text']  = ' '  
            row_of_space = x            
            col_of_space = y
            n = 0   
            for row in range(3):
                for col in range(3):
                    """对比所有按钮序列是否正确,不正确则跳出函数"""
                    if buttons[row,col]['text'] != numbers[n]:  
                        return
                    n += 1
            """所有按钮判断完毕赢得游戏胜利"""
            label_welcomes['text'] = '你赢了'

该部分定义了三个按钮的点击事件处理函数,主要区别在于range循环中的数值不同,以适配不同阶数的棋盘。函数内部首先判断被点击按钮是否与空白按钮相邻(即曼哈顿距离为1),若相邻则交换两者位置。随后,通过嵌套循环遍历所有按钮,对比当前序列与目标矩阵是否完全一致:若不一致则跳出循环继续游戏,若完全对应则判定玩家获胜。


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

该部分负责创建图形化用户界面,每行代码的具体功能已在代码注释中详细说明。

受限于开发时间,目前仅实现了在命令行窗口输入数字来选择关卡等级的版本。其余功能如按钮创建、函数调用及循环逻辑均较为简单,代码中已添加大致注释,具备tkinter基础的用户应能轻松理解。如有疑问,欢迎交流探讨。

以上就是本文的全部内容,希望对各位的学习有所帮助,也欢迎大家继续支持本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。