Python 流程控制实战:打造文字版数独小游戏(新手友好)

Python 流程控制实战:打造文字版数独小游戏(新手友好)

数独是经典的逻辑推理游戏,核心规则简单却充满挑战 ------ 在 9x9 网格中填充数字 1-9,确保每行、每列和每个 3x3 子网格内数字不重复。对于编程新手来说,先通过文字版实现数独游戏,能重点练习流程控制(循环、条件判断)和逻辑推理,后续再拓展图形界面更易上手。本文将带大家从零开发一款交互流畅的文字版数独,无需复杂库,仅用 Python 基础语法就能完成。

一、开发准备

1.1 环境要求

  • Python 3.6+(无需额外第三方库,纯基础语法实现)
  • 任意代码编辑器(如 VS Code、PyCharm)

1.2 核心目标

  1. 自动生成带空白的数独谜题(支持简单 / 中等 / 困难难度)
  2. 支持用户输入数字填充空白,实时校验合法性
  3. 提供游戏重置、查看答案、退出功能
  4. 完成后自动判断胜负,给出反馈

二、核心逻辑设计

数独游戏的核心的是 "谜题生成" 和 "合法性校验",再结合流程控制实现交互逻辑,整体结构清晰易懂:

模块 功能描述 核心语法依赖
谜题生成模块 生成完整数独矩阵,随机挖空形成谜题 嵌套循环、递归、随机数
合法性校验模块 校验用户输入的数字是否符合数独规则 多条件判断、列表遍历
交互模块 显示游戏界面、接收用户操作、判断游戏结果 while 循环、输入输出处理

三、完整代码实现(含详细注释)

python

运行

python 复制代码
import random

