ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用猜数字游戏入门Python:从基础语法到项目实战

用猜数字游戏入门Python:从基础语法到项目实战 很多人在学 Python 的时候真正的问题不是“看不懂语法”而是学完print()、if、for、while之后突然发现自己不知道该做什么了。装了 Python、配好了 VSCode、看了一堆入门教程结果打开命令行还是只能写两行“Hello World”。这种落差会在一两周内慢慢消磨掉兴趣最后得出一个错误的结论Python 不适合我。但事实不是这样。你缺的不是语法缺的是一个能在几分钟内给你正反馈的小项目。真正让我对 Python 兴趣拉满的不是某个复杂的爬虫也不是动辄几百行的数据分析代码而是“猜数字”这样一个小游戏。它只用到了input、while、if、random这几个最基础的知识点却完整地走了一遍“设计—写代码—运行—看报错—改代码—跑通”的流程。这个过程带来的成就感比看十篇教程都值钱。所以这篇文章不打算给你讲一堆大而全的概念而是带着你把一个能玩的游戏从零写出来再一步步扩展成具备多轮、计分、文件存档甚至打包成 exe 的版本。读完这篇文章你会得到两个版本的可运行源码、一遍完整的调试路径、一份常见报错对照表以及往图形界面和打包方向继续深入的实践建议。你可以把它当作一篇 Python 入门游戏实战来读也可以当作一个“检验自己到底会不会写 Python”的标准答案收藏备用。1. 这篇文章真正要解决的问题1.1 Python 新手最常见的学习障碍先说一个很现实的现象很多人在学习 Python 的第一个月就会放弃不是因为教程太难而是因为“不知道学来干嘛”。看完变量和数据类型写几个赋值语句没感觉。看完循环用for打印几个数字还是没感觉。等学完函数和模块觉得好像懂了不少但一旦关掉教程动手写一个独立的小程序时大脑一片空白。问题出在哪里出在“输入”和“输出”不成比例——你一直在被动地接收知识点却很少主动解决一个具体问题。做项目是打破这种状态最直接的方式。但这里又有一个误区很多人一上来就想做爬虫、做网站、做量化交易。这些项目不是不好而是它们隐性地依赖很多前置知识。比如爬虫涉及 HTTP 协议、HTML 结构、反爬机制一个初学者还没体会到 Python 的乐趣就先被异常处理和各种规则搞崩溃了。1.2 为什么“游戏”是最合适的入门载体游戏类项目在入门阶段有一个不可替代的优势反馈速度极快。你写一个猜数字程序从写完到运行只需要几秒程序会立刻告诉你数字大了还是小了。这种即时反馈会在你的大脑里形成一个清晰的正循环我改了一行代码程序就变了一个行为我就能立刻意识到这套逻辑是成立的。这种感觉很容易让人上头也是很多人口中“对 Python 兴趣暴涨”的真正原因。从知识密度来看一个猜数字小游戏至少覆盖了 Python 中这些核心基础变量与数据类型input()与print()输入输出类型转换while循环与if条件分支random模块的使用函数封装文件读写几乎每一个 Python 入门教程里反复强调的知识点都能在几十行代码里被串起来。学语法时它们是零散的做游戏时它们变成了一张网。1.3 什么样的读者最应该读这篇文章如果你符合下面任意一条这篇文章就是为你准备的Python 零基础刚看完变量、循环、条件判断但不知道下一步学什么。学过 Python 基础语法但一直没有独立完成过一个能运行的项目。想找一个适合写进简历或作业里的入门练手项目但不想一上来就啃复杂的框架。想带朋友或同事入门编程需要一套简单又不失完整性的示例项目。如果你已经能熟练用 Python 做数据分析或后端开发那这篇文章里的游戏对你来说会显得非常简单你可以直接跳到第 8 章看工程化和打包建议。1.4 读完这篇文章你能获得什么在动手之前先明确一下目标。读完这篇文章你应该能独立完成以下几件事在命令行中用 Python 运行一个可交互的猜数字游戏。理解游戏背后每一行代码的作用而不只是复制粘贴。遇到输入非数字、循环退不出、类型报错等问题时能自己定位和修复。把代码改造成多轮游戏并把历史最好成绩保存到本地文件。知道如何把 Python 脚本打包成 exe分享给别人运行。带着这个清单往下读你会发现每一步都对应着一小段代码和一个可验证的结果。2. 基础概念游戏背后只有四个核心知识点很多人一听到“写游戏”就觉得很难其实是把“游戏”和“图形画面”绑定在一起了。对于入门来说控制台里跑起来的回合制文字游戏完全够用。拆开来看一个猜数字游戏只有四个核心知识点。2.1 input() 与 print()与程序对话print()负责把信息输出到屏幕input()负责从用户那里读取输入。这两个函数是控制台游戏的门面和入口。name input(请输入你的名字) print(你好, name)这里最容易犯的错是使用者在输入行按下回车后input()返回的一定是一个字符串哪怕输入的是数字50它的类型也是str而不是int。这一点非常重要因为游戏里马上要做数字大小的比较而字符串和数字是不能直接比较的。解决办法是用int()做类型转换。2.2 类型转换字符串与数字的边界Python 是一个强类型语言虽然它不要求你显式声明变量类型但不同类型之间做运算时会受到严格限制。number input(请输入数字) print(number 1) # 报错TypeError: can only concatenate str (not int) to str正确写法是number int(input(请输入数字)) print(number 1)input()返回字符串int()把它变成整数之后才能参与数学运算和大小比较。这个“字符串转整数”的动作是控制台游戏里最常见的类型转换也几乎是所有新手接触的第一个类型转换场景。2.3 while 循环与 if 条件分支游戏需要让玩家反复猜测直到猜中为止这就要用到while循环。而“猜大了”还是“猜小了”的判断则需要if和elif条件分支。guess 0 while guess ! 50: guess int(input(请输入猜测)) if guess 50: print(大了) elif guess 50: print(小了) print(猜对了)这里的循环条件是guess ! 50只要玩家没猜中就会一直循环。每一次循环都会读取新的输入重新执行判断。理解这段逻辑后你就已经掌握了while和if的配合方式循环负责“重复做”条件负责“每轮怎么选择”。2.4 random 模块让程序有随机性没有随机性的游戏玩一次就腻了。Python 标准库里的random模块可以生成随机整数import random target random.randint(1, 100)random.randint(1, 100)会返回 1 到 100 之间的一个随机整数包含 1 和 100 本身。这就是程序要玩家猜的目标数字。通过上面四个知识点的组合一个猜数字游戏的骨架就已经出现了程序生成随机数玩家用循环反复输入程序用条件判断来提示大小直到数字被猜中。可以用一张表来总结这四个知识点的作用和常见坑知识点作用常见坑print()向屏幕输出提示信息忘记格式化变量和字符串拼接出问题input()接收用户输入返回值永远是字符串不能直接用于比较int()将字符串转换为整数输入非数字内容时会抛出 ValueErrorwhileif控制游戏循环和逻辑分支循环条件不更新导致死循环random.randint生成指定范围的随机整数参数上下边界使用错误3. 环境准备与前置条件在写代码之前需要先把 Python 运行环境准备好。这里假定你使用的是当前主流的 Python 3如果你还在看 Python 2 时代的教程建议尽快切换。3.1 安装 Python 并验证版本如果你还没有安装 Python去官网下载对应操作系统的安装包即可。在 Windows 上安装时有一个非常关键的勾选项Add Python to PATH。如果安装时漏掉了这一步之后在命令行里执行python命令可能会提示找不到命令。安装完成后打开终端或命令行执行python --version如果看到类似Python 3.10.x、Python 3.11.x、Python 3.12.x的输出说明安装成功。在 Linux 或 macOS 上某些环境下需要使用python3命令python3 --version这里不需要死记版本号。只要你使用的是 3.8 以上的版本运行本文的代码都没有问题。3.2 选择一个合适的 IDE对于这种几十行的入门项目编辑器选择并不复杂。如果你什么工具都不想装Python 自带的IDLE完全够用。打开 IDLE点击 File - New File就能新建一个 Python 文件进行编辑和运行。如果你希望有更好的代码提示和调试体验推荐使用VSCode并在扩展市场安装官方Python扩展。安装完成后用 VSCode 打开项目文件夹在命令面板里选择 Python 解释器就可以直接运行.py文件。对于 VSCode 用户一个经常碰到的问题是明明装了 Python 扩展运行时还是使用的系统默认解释器导致已经安装的第三方库找不到。解决办法是打开一个.py文件后点击右下角的解释器版本手动选择你刚安装的解释器路径。3.3 建立项目目录建议为这个游戏单独建立一个文件夹方便管理以后逐步增加的版本文件。例如在桌面创建一个guess_number文件夹所有.py文件都放在这里。在命令行中操作mkdir guess_number cd guess_number后续所有代码文件都保存在这个目录下运行命令也在这个目录下执行。4. 核心流程拆解猜数字小游戏是怎么设计的很多人拿到编程题的第一反应是直接敲代码但更有效的思路是先把流程画清楚再一步一步翻译成代码。4.1 游戏规则先明确规则程序在 1 到 100 之间随机生成一个整数玩家通过输入数字来猜测。如果猜大了程序提示“大了”如果猜小了程序提示“小了”如果猜中程序输出游戏结束并统计猜的次数。这个规则足够简单但又完整地包含了循环和判断。4.2 流程拆解为四个步骤整个游戏可以拆成四个步骤生成一个 1 到 100 之间的随机整数。进入循环反复让玩家输入一个整数。将输入的整数与随机数比较给出提示。如果相等跳出循环并输出统计结果。翻译成 Python 伪代码大概是这样的生成随机数 target 初始化 guess 为 0count 为 0 while guess ! target: 读取玩家输入并转换为整数 猜测次数加 1 如果 guess target提示“大了” 否则如果 guess target提示“小了” 输出“猜对了”以及猜测次数第 2 步中“读取玩家输入并转换为整数”这里是最容易出问题的位置因为一旦用户输入的不是数字int()会直接抛出异常。这个问题的处理方式在第 5 章的完整代码里会有体现。4.3 三个容易出错的地方根据大多数初学者的反馈这个游戏最容易出错的地方有三个。第一个是没有做类型转换。input()返回字符串直接用guess target进行比较会在 Python 3 中抛出TypeError。解决办法是使用int(input(...))。第二个是循环条件写错导致死循环。比如把while guess ! target写成了while True然后判断结束后又没有用break跳出程序就会一直循环下去。第三个是猜的次数统计不准。很多初始版本会把count 1放在循环外面或者放在判断之后导致计数逻辑混乱。正确的做法是每一次循环都表示玩家进行了一次有效猜测所以计数器应该在循环体内部每次自增一次。这四个步骤和三个易错点基本就是整个游戏的全部内容了。剩下的只是如何把伪代码变成能完整运行的真实代码。5. 完整示例与代码实现下面直接进入代码环节。这里提供三个版本第一个是最简可运行版本适合跑通流程第二个是函数化版本支持多轮游戏第三个是扩展版本会把历史最好成绩保存到本地文件。5.1 第一版最简可运行版本# 文件路径guess_number/game_v1.py import random target random.randint(1, 100) guess 0 count 0 print(我想好了一个 1 到 100 之间的数字你来猜一猜。) while guess ! target: try: guess int(input(请输入你的猜测)) except ValueError: print(输入无效请输入一个整数。) continue count 1 if guess target: print(大了再小一点。) elif guess target: print(小了再大一点。) else: print(f恭喜你猜对了你一共用了 {count} 次。)这段代码的核心逻辑是random.randint(1, 100)生成随机目标数字。while guess ! target保证玩家没猜中时不结束循环。try...except ValueError用来处理用户输入非数字的情况避免程序崩溃。每次有效输入后count 1统计猜测次数。print(f...)使用 f-string 格式化输出计算结果。文件保存后在命令行运行python game_v1.py此时程序会一直等待输入直到玩家猜中为止。5.2 第二版函数化并支持多轮游戏第一版只能玩一局。稍微改造一下把一局游戏封装成一个函数然后循环调用多次就能得到多轮游戏。# 文件路径guess_number/game_v2.py import random def play_one_round(max_num100): target random.randint(1, max_num) count 0 print(f本轮数字范围是 1 到 {max_num}) while True: raw input(请输入你的猜测) try: guess int(raw) except ValueError: print(输入无效请输入整数。) continue count 1 if guess target: print(大了再小一点。) elif guess target: print(小了再大一点。) else: print(f猜对了本轮用了 {count} 次。) return count def main(): total_rounds 3 total_times 0 for i in range(1, total_rounds 1): print(f\n第 {i} 轮) total_times play_one_round() average total_times / total_rounds print(f\n三局平均猜测次数{average:.1f}) if __name__ __main__: main()这一版有几个值得学习的点play_one_round()把一局游戏的逻辑完全收进函数里主程序变得非常清晰。while True搭配函数内部的return count猜测成功时直接结束本轮并返回结果。for i in range(1, total_rounds 1)控制总共玩三轮。if __name__ __main__:这一行保证了文件被直接运行时才执行main()被其他模块导入时不会意外触发游戏。运行方式和第一版一样程序会连续进行三局并输出平均猜测次数。5.3 扩展版文件记录历史最好成绩到这个版本就可以加入文件读写的能力了。思路是游戏结束后把猜的次数和历史最好成绩比较如果打破了纪录就把新纪录写进文件。# 文件路径guess_number/game_v3.py import random import os SCORE_FILE best_score.txt def load_best(): if not os.path.exists(SCORE_FILE): return None with open(SCORE_FILE, r, encodingutf-8) as f: content f.read().strip() return int(content) if content else None def save_best(best): with open(SCORE_FILE, w, encodingutf-8) as f: f.write(str(best)) def play_one_round(max_num100): target random.randint(1, max_num) count 0 print(f本轮数字范围是 1 到 {max_num}) while True: raw input(请输入你的猜测) try: guess int(raw) except ValueError: print(输入无效请输入整数。) continue count 1 if guess target: print(大了再小一点。) elif guess target: print(小了再大一点。) else: print(f猜对了本轮用了 {count} 次。) return count def main(): best load_best() if best is not None: print(f当前历史最好成绩{best} 次) else: print(还没有历史记录这一局将创建记录。) count play_one_round() if best is None or count best: save_best(count) print(f新纪录{count} 次已写入 {SCORE_FILE}) else: print(f本局 {count} 次未打破纪录 {best} 次) if __name__ __main__: main()这个版本引入了两个小设计用os.path.exists()判断存档文件是否存在避免第一次运行时找不到文件而报错。用with open(...) as f语法读取和写入文件它会自动管理文件关闭防止资源泄漏。对于入门阶段的人来说文件读写看起来像一个新世界但实际上核心就两句话读文件用open(..., r)写文件用open(..., w)。真正要注意的是文件路径和编码格式。这里统一使用encodingutf-8可以避免中文字符在 Windows 控制台上出现乱码。5.4 运行与验证方式三个版本的运行方式都一样python game_v1.py python game_v2.py python game_v3.py如果你使用的是 Linux 或 macOS可能需要用python3代替python。运行game_v3.py时第一次运行会看到“还没有历史记录”的提示然后正常进行游戏。游戏结束后目录下会出现一个best_score.txt文件里面保存着一个数字。第二次再运行程序就会读取并展示这个数字。6. 运行结果与效果验证写完代码之后验证是必备环节。真正优秀的代码习惯不是“写完就行了”而是知道“输出长什么样才算成功”。6.1 正常运行的输入输出示例以game_v1.py为例假设程序生成的随机数是 37一次完整的输入输出过程大致如下 python game_v1.py 我想好了一个 1 到 100 之间的数字你来猜一猜。 请输入你的猜测50 大了再小一点。 请输入你的猜测25 小了再大一点。 请输入你的猜测37 恭喜你猜对了你一共用了 3 次。这里的关键判断点是提示“大了”或“小了”与输入内容是否匹配。猜中后程序能否正常退出循环。猜测次数是否为有效猜测次数。6.2 异常输入的表现如果你输入的不是数字比如输入abc程序不会崩溃而是会提示请输入你的猜测abc 输入无效请输入一个整数。这在控制台程序里是必须具备的容错能力。如果没有try...except包裹程序会直接抛出ValueError并终止运行体验会大打折扣。判断这一步正确的方法是分别输入文字、小数、边界值 1 和 100观察程序是否都能正常提示。6.3 如果运行失败第一步看哪里如果程序运行后立刻报错先不要慌。第一步应该看报错信息的第一行它通常会说明错误类型和出错的具体文件行号。最常见的错误是ModuleNotFoundError: No module named xxx说明缺少依赖库。TypeError说明类型不匹配通常是忘了转换input()返回的字符串。SyntaxError说明某个位置的语法写错了比如少写了冒号或括号不匹配。对于这个入门游戏来说所有导入的库都来自 Python 标准库正常情况下不会出现依赖缺失的问题。如果报错优先检查代码是否完整、括号是否闭合、文件是否保存成功。7. 常见问题与排查思路把初学者在这类项目中最容易碰到的问题整理成一张表方便你遇到问题时直接对照排查。问题现象可能原因排查方式解决方案运行时报SyntaxError: invalid syntax代码里少写了冒号或括号字符串引号未闭合查看报错指向的行检查冒号和括号补全冒号、括号或引号比较时报TypeError: not supported between instances of str and int没有对input()的结果做int()转换检查guess变量的类型打印type(guess)改用int(input(...))输入abc后程序直接崩溃缺少对ValueError的处理输入非数字内容复现崩溃场景用try...except ValueError包裹转换代码程序进入死循环无法退出循环条件一直为真或循环体内没有更新条件检查循环条件和break/return的位置在猜中后使用break或return退出第一次运行文件记录功能时报FileNotFoundError存档文件不存在直接尝试读取检查文件是否存在先判断os.path.exists()再读取创建了random.py文件后程序行为异常自定义文件与标准库random模块同名导致 import 冲突查看目录下是否有random.py重命名自定义文件不要叫random.pyWindows 控制台中文乱码文件编码与控制台编码不一致查看文件保存编码统一用 UTF-8 编码保存文件代码中显式指定encoding在 VSCode 中运行时找不到 Python 解释器没有在 VSCode 中选择正确的解释器路径打开命令面板选择 Python: Select Interpreter手动选择已安装的 Python 解释器表格之外的另一个经典问题是网上的教程代码写着print hello这种不带括号的写法。那基本是 Python 2 时代的代码建议直接忽略。现在学习和使用 Python统一以 Python 3 为主。还有一个小技巧当你不确定某个变量的类型时可以在代码里临时加一行print(type(变量名))运行后观察输出。这个调试方法对任何类型相关的问题都很有效。8. 最佳实践与工程建议你可能会说一个 50 行的猜数字游戏也要谈工程化其实越是小项目越适合建立好习惯。因为这些习惯的成本很低但收益会在你写更大项目时成倍放大。8.1 从最小可运行版本开始改不要指望一次性写出包含所有功能的完整版本。更好的路径是先写一个只要能看到“猜对/猜错”反馈的最小版本。确认最小版本能运行后再逐步添加异常处理、多轮游戏、文件存档。这背后的原因是保持程序随时处于可运行状态。一旦新增代码出现问题你能快速定位到是新增部分导致的而不是连基础的输入输出都在报错。这个习惯在后续做任何前后端项目时都非常重要。8.2 用函数拆分逻辑第二版里把一局游戏封装成play_one_round()就是典型的函数化思考。它能带来两个好处主流程的可读性大大提升看main()时能立刻知道程序在做什么。单个函数的职责变清晰测试和维护的成本都降低了。在命名上函数名使用动词短语比如play_one_round、load_best、save_best。变量名用名词或形容词短语比如target、guess、best。这看起来是很基础的要求但对代码的可读性影响非常大。8.3 对用户输入做容错控制台程序面对的用户是不可预测的他们可能输入空格、中文、负数、小数。一个健壮的程序应该对输入做校验而不是把异常直接暴露给用户。在这个游戏里try...except ValueError已经处理了大部分非整数输入。如果需要更严格可以再加一个范围校验比如数字必须在 1 到 100 之间超范围时提示重新输入。这部分可以当作你的课后扩展练习。8.4 用版本管理保存每一次迭代如果你打算认真把这个项目写下去强烈建议在创建guess_number目录时就执行git init把每次修改作为一个提交。git init git add game_v1.py git commit -m 完成第一版猜数字游戏这么做的好处是改坏代码时随时可以回退。对于入门项目这也能让你提前习惯团队开发中最基础的协作方式。如果还没有学过 Git这个游戏就是练习 Git 命令最好的试验场反正代码量很小怎么折腾都不会有太大损失。8.5 打包成 exe分享给别人玩当你把第三版写完想让没装 Python 的朋友也能运行。这时候可以使用 PyInstaller 打包pip install pyinstaller pyinstaller --onefile game_v3.py打包完成后在dist目录下会生成一个可执行文件。在 Windows 上就是.exe文件朋友双击就能运行。这里有几个注意事项PyInstaller 只能在当前操作系统上打包当前平台的程序。在 Windows 上打的 exe只能在 Windows 上运行。打包出来的文件体积可能比代码本身大得多这是正常现象因为它把 Python 运行时和依赖库一起打包进去了。如果你的项目依赖外部文件比如游戏需要读取best_score.txt打包后需要注意文件路径问题。坦白说这个游戏已经足够经典网上各种版本都有但只有自己敲一遍才能体会从零到跑通的完整过程。8.6 安全边界不要盲跑陌生源码每次提到下载和运行 Python 代码我都会加一句安全提醒不要直接运行从网上下载的未知源码。Python 脚本的能力非常强可以读写文件、发起网络请求、甚至执行系统命令。如果你从某个地方复制了一段代码至少先通读一遍确认它做的事情和描述一致再在隔离环境里运行。对于学习来说自己动手敲代码比复制粘贴更能积累经验。如果确实需要复现代码也尽量理解每段代码的作用而不是运行完就结束。9. 总结与后续学习方向到这里你已经从零实现了一个可以交互、可以多轮、可以保存历史成绩、还可以打包成 exe 的 Python 小游戏。回顾整个过程你其实已经用到了变量、类型转换、循环、条件判断、函数、异常处理、文件读写这些 Python 入门阶段最核心的知识点。下一步如果你想继续往游戏方向深入有三个很自然的扩展方向。第一个方向是图形界面化。可以用 Python 自带的tkinter库把猜数字游戏从控制台搬到窗口里加入输入框、按钮和消息提示。这样游戏就有了真正的“界面”体验会完全不一样。第二个方向是玩一玩turtle库。如果你觉得控制台游戏不够直观可以用turtle画出简单图案。比如下面这个经典的爱心图形代码量很小运行起来却很直观# 文件路径bonus/heart.py import turtle t turtle.Turtle() t.speed(3) t.color(red) t.begin_fill() t.left(50) t.forward(133) t.circle(50, 200) t.right(140) t.circle(50, 200) t.forward(133) t.end_fill() t.hideturtle() turtle.done()这个例子适合用来理解“用代码控制绘图”的基本思路。运行后可以看到一个红色的爱心被逐步画出来过程很有画面感很适合拿来重建对编程的兴趣。第三个方向是使用pygame做更复杂的游戏。比如贪吃蛇、俄罗斯方块这些项目对游戏循环、事件处理、碰撞检测的要求明显更高但可以作为你掌握 Python 基础后的下一个里程碑。最后提醒一句入门阶段最容易犯的错是不断“看教程”而不是“动手写”。猜数字这个项目虽然简单但如果你能不看答案自己从头默写一遍并且能解释每一行代码的作用说明你的 Python 基础已经比大多数半途而废的人扎实了。建议把本文收藏备用遇到相关问题时回来对照排查。如果你把这个游戏继续扩展成了什么有意思的版本也欢迎在评论区分享你的玩法。
返回列表