猜数字游戏:写完这个,我终于理解了if/else和循环
猜数字游戏:写完这个,我终于理解了if/else和循环
上一篇文章我们学了变量和input(),今天用这些知识写一个真正能玩的游戏——猜数字。计算机会想一个1到100之间的整数,你来猜,它会告诉你猜大了还是猜小了,直到猜对为止。写完这个程序,你会真正理解 if/else 条件判断和 while 循环。
一句话概括
这篇文章解决一个问题:通过写一个猜数字游戏,学会 if/else 条件判断和 while 循环。
需求分析
在开始写代码之前,先想清楚这个游戏要有哪些功能:
- 计算机随机想一个数字(1-100之间)
- 玩家输入猜测的数字
- 计算机会告诉玩家:猜大了、猜小了、还是猜对了
- 玩家继续猜,直到猜对为止
- 猜对之后,统计玩家一共猜了多少次
涉及的新知识
写这个程序需要用到三个新东西:
| 知识 | 作用 |
|---|---|
if / elif / else | 条件判断,根据不同情况执行不同代码 |
while | 循环,重复执行一段代码直到满足条件 |
random.randint() | 随机生成整数 |
Step 1:随机数
Python自带一个随机数的模块叫random,使用前要先导入:
importrandom然后用randint(a, b)生成 a 到 b 之间(包括 a 和 b)的随机整数:
importrandom# 计算机想一个1到100之间的数字answer=random.randint(1,100)print(answer)# 先打印出来看看,方便测试运行一下,你应该能看到一个1到100之间的数字。
调试技巧:先把随机数打印出来,方便测试。等确认程序没问题了,再把这行print删掉。
Step 2:if / elif / else 条件判断
条件判断的语法是这样的:
if条件1:# 条件1满足时执行这里elif条件2:# 条件1不满足,但条件2满足时执行这里else:# 所有条件都不满足时执行这里注意:if/elif/else后面的代码块要用缩进来表示。Python靠缩进识别代码块,不是靠大括号。
用猜数字来举例:
guess=int(input("请猜一个数字:"))ifguess>answer:print("猜大了,往小一点猜!")elifguess<answer:print("猜小了,往大一点猜!")else:print("恭喜你,猜对了!")拆开解释:
guess > answer:guess是否大于answer?是的话执行下面的printelif是 “else if” 的缩写,意思是"如果上面不满足,再判断这一个"else是"上面所有条件都不满足"的情况
Step 3:while 循环
现在只有一个问题:玩家猜错一次,程序就结束了。但我们想让玩家一直猜,直到猜对为止。
这时候就要用while循环:
while条件:# 条件满足时,重复执行这里的代码写猜数字游戏:
importrandom answer=random.randint(1,100)whileTrue:# True 永远为真,所以这个循环会一直执行guess=int(input("请猜一个1-100之间的数字:"))ifguess>answer:print("猜大了,往小一点猜!")elifguess<answer:print("猜小了,往大一点猜!")else:print("恭喜你,猜对了!")break# 猜对了就退出循环break是什么?
break是用来提前退出循环的。猜对了之后,不需要继续猜了,就用break跳出 while 循环。
Step 4:加入猜词计数
现在游戏基本能玩了,但还差一个功能——统计猜了多少次。
引入一个计数器变量:
importrandom answer=random.randint(1,100)count=0# 计数器,初始值为0whileTrue:guess=int(input("请猜一个1-100之间的数字:"))count+=1# 每次猜完,计数加1ifguess>answer:print("猜大了,往小一点猜!")elifguess<answer:print("猜小了,往大一点猜!")else:print(f"恭喜你,猜对了!你一共猜了{count}次。")break注意这里f"恭喜你,猜对了!你一共猜了 {count} 次。"的写法——f-string可以直接在字符串里插入变量,非常方便。
Step 5:加入"还能不能继续"的判断
现在程序有点硬邦邦的——每次运行只能猜一轮。可以加一个功能:猜完之后问玩家要不要再来一局。
importrandomdefguess_number_game():"""猜数字游戏的核心逻辑"""answer=random.randint(1,100)count=0whileTrue:guess=int(input("请猜一个1-100之间的数字:"))count+=1ifguess>answer:print("猜大了,往小一点猜!")elifguess<answer:print("猜小了,往大一点猜!")else:print(f"🎉 恭喜你,猜对了!你一共猜了{count}次。")breakreturncount# 返回猜的次数# 主程序print("="*30)print("欢迎来到猜数字游戏!")print("我会想一个1-100之间的数字,你来猜")print("="*30)total_games=0# 总共玩了几局total_count=0# 总共猜了多少次whileTrue:print()guess_number_game()again=input("再来一局?(y/n):")ifagain.lower()!='y':# .lower()转成小写print("游戏结束!")breaktotal_count+=1# 统计用,但注意这个逻辑还不够完整print("欢迎下次再来!")改进版本:更完整的记录
上面那个版本有个小问题——统计不够准确。重写一个更干净的版本:
importrandomprint("="*30)print("🎯 猜数字游戏")print("="*30)total_games=0total_guesses=0whileTrue:answer=random.randint(1,100)count=0total_games+=1print(f"\n第{total_games}局开始!")whileTrue:guess=int(input("请猜一个1-100之间的数字:"))count+=1ifguess>answer:print("猜大了,往小一点~")elifguess<answer:print("猜小了,往大一点~")else:print(f"🎉 猜对了!你一共猜了{count}次。")total_guesses+=countbreakprint(f"历史平均:{total_guesses/total_games:.1f}次/局")again=input("\n再来一局?(y/n):")ifagain.lower()!='y':breakprint()print("="*30)print(f"游戏结束!你一共玩了{total_games}局")print(f"总共猜了{total_guesses}次,平均{(total_guesses/total_games):.1f}次/局")print("欢迎下次再来!👋")运行示例:
============================== 🎯 猜数字游戏 ============================== 第 1 局开始! 请猜一个1-100之间的数字:50 猜小了,往大一点~ 请猜一个1-100之间的数字:75 猜大了,往小一点~ 请猜一个1-100之间的数字:63 🎉 猜对了!你一共猜了 3 次。 历史平均:3.0 次/局 再来一局?(y/n):y 第 2 局开始! ...代码解读:每一步为什么这么做
为什么要用count = 0然后count += 1?
count = 0表示把计数器初始化为0。count += 1是count = count + 1的简写,意思是"在原来的基础上加1"。
这种写法在编程里非常常见,叫增量赋值。
类似的还有:
count -= 1(减量)count *= 2(翻倍)count /= 3(除以3)
while True是什么意思?会不会死循环?
while True后面如果不加break,确实会死循环。
这里的逻辑是:
while True保证循环一定开始- 循环内部根据条件判断是否
break - 猜对了就
break退出,没猜对就继续循环
所以不会真的死循环。
什么是函数?为什么要在前面加def?
def用来定义一个函数。函数就是一段可以重复使用的代码。
defsay_hello():print("你好!")say_hello()# 调用函数,输出"你好!"好处是:如果一个功能要用很多次,不用每次都写一遍,直接调用函数就行。
初学者可以先不深入理解函数,知道def 函数名():是定义函数的意思就够了。
常见问题FAQ
Q1:为什么input()要包在int()里?
input()返回的是字符串,字符串不能和数字比较大小。
guess=input("请猜一个数字:")print(guess>50)# 报错!字符串和整数不能比int()把字符串转成整数:
guess=int(input("请猜一个数字:"))print(guess>50)# 正常Q2:为什么用break退出内层循环后,外层循环还在继续?
因为break只退出最近的一层循环。
whileTrue:# 外层循环whileTrue:# 内层循环ifguess==answer:break# 只退出内层循环# 这里还会继续执行break# 需要再写一个break退出外层循环Q3:程序报错NameError: name 'randint' is not defined
说明没有导入random模块。在代码最前面加一行:
importrandom思维挑战
挑战1:限制最大猜词次数
能不能加一个规则:玩家只能猜7次,7次猜不中就输了?
max_attempts=7forattemptinrange(1,max_attempts+1):# range(1, 8) 生成 1, 2, 3, 4, 5, 6, 7guess=int(input(f"第{attempt}/{max_attempts}次:请猜:"))ifguess==answer:print("猜对了!")breakelifguess>answer:print("猜大了")else:print("猜小了")else:# 如果循环正常结束(没break),执行这里print(f"次数用完了!正确答案是{answer}")注意这个else是for-else结构——当 for 循环正常结束(不是因为 break 退出)时,会执行 else 里的代码。
挑战2:猜中后显示段位
根据猜的次数显示不同的评价:
| 猜的次数 | 段位 |
|---|---|
| 1次 | 运气逆天! |
| 2-3次 | 大师级别! |
| 4-5次 | 很不错! |
| 6-7次 | 普通水平 |
| 8次以上 | 继续努力! |
写在最后
写完这个猜数字游戏,你应该已经理解了:
if / elif / else条件判断while循环break退出循环- 变量的基本使用
这三个东西是所有编程语言的基石——不管以后学什么语言,条件判断和循环都是这些核心逻辑。
下一篇文章我们会讲Python的运算符和数据类型转换,这些是写程序的基本功。
参考资料:
- Python官方文档:random模块
- Python官方文档:while语句