# -------------------------- 1. 核心工具函数 --------------------------
def check_valid(matrix, row, col, num):
    """校验数字num能否放在matrix[row][col]位置,符合数独规则返回True"""
    # 规则1:当前行无重复数字
    if num in matrix[row]:
        return False
    # 规则2:当前列无重复数字
    for i in range(9):
        if matrix[i][col] == num:
            return False
    # 规则3:3x3子网格无重复数字
    group_row = (row // 3) * 3  # 子网格起始行(0/3/6)
    group_col = (col // 3) * 3  # 子网格起始列(0/3/6)
    for i in range(group_row, group_row + 3):
        for j in range(group_col, group_col + 3):
            if matrix[i][j] == num:
                return False
    return True

def generate_full_sudoku():
    """生成完整的合法数独矩阵(递归实现)"""
    matrix = [[0 for _ in range(9)] for _ in range(9)]  # 初始化9x9空矩阵
    
    def fill_cell(row, col):
        # 递归终止条件:所有单元格填充完成(行号≥9)
        if row == 9:
            return True
        # 计算下一个单元格位置(列满则换行)
        next_row = row if col < 8 else row + 1
        next_col = col + 1 if col < 8 else 0
        
        # 随机打乱1-9,生成不同谜题
        nums = random.sample(range(1, 10), 9)
        for num in nums:
            if check_valid(matrix, row, col, num):
                matrix[row][col] = num
                # 递归填充下一个单元格,成功则返回True
                if fill_cell(next_row, next_col):
                    return True
                # 回溯:当前数字填充失败,恢复为0
                matrix[row][col] = 0
        return False
    
    fill_cell(0, 0)
    return matrix

def generate_puzzle(difficulty="easy"):
    """生成带空白的数独谜题,难度控制挖空数量"""
    full_matrix = generate_full_sudoku()
    puzzle_matrix = [row.copy() for row in full_matrix]
    
    # 按难度设置挖空数量(0表示空白)
    difficulty_level = {
        "easy": 30,    # 简单:30个空白
        "medium": 45,  # 中等:45个空白
        "hard": 60     # 困难:60个空白
    }
    blank_count = difficulty_level.get(difficulty, 30)
    
    # 随机挖空(避免重复挖同一位置)
    blank_positions = set()
    while len(blank_positions) < blank_count:
        row = random.randint(0, 8)
        col = random.randint(0, 8)
        blank_positions.add((row, col))
    
    for row, col in blank_positions:
        puzzle_matrix[row][col] = 0
    return puzzle_matrix, full_matrix

def print_sudoku(matrix):
    """美化打印数独矩阵,方便用户查看"""
    print("=" * 31)
    for i in range(9):
        # 每3行打印一条分隔线
        if i % 3 == 0 and i != 0:
            print("-" * 31)
        line = "| "
        for j in range(9):
            # 每3列打印一条竖线
            if j % 3 == 0 and j != 0:
                line += "| "
            # 空白位置显示为" ",已填充数字显示对应值
            val = matrix[i][j] if matrix[i][j] != 0 else " "
            line += f"{val} "
        line += "|"
        print(line)
    print("=" * 31)

def is_complete(matrix):
    """判断数独是否填充完成(无空白单元格)"""
    for row in matrix:
        if 0 in row:
            return False
    return True

# -------------------------- 2. 游戏主逻辑 --------------------------
def sudoku_game():
    print("🎮 欢迎来到文字版数独小游戏!")
    print("规则:在9x9网格中填充1-9,每行、每列、每个3x3子网格数字不重复")
    print("难度选择:easy(简单)、medium(中等)、hard(困难)")
    
    # 1. 选择难度
    while True:
        difficulty = input("\n请输入难度(默认easy):").lower()
        if difficulty in ["easy", "medium", "hard", ""]:
            difficulty = difficulty if difficulty else "easy"
            break
        print("❌ 难度输入错误,请输入easy/medium/hard")
    
    # 2. 生成谜题和答案
    puzzle, answer = generate_puzzle(difficulty)
    current = [row.copy() for row in puzzle]  # 存储用户当前填充进度
    print(f"\n✅ 已生成{difficulty}难度数独,空白位置请填充1-9")
    
    # 3. 游戏主循环
    while True:
        print("\n当前数独进度:")
        print_sudoku(current)
        
        # 4. 显示功能菜单
        print("\n功能菜单:")
        print("1. 填充数字  2. 重置游戏  3. 查看答案  4. 退出游戏")
        choice = input("请选择功能(1-4):")
        
        # 5. 功能分支处理
        if choice == "1":
            # 填充数字:接收用户输入的行、列、数字
            try:
                # 行和列从1开始(符合用户习惯),转换为程序中的0开始索引
                row = int(input("请输入要填充的行(1-9):")) - 1
                col = int(input("请输入要填充的列(1-9):")) - 1
                num = int(input("请输入要填充的数字(1-9):"))
                
                # 校验输入范围
                if not (0 <= row < 9 and 0 <= col < 9 and 1 <= num <= 9):
                    print("❌ 输入无效!行/列必须是1-9,数字必须是1-9")
                    continue
                
                # 校验该位置是否为空白(不能修改初始数字)
                if puzzle[row][col] != 0:
                    print("❌ 该位置是初始数字,不能修改!")
                    continue
                
                # 校验数字是否符合规则
                if check_valid(current, row, col, num):
                    current[row][col] = num
                    print("✅ 填充成功!")
                    
                    # 检查游戏是否完成
                    if is_complete(current):
                        print("\n🎉 恭喜你!数独填充完成且全部正确!")
                        print("最终答案:")
                        print_sudoku(answer)
                        break
                else:
                    print("❌ 该数字不符合数独规则(行/列/子网格有重复),请重新选择!")
            except ValueError:
                print("❌ 输入错误!请输入有效的数字!")
        
        elif choice == "2":
            # 重置游戏:恢复到初始谜题状态
            current = [row.copy() for row in puzzle]
            print("🔄 游戏已重置!")
        
        elif choice == "3":
            # 查看答案
            print("\n📖 数独答案:")
            print_sudoku(answer)
        
        elif choice == "4":
            # 退出游戏
            print("👋 感谢游玩,下次再见!")
            break
        
        else:
            print("❌ 功能选择错误,请输入1-4!")

# 启动游戏
if __name__ == "__main__":
    sudoku_game()

四、游戏玩法说明

1. 启动游戏

运行代码后,首先选择难度(输入easy/medium/hard,直接回车默认简单难度),程序会自动生成对应的数独谜题。

2. 核心操作

  • 填充数字:选择功能 1,输入要填充的 "行、列、数字"(例如 "3 5 7" 表示在第 3 行第 5 列填充 7)。
  • 重置游戏:选择功能 2,恢复到初始谜题状态,重新开始。
  • 查看答案:卡壳时选择功能 3,查看完整正确答案。
  • 退出游戏:选择功能 4,结束游戏。

3. 示例运行效果

plaintext

python 复制代码
🎮 欢迎来到文字版数独小游戏!
规则:在9x9网格中填充1-9,每行、每列、每个3x3子网格数字不重复
难度选择:easy(简单)、medium(中等)、hard(困难)

请输入难度(默认easy):

✅ 已生成easy难度数独,空白位置请填充1-9

当前数独进度:
===============================
| 5 3   | 6     | 9 8   |
| 6     | 3 4   |     1 |
| 1 9 8 |       | 5     |
-------------------------------
| 8     |     6 |     3 |
| 4     | 8 1 3 |     5 |
| 7     |     2 |     6 |
-------------------------------
|       | 6     | 2 8   |
| 2     |     9 |     4 |
|       | 4 1   | 7     |
===============================

功能菜单:
1. 填充数字  2. 重置游戏  3. 查看答案  4. 退出游戏
请选择功能(1-4):1
请输入要填充的行(1-9):1
请输入要填充的列(1-9):3
请输入要填充的数字(1-9):4
✅ 填充成功!

五、核心流程控制亮点(新手重点学习)

  1. 递归与循环结合:用递归实现数独矩阵生成,while 循环控制游戏主流程,嵌套 for 循环处理网格遍历,覆盖多种循环场景。
  2. 多条件判断 :校验数字合法性时,通过三层条件判断(行、列、子网格)实现规则校验,强化if-else逻辑应用。
  3. 分支功能设计 :用if-elif-else实现多功能菜单,每个功能对应独立逻辑,结构清晰,便于维护。
  4. 异常处理 :通过try-except捕获用户输入非数字的错误,提升游戏稳定性,体现 "容错性" 编程思维。

六、拓展优化方向(新手进阶练习)

  1. 增加计时功能:记录游戏开始到完成的时间,挑战最快解题速度。
  2. 添加错误次数限制:设置最大错误填充次数,超过则游戏失败,增加挑战性。
  3. 支持自定义挖空数:让用户自主设置空白单元格数量,灵活调整难度。
  4. 图形界面升级:学习 Pygame 库,将文字版改为可视化界面,添加鼠标点击填充、颜色区分等功能(参考原文图形化思路)。

这款文字版数独游戏完全基于 Python 基础语法开发,重点锻炼流程控制和逻辑推理能力。新手可以先理解核心函数的逻辑(尤其是数独生成和合法性校验),再尝试自己修改代码实现拓展功能,逐步提升编程实战能力。

相关推荐
liebe1*17 小时前
第八章 防火墙高可靠性技术
运维·服务器·网络
DN金猿7 小时前
jenkins 权限控制(用户只能看指定的项目)
linux·运维·服务器·jenkins
長安一片月7 小时前
操作系统之进程和线程
linux·运维·服务器
JIngJaneIL7 小时前
基于Java+ vueOA工程项目管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
测试人社区-小明7 小时前
从前端体验到后端架构:Airbnb全栈SDET面试深度解析
前端·网络·人工智能·面试·职场和发展·架构·自动化
李少兄7 小时前
前端开发中的 transform、translate 与 transition
前端·css
蓝鲸屿7 小时前
JS基础第九天——对象(2)+Random
开发语言·前端·javascript
全栈练习生7 小时前
ESModule的工作原理是什么
前端
眠晚晚7 小时前
src挖洞笔记分享_上
服务器·网络·笔记