公司动态
Python入门实战:200行代码打造文字游戏“人狗大作战”
很多学 Python 的人都卡在同一个地方语法看懂了练习题也做了但合上教程自己写不出任何有完整逻辑的程序。这通常不是笨而是反馈太长。等你学会列表、字典、函数、文件操作再动手可能已经过去两周热情早被耗光了。但如果第一周就做出一个“能玩”的东西情况会完全不同。今天要拆解的这个项目名字叫「人狗大作战」。它是一个纯文字、单文件、不依赖第三方库的回合制小游戏。运行之后你能在终端里扮演一个遇到恶犬的人选择“攻击、投喂、躲避”等策略来影响剧情走向最后触发不同结局。我的判断是它特别适合作为 Python 入门后的第一个实战项目因为它把input、if/elif/else、while、random、函数拆分这些基础知识的练习全部装进了一个 200 行左右的程序里。你不需要先学完“所有语法”才能做项目游戏本身就是驱动你把语法用起来的最好方式。这篇文章会从游戏设计思路讲起然后逐步搭建骨架最后给出完整可运行源码。读完你可以直接复制、运行、改造也可以把它当作教学案例讲给别人听。1. 为什么一个文字游戏能点燃 Python 兴趣很多初学者对 Python 的印象停留在“数据分析”“人工智能”这些宏大标签上。结果一打开教程先背变量、再学列表练了半天九九乘法表内心真实想法是这东西到底能干什么问题不在于 Python 不够有趣而在于学习路线缺少“正反馈闭环”。什么叫正反馈闭环就是你在电脑前敲下代码运行之后立刻看到一个真实结果。这个结果越接近“你在做的事”你的学习动力就越强。文字游戏恰好站在了这个闭环的最前端。文字游戏有四个天然优势第一它只需要终端不需要图形界面。任何装了 Python 的电脑都能运行跨平台问题几乎不存在。第二它天然是交互式的。程序会反复向你提问你输入不同内容程序给出不同反应。这种“即时反馈”是刷题和背语法给不了的。第三它自带剧情和悬念。玩家关心的是下一步会发生什么而不是“这个循环我到底学没学会”。等你通关之后回头一看才发现循环、判断、随机早就用熟了。第四它容易扩展。文字游戏做出来后你想加道具、加角色、加地图都只是在原有逻辑上做增量。一个项目可以陪你从入门走到进阶。「人狗大作战」这个项目名2023 年前后经常出现在 Python 小游戏练习的相关内容里网上也有各种玩法版本。但我们不纠结某个固定玩法而是自己从零设计一版。因为写游戏最大的乐趣不是照抄别人的代码而是自己定义规则然后看着规则在代码里活过来。2. 游戏设计没有需求分析的开发都是写着玩很多人一上来就写代码写到一半发现逻辑混乱最后只能推倒重来。这其实是开发习惯的问题。写任何程序哪怕是 200 行的小游戏也应该先想清楚三件事玩家能做什么对手能做什么游戏什么时候结束。2.1 核心玩法设计我给「人狗大作战」定的核心规则是玩家遇到一只凶巴巴的小狗每回合双方各选一个行动行动碰撞后产生不同结果。玩家每回合可以从四个行动里选一个攻击强行制服狗狗但自己也可能受伤。投喂用食物试探增加狗狗好感度。躲避稳住局面观察狗狗接下来的反应。查看状态查看当前血量、狗狗血量和好感度。狗狗每回合会随机做出三种反应之一咬主动攻击玩家。吼虚张声势威慑玩家。跑试图拉开距离。不同的行动组合会产生不同结果。例如玩家“攻击”而狗狗“咬”双方都会掉血玩家“投喂”而狗狗“吼”好感度会明显增加玩家“躲避”而狗狗“跑”狗狗则会恢复一点精力。2.2 游戏怎么结束我设计了三个结局这让玩家有重复挑战的欲望第一个结局是“人狗同盟”。当好感度达到 100狗狗信任玩家游戏进入和平结局。第二个结局是“武力压制”。狗狗血量降到 0玩家赢了但代价是内心的失落。第三个结局是“任务失败”。玩家血量先归零游戏结束提示玩家也许狗狗只是想要食物和耐心。三个结局对应三种玩法思路硬刚、怀柔、拖延。玩家如果想看懂全部剧情就必须把三套策略都试一遍。这种“可重玩性”恰恰是文字游戏最迷人的地方。2.3 用到的 Python 知识点知识点在游戏中的位置作用input()玩家行动选择获取用户输入if/elif/else行动结果结算根据组合触发不同分支while True主循环让游戏持续到胜负判定break结局触发结束循环退出游戏random.choice()狗狗行动生成随机行为函数定义行动选择、结果结算拆分功能让主逻辑清晰这个表格可以当作复习清单。写完游戏之后你再用它对照一遍会发现自己已经不知不觉掌握了 Python 核心入门语法。3. 环境准备装好 Python 就能开始在做游戏之前需要确认电脑上已经安装了 Python。3.1 Python 安装与验证无论你用的是 Windows、macOS 还是 Linux都可以去 Python 官网下载对应系统的稳定版安装包。版本号以官网最新稳定版为准本文重点演示的是通用思路不针对特定小版本。Windows 用户安装时有一个关键勾选项很多新手容易忽略在安装向导第一页勾选最下方的Add Python to PATH。这一步的作用是让系统能在命令行直接识别python命令。如果漏掉后续运行会提示找不到命令。装完之后打开终端或命令行工具输入python --version如果输出类似Python 3.x.x说明环境正常。有些系统上 Python 命令可能是python3 --version这是因为某些 Linux 发行版会同时存在 Python 2 和 Python 3用python3可以明确调用 Python 3。你自己机器上哪条能用就用哪条。3.2 创建项目文件建议新建一个专门的文件夹比如dog_battle然后在里面新建一个 Python 文件文件名可以是human_dog_battle.py。mkdir dog_battle cd dog_battle在文件夹里新建文件后用任意文本编辑器打开比如 VS Code、PyCharm、Notepad或者系统自带的记事本。注意Windows 自带的记事本也可以但保存时文件编码要选择 UTF-8否则中文输出可能出现乱码。Python 3 默认使用 UTF-8 编码所以只要你保存时选对编码终端里的中文一般不会出问题。如果运行后中文乱码优先检查终端编码设置和文件保存编码。4. 从零搭建游戏骨架直接给完整代码看起来确实很爽但如果只是想“跑通”你其实错失了最重要的学习过程。我建议按下面三步先把骨架搭出来再逐步填充细节。4.1 先写主循环所有回合制游戏的核心都是同一个结构循环 结束条件。while True: print(新回合开始) # 玩家行动、狗狗行动、结果结算 break这里的while True表示无限循环游戏会一直运行下去。什么时候结束由胜负判定条件决定判定实现后把break放到对应分支里。很多新手不理解为什么要用while True总觉得它很危险。实际上它就是让程序“边运行边等待输入”的经典写法配合break就能精确退出。4.2 玩家输入与校验玩家输入是整个游戏交互的入口。为了让程序更健壮我们一定要对输入做校验。while True: choice input(请输入数字 1-4).strip() if choice in [1, 2, 3, 4]: print(f你选择了 {choice}) break else: print(输入无效请重新输入。)这里有两个细节值得注意strip()方法会去掉用户输入首尾的多余空格避免用户在输入数字时误敲一个空格导致判断失败。这是实际开发中非常常见的坑。校验逻辑使用if choice in [...]而不是写一长串or条件代码更简洁也更容易扩展。如果以后要加第 5 个选项只需要在列表里加一个字符串。4.3 随机行为狗狗的行为需要随机产生。Python 的标准库random提供了choice方法可以直接从一个序列中随机挑一个元素。import random actions [咬, 吼, 跑] dog_move random.choice(actions)random是 Python 标准库的一部分不需要额外安装。这也是本项目能“零第三方依赖”运行的重要原因。5. 完整代码人狗大作战下面是完整源码。建议不要直接复制粘贴先尝试自己根据前面的骨架思路补全遇到困难再看答案。如果只是想体验效果直接复制也能运行。# 文件名human_dog_battle.py import random import time def show_status(player_hp, dog_hp, affection): print(\n 当前状态 ) print(f你的血量{player_hp} | 狗狗血量{dog_hp} | 好感度{affection}) print() def get_player_action(): print(\n请选择行动) print(1. 攻击强行制服) print(2. 投喂增加好感) print(3. 躲避观察局势) print(4. 查看状态) while True: choice input(请输入数字 1-4).strip() if choice 1: return 攻击 elif choice 2: return 投喂 elif choice 3: return 躲避 elif choice 4: return 查看状态 else: print(输入无效请重新输入。) def get_dog_action(): return random.choice([咬, 吼, 跑]) def resolve_round(player_move, dog_move, player_hp, dog_hp, affection): print(f\n你选择了【{player_move}】狗狗选择了【{dog_move}】) if player_move 攻击: if dog_move 咬: player_hp - 15 dog_hp - 20 print(你冲上前去狗狗也毫不示弱。你被咬了一口但也打中了它。) elif dog_move 吼: player_hp - 5 dog_hp - 25 print(狗狗虚张声势地吼叫你抓住破绽给了它一下。) else: dog_hp - 20 print(狗狗想转身逃跑被你的攻击命中。) elif player_move 投喂: if dog_move 咬: player_hp - 10 affection 10 print(它警惕地咬了你一口但开始留意你手里的食物。) elif dog_move 吼: affection 15 print(它吼了两声却没有真的下口。你慢慢蹲下把食物放在面前。) else: affection 5 dog_hp 5 print(它跑开几步远远看着你。你把食物放在地上等它慢慢靠近。) elif player_move 躲避: if dog_move 咬: print(你及时后退躲开了它的扑咬。) elif dog_move 吼: affection 5 print(它吼叫着试探你你保持冷静没有后退一步。) else: dog_hp 10 print(它跑远了。你趁机喘了口气狗狗也恢复了一点精力。) elif player_move 查看状态: show_status(player_hp, dog_hp, affection) return player_hp, dog_hp, affection def main(): print(欢迎来到「人狗大作战」) print(你遇到了一只凶巴巴的小狗。) print(可以攻击它也可以尝试用食物安抚它。) time.sleep(1) player_hp 100 dog_hp 80 affection 0 round_count 0 while True: round_count 1 print(f\n-------- 第 {round_count} 回合 --------) show_status(player_hp, dog_hp, affection) player_move get_player_action() if player_move 查看状态: continue dog_move get_dog_action() player_hp, dog_hp, affection resolve_round( player_move, dog_move, player_hp, dog_hp, affection ) if affection 100: print(\n狗狗终于放下戒备摇着尾巴走到你身边。) print(你成功驯服了它从此它成为你的伙伴。) print(【结局人狗同盟】) break if dog_hp 0: print(\n狗狗倒了下去。你赢了但心里似乎有些空落落的。) print(【结局武力压制】) break if player_hp 0: print(\n你被狗狗打败了……它可能只是想要一点食物和耐心。) print(【结局任务失败】) break time.sleep(1) if __name__ __main__: main()代码写完后几个核心逻辑值得再解释一次。resolve_round函数接收玩家行动、狗狗行动以及三个状态变量计算后返回更新后的状态。它本身不修改外部变量而是把结果传递回来。这种“输入参数、返回结果”的函数设计比直接在函数里修改全局变量更清晰也更不容易出 bug。get_player_action里的while True是输入校验的经典模式。只要用户输入不合法就继续循环直到拿到合法输入才return。这样可以保证resolve_round永远收到的都是合法行动值。main函数里的while True是游戏主循环。每次循环是一回合先展示状态再获取玩家操作再让狗狗随机行动最后结算胜负。好感度优先级最高先判断它是否达到 100再判断双方血量。这样设计的原因是想传递一个价值观感化比武力更重要所以和平结局优先触发。if __name__ __main__:这个写法保证了当文件被直接运行时才执行main()。以后如果别人写代码import你的文件不会莫名其妙启动游戏。6. 运行结果与效果验证在终端进入项目文件夹运行python human_dog_battle.py如果你的系统需要用python3就把命令替换成python3 human_dog_battle.py运行后你会看到类似下面的界面。欢迎来到「人狗大作战」 你遇到了一只凶巴巴的小狗。 可以攻击它也可以尝试用食物安抚它。 -------- 第 1 回合 -------- 当前状态 你的血量100 | 狗狗血量80 | 好感度0 请选择行动 1. 攻击强行制服 2. 投喂增加好感 3. 躲避观察局势 4. 查看状态 请输入数字 1-4输入1狗狗随机行动输出类似你选择了【攻击】狗狗选择了【吼】 狗狗虚张声势地吼叫你抓住破绽给了它一下。之后再回到下一回合状态显示说明主循环正常。验证游戏是否成功可以按三条路线各玩一次第一次全程选攻击观察“武力压制”结局能否触发。第二次全程选投喂观察“人狗同盟”结局能否触发。第三次故意连续选攻击并期待玩家血量下降观察“任务失败”结局能否触发。如果三种结局都能正常出现程序逻辑基本没有问题。如果某一结局一直触发不了优先检查对应条件的比较符号以及行动结果结算里血量或好感度的增减值。运行失败时第一步要看终端里的报错信息。Python 的报错会明确告诉你是哪一行出了问题是语法错误还是变量名拼写错误。绝大多数小问题都能通过“看最后一行报错”解决。7. 常见问题与排查思路问题现象可能原因排查方式解决方案提示python不是内部或外部命令Python 未加入 PATH运行python --version确认重新安装并勾选Add Python to PATH中文输出乱码文件编码不是 UTF-8查看编辑器右下角编码把文件另存为 UTF-8 编码输入数字后没有反应输入了全角数字或空格检查输入内容用strip()去掉空格只输入半角数字无限循环停不下来缺少break或条件永远为真检查所有结局分支确认每个结局都有break狗狗行为永远一样random未生效或种子固定检查是否调用random.choice确认代码import random且每次调用choice血量变成负数后仍未结束结算顺序错误查看resolve_round后的判断顺序在结算后紧接着判断血量而不是在其他逻辑之后这些问题是初学者最常遇到的。其中输入问题最隐蔽因为控制台里的空格和全角字符肉眼看不太出来。如果代码怎么改都不对建议先把用户输入原样打印出来确认它到底是什么内容。8. 工程化建议从能玩到好用完成了基础版之后你已经有了一个“能跑”的程序。但“能跑”和“写得好”之间还有距离。下面这些建议能让代码质量明显提升也能帮你建立更好的开发习惯。8.1 用常量代替魔法数字代码里的100、80、15、20这些数字散落在多个函数中。如果将来想调整难度需要逐个修改还容易漏掉。更合理的做法是统一使用常量PLAYER_MAX_HP 100 DOG_MAX_HP 80 AFFECTION_MAX 100Python 社区习惯用全大写变量名表示“这个值不该被修改”。虽然 Python 没有真正意义的常量但这是一种代码约定能显著提高可读性。8.2 把判断逻辑继续拆分现在的resolve_round虽然有 9 种交互结果但都堆在一个函数里代码规模已经比较大了。进一步优化时可以把每一类行动提取成独立函数比如handle_attack、handle_feed、handle_dodge。def handle_attack(dog_move, player_hp, dog_hp): ... return player_hp, dog_hp这样resolve_round只负责根据玩家行动分发到对应函数每个函数的职责更单一测试起来也更方便。8.3 增加可配置的难度你可以给游戏增加一个简易的难度选择简单模式狗狗初始血量低困难模式狗狗初始血量高而且伤害更大。把初始参数做成用户输入能让游戏的可玩性立刻上一个台阶。难度参数设计好后连带着需要在玩家选择难度时做输入校验。这会让你再把输入校验逻辑巩固一遍一举两得。8.4 给程序加日志游戏本身不需要日志但你在学习和调试过程中可以考虑加一个debug开关用来输出战斗结算的详细数值。DEBUG True if DEBUG: print(f[调试] 玩家血量变化后{player_hp}, 狗狗血量{dog_hp})这个习惯对以后开发更复杂的程序非常有价值。日志是程序员定位问题的第一工具早点养成习惯后面会少走很多弯路。8.5 打包成可执行文件如果想把游戏分享给没有安装 Python 的朋友可以用PyInstaller打包成可执行文件。pip install pyinstaller pyinstaller -F human_dog_battle.py打包完成后在dist目录下会生成一个可执行文件。把这个文件发给别人对方双击即可运行不需要安装 Python 环境。这是很多 Python 新手想要掌握的技能也是把作品分享出去的常用方式。9. 从这个小游戏到更远的 Python 之路「人狗大作战」看起来只是一个文字游戏但它背后的知识点其实覆盖了 Python 入门阶段最关键的内容。你现在可以动手做三件事。第一先把代码完整敲一遍不要复制粘贴。哪怕最终和示例代码几乎一样你也会因为修改过几个小问题而收获巨大。因为“敲代码时手很快出问题时脑子才开始真正工作”。第二尝试修改参数。把狗狗初始血量改成 50把攻击伤害改成 30看看游戏难度如何变化。这种小改动能让你直观感受到数值设计对游戏体验的影响。第三给它增加一个新功能。比如增加一个“逃跑”选项或者增加一个“道具”系统让玩家可以捡到骨头提高投喂效果。每加一个新功能你都会被迫复习一遍已有的代码结构这正是项目驱动学习的精髓。文字游戏的下一步很自然地会朝着图形界面方向走。你可以用 Tkinter 做窗口版也可以用 pygame 做动画版。但要记住工具可以换核心逻辑不变。先学会用标准库把规则表达清楚再谈图形渲染和界面美化会让后续学习轻松很多。如果你顺手把这个项目保存到自己的代码仓库里以后回头再看会发现那些曾经“看不懂的语法”已经变成了“理所当然的工具”。这就是兴趣带来的正反馈你不是在坚持学习而是在好奇心的驱动下主动探索。希望这只凶巴巴的小狗能成为你 Python 学习路上一个值得记住的坐标。动手运行一下比收藏十篇教程都有用。