当前位置:网站首页>“罚点球”小游戏
“罚点球”小游戏
2022-07-06 12:23:00 【Crossin的编程教室】
零基础python入门教程:python666.cn
大家好,欢迎来到 Crossin的编程教室 !
这是之前教程初期的一道练习题,现把它单独整理出来,方便同学阅读。
在学习了一点 Python 基础之后,我们可以做一个罚点球的小游戏,大概流程是这样:
每一轮,你先输入一个方向射门,然后电脑随机判断一个方向扑救。方向不同则算进球得分,方向相同算扑救成功,不得分。
之后攻守轮换,你选择一个方向扑救,电脑随机方向射门。
第5轮结束之后,如果得分不同,比赛结束。
5轮之内,如果一方即使踢进剩下所有球,也无法达到另一方当前得分,比赛结束。
5论之后平分,比赛继续进行,直到某一轮分出胜负。
实现方法有很多种,我这里提供的只是一种参考。你可以按照自己喜欢的方式去做,那样才是属于你的游戏。
先说一下方向的设定。我的想法比较简单,就是左、中、右三个方向,用字符串来表示。射门或者扑救的时候,直接输入方向。所以这里我用 input 来实现。有同学是用 1-9 的数字来表示八个方向和原地不动,每次输入一个数字,这也是可以的。不过这样守门员要扑住的概率可就小多了。
至于电脑随机挑选方向,如果你是用数字表示,就用我们之前讲过的 randint 来随机就行。不过我这里打算用 random 的一个方法:choice。它的作用是从一个 list 中随机挑选一个元素。
于是,罚球的过程可以这样写:
from random import choice
you = input('选择你要踢的方向:(左、中、右)')
print('你踢向了' + you)
direction = ['左', '中', '右']
com = chice(direction)
print ('电脑扑向了' + com)
if you != com:
print ('进球得分!')
else:
print ('被扑出去了...')
反之亦然,这里不赘述。
接下来,我们让它循环5次,并且记录下得分。暂时先不判断胜负。
用 score_you 表示你的得分,score_com 表示电脑得分。开始都为0,每进一球就加1。
from random import choice
score_you = 0
score_com = 0
direction = ['左', '中', '右']
for i in range(5):
print('==== 第 %d 回合 - 玩家罚球 ====' % (i+1))
you = input('选择你要踢的方向:(左、中、右)')
print('你踢向了' + you)
com = choice(direction)
print('电脑扑向了' + com)
if you != com:
print('进球得分!')
score_you += 1
else:
print('被扑出去了...')
print('比分: %d(you) - %d(com)\n' % (score_you, score_com))
print('==== 第 %d 回合 - 玩家扑救 ====' % (i+1))
you = input('选择你要扑的方向:(左、中、右)')
print('你扑向了' + you)
com = choice(direction)
print('电脑踢向了' + com)
if you == com:
print('扑出去了!')
else:
print('丢球了...')
score_com += 1
print('比分: %d(you) - %d(com)\n' % (score_you, score_com))
这段代码里有两段相似度很高,你可以想想是不是有办法可以用个函数把它简化。
在此基础之上,我们再加上胜负判断,如果5轮结束之后是平分,就继续踢。
所以我们把一轮的过程单独拿出来作为一个函数kick,在5次循环之后再加上一个while循环。
另外,这里把之前的 score_you 和 score_com 合并成了一个 score 数组。这里的原因是,要让 kick 函数里用到外部定义的变量,需要使用全局变量的概念。暂时想避免说这个,而用 list 不存在这个问题。(但希望你不要觉得在函数里使用外面定义的变量很自然,后面我们会具体分析。想要了解的同学可以在公众号“Crossin的编程教室”里回复关键字 全局变量)
from random import choice
score = [0, 0]
direction = ['左', '中', '右']
def kick():
print('==== 玩家罚球 ====')
you = input('选择你要踢的方向:(左、中、右)')
print('你踢向了' + you)
com = choice(direction)
print('电脑扑向了' + com)
if you != com:
print('进球得分!')
score[0] += 1
else:
print('被扑出去了...')
print('比分: %d(you) - %d(com)\n' % (score[0], score[1]))
print('==== 玩家扑救! ====')
you = input('选择你要扑的方向:(左、中、右)')
print('你扑向了' + you)
com = choice(direction)
print('电脑踢向了' + com)
if you == com:
print('扑出去了!')
else:
print('丢球了...')
score[1] += 1
print('比分: %d(you) - %d(com)\n' % (score[0], score[1]))
for i in range(5):
print('==== 第 %d 轮 ====' % (i + 1))
kick()
while score[0] == score[1]:
i += 1
print('==== 第 %d 轮 ====' % (i + 1))
kick()
if score[0] > score[1]:
print('玩家获胜!')
else:
print('玩家落败.')
到这里我们的点球游戏已经快完成了,现在要做的就是增加比赛提前结束的机制,让它更真实。
我的思路是这样:比赛提前结束,就是落后一方的得分,加上他在5轮中剩下的轮数,仍然低于领先方现在的得分。虽然可以根据当前的轮数计算剩下的机会,但由于先踢和后踢的情况不同,这样计算会有些复杂,容易搞错。
所以我决定再增加一个 list,里面记录双方剩余的轮数,初始均为5。
每踢一球,就把对应那一方的计数减1。
每踢一球,就判断输的那一方是否还有机会。
于是需要在最开始增加代码:
rest = [5, 5]
以玩家为例,每踢完一球的判断:
if rest[0] > 0:
rest[0] -= 1
if score[0] < score[1] and score[0] + rest[0] < score[1]:
return True
if score[1] < score[0] and score[1] + rest[1] < score[0]:
return True
由于提前结束仅限于5轮内,所以要判断 rest[0]>0。return 可以让 kick 函数提前结束。电脑的判断与这个类似,只是要换成 rest[1]。
因为需要有个方法提前结束循环,所以我让 kick 函数返回一个 bool 值,正常情况返回 False,一旦提前结束就返回 True。
之前的 for 循环也改成 while,以便于提前结束循环:
i = 0
end = False
while i < 5 and not end:
print '==== 第 %d 轮 ====' % (i+1)
end = kick()
i += 1
完整代码如下:
from random import choice
score = [0, 0]
rest = [5, 5]
direction = ['左', '中', '右']
def kick():
print('==== 玩家罚球 ====')
you = input('选择你要踢的方向:(左、中、右)')
print('你踢向了' + you)
com = choice(direction)
print('电脑扑向了' + com)
if you != com:
print('进球得分!')
score[0] += 1
else:
print('被扑出去了...')
print('比分: %d(you) - %d(com)\n' % (score[0], score[1]))
if rest[0] > 0:
rest[0] -= 1
if score[0] < score[1] and score[0] + rest[0] < score[1]:
return True
if score[1] < score[0] and score[1] + rest[1] < score[0]:
return True
print('==== 玩家扑救! ====')
you = input('选择你要扑的方向:(左、中、右)')
print('你扑向了' + you)
com = choice(direction)
print('电脑踢向了' + com)
if you == com:
print('扑出去了!')
else:
print('丢球了...')
score[1] += 1
print('比分: %d(you) - %d(com)\n' % (score[0], score[1]))
if rest[1] > 0:
rest[1] -= 1
if score[0] < score[1] and score[0] + rest[0] < score[1]:
return True
if score[1] < score[0] and score[1] + rest[1] < score[0]:
return True
return False
i = 0
end = False
while i < 5 and not end:
print('==== 第 %d 轮 ====' % (i + 1))
end = kick()
i += 1
while score[0] == score[1]:
i += 1
print('==== 第 %d 轮 ====' % (i + 1))
kick()
if score[0] > score[1]:
print('玩家获胜!')
else:
print('玩家落败.')
这次的程序比我们之前写过的都要长,结构也更复杂,需要耐心去分析。
你可以按照自己的理解,去一步步完善这个游戏。
感谢转发和点赞的各位~
_往期文章推荐_
如需了解付费精品课程及教学答疑服务
请在Crossin的编程教室内回复: 666
边栏推荐
- 小微企业难做账?智能代账小工具快用起来
- 系统与应用监控的思路和方法
- 【云小课】EI第47课 MRS离线数据分析-通过Flink作业处理OBS数据
- How to handle the timeout of golang
- 腾讯字节阿里小米京东大厂Offer拿到手软,老师讲的真棒
- Continuous test (CT) practical experience sharing
- 微信小程序常用集合
- Special topic of rotor position estimation of permanent magnet synchronous motor -- Summary of position estimation of fundamental wave model
- In line elements are transformed into block level elements, and display transformation and implicit transformation
- 某东短信登录复活 安装部署教程
猜你喜欢
随机推荐
RT-Thread 组件 FinSH 使用时遇到的问题
leetcode先刷_Maximum Subarray
Tencent byte Alibaba Xiaomi jd.com offer got a soft hand, and the teacher said it was great
Linear distance between two points of cesium
OceanBase社区版之OBD方式部署方式单机安装
腾讯字节阿里小米京东大厂Offer拿到手软,老师讲的真棒
5. 无线体内纳米网:十大“可行吗?”问题
5. 無線體內納米網:十大“可行嗎?”問題
Boder radius has four values, and boder radius exceeds four values
【云原生与5G】微服务加持5G核心网
Appx代码签名指南
永磁同步电机转子位置估算专题 —— 基波模型与转子位置角
How does kubernetes support stateful applications through statefulset? (07)
【Yann LeCun点赞B站UP主使用Minecraft制作的红石神经网络】
AsyncHandler
Tencent cloud database public cloud market ranks top 2!
腾讯字节等大厂面试真题汇总,网易架构师深入讲解Android开发
Le lancement du jupyter ne répond pas après l'installation d'Anaconda
8086 instruction code summary (table)
Standardized QCI characteristics