Python学习日记 – KillAliens 实现持续读写并运算

前言

放下 Python 已经半年了,在期中考试之后,很快就要涉及算法初步了,我觉得通过 Python 的思维,对算法的学习有十分显著的帮助,便花费几小时写了这个 KillAliens 小游戏。

其中最重要的两个部分,分别是 分数的持续读写并运算随机事件的生成 这两个部分,接下来我将详细讲述如何实现整个 KillAliens 小游戏以及这两个部分的实现过程。

基于

此 KillAilens 小游戏,灵感来源于我很久之前写的简单的 击杀外星人.py 这个只有不到 30 行的 简单文字表达 游戏,在 KillAilens 里,记分系统是 击杀外星人.py 没有的,同时使用了字典,使用键值对实现每个种类的 Ailen 对应一个属于自己的分数。

击杀外星人.py 可以在我的Python学习仓库内找到。

补充

这个小游戏 初次写于 2022/5/14 在经过研究后,2022/5/19修改了算法,提高了线程性能,旧代码在仓库中名称为 KillAliens.pyKillAliens_NoComment.py ,新代码在仓库中名称为 KillAliens_V2.pyKillAliens_NoComment_V2.py

输出预览

你的名字:
	Magneto
你好  Magneto  ,接下来让我为你介绍游戏中有的 Alien 以及其对应的分数!

	击杀 Big Alien 可以获得 10 分
	击杀 Middle Alien 可以获得 5 分
	击杀 A Alien 可以获得 2 分
	击杀 Small Alien 可以获得 1 分

当前你的分数是  0  分

如果你想退出游戏,请输入 'quit' ,退出游戏,或输入其它任意值开始(继续)游戏。
	开始
请输入你想要击杀的 Alien 的  名称  击杀成功后,可获得指定分数
	名称:Big Alien
		对应分数:10
	名称:Middle Alien
		对应分数:5
	名称:A Alien
		对应分数:2
	名称:Small Alien
		对应分数:1
请注意,你有概率无法击杀 Alien 并且会因此结束游戏,并且对应分数越高,击杀几率越小。
请输入对应名称:
	Small Alien
你选择了 Small Alien
恭喜你  Magneto  ,击杀成功,获得 1 分
当前总分: 1  分




当前你的分数是  1  分

如果你想退出游戏,请输入 'quit' ,退出游戏,或输入其它任意值开始(继续)游戏。
	继续
请输入你想要击杀的 Alien 的  名称  击杀成功后,可获得指定分数
	名称:Big Alien
		对应分数:10
	名称:Middle Alien
		对应分数:5
	名称:A Alien
		对应分数:2
	名称:Small Alien
		对应分数:1
请注意,你有概率无法击杀 Alien 并且会因此结束游戏,并且对应分数越高,击杀几率越小。
请输入对应名称:
	Small Alien
你选择了 Small Alien
恭喜你  Magneto  ,击杀成功,获得 1 分
当前总分: 2  分




当前你的分数是  2  分

如果你想退出游戏,请输入 'quit' ,退出游戏,或输入其它任意值开始(继续)游戏。
	继续
请输入你想要击杀的 Alien 的  名称  击杀成功后,可获得指定分数
	名称:Big Alien
		对应分数:10
	名称:Middle Alien
		对应分数:5
	名称:A Alien
		对应分数:2
	名称:Small Alien
		对应分数:1
请注意,你有概率无法击杀 Alien 并且会因此结束游戏,并且对应分数越高,击杀几率越小。
请输入对应名称:
	Big Alien
你选择了 Big Alien
很遗憾  Magneto  ,你尝试击杀 Big Alien 失败了,分数清零,退出游戏。

进程已结束,退出代码0

代码预览

############################
### Date 2022 May 14     ###
### Author Magneto       ###
### Name KillAliens      <——>
### Facility Windows 11  ###
### Language Python      ###
############################

import random
import time
aliens_name_and_mark = {
    'Big Alien': 10,
    'Middle Alien': 5,
    'A Alien': 2,
    'Small Alien': 1
}
Data = {'The_name': '', 'The_marks': 0}
state_one = ['1', '2', '3', '4', '5']
print("欢迎来到 KillAliens 小游戏,字典已经初始化完成\n接下来请输入内容\n")
Data['The_name'] = input("你的名字:\n\t")
print(f"你好 \033[94m{Data['The_name']}\033[0m ,接下来让我为你介绍游戏中有的 Alien 以及其对应的分数!\n")
time.sleep(1)
for name, marks in aliens_name_and_mark.items():
    print(f"\t击杀 {name} 可以获得 {marks} 分")
time.sleep(1)
while True:
    print(f"\n当前你的分数是 \033[35m{Data['The_marks']}\033[0m 分")
    exit_the_game = input("\n如果你想退出游戏,请输入 'quit' ,退出游戏,或输入其它任意值开始(继续)游戏。\n\t")
    if exit_the_game == 'quit':
        break
    print("请输入你想要击杀的 Alien 的 \033[94m 名称 \033[0m 击杀成功后,可获得指定分数")
    for name, marks in aliens_name_and_mark.items():
        print(f"\t名称:{name}\n\t\t对应分数:{marks}")
    print("请注意,你有概率无法击杀 Alien 并且会因此结束游戏,并且对应分数越高,击杀几率越小。")
    time.sleep(1)
    ChoiseAliens = input("请输入对应名称:\n\t")
    if ChoiseAliens == 'Small Alien':
        state_two = ['1', '2', '3', '4', '5', '6', '7', '8']
        The_Random = random.choice(state_two)
        print("你选择了 Small Alien")
        if The_Random in state_one:
            print(f"恭喜你 \033[94m{Data['The_name']}\033[0m ,击杀成功,获得 1 分")
            Data['The_marks'] += aliens_name_and_mark['Small Alien']
            print(f"当前总分:\033[35m{Data['The_marks']}\033[0m 分\n\n\n")
        else:
            print(f"很遗憾 \033[94m {Data['The_name']} \033[0m ,你尝试击杀 Small Alien 失败了,分数清零,退出游戏。")
            break
    elif ChoiseAliens == 'A Alien':
        state_two = ['1', '2', '3', '6', '7', '8']
        The_Random = random.choice(state_two)
        print("你选择了 A Alien")
        if The_Random in state_one:
            print(f"恭喜你 \033[94m{Data['The_name']}\033[0m ,击杀成功,获得 2 分")
            Data['The_marks'] += aliens_name_and_mark['A Alien']
            print(f"当前总分:\033[35m{Data['The_marks']}\033[0m 分\n\n\n")
        else:
            print(f"很遗憾 \033[94m{Data['The_name']}\033[0m ,你尝试击杀 A Alien 失败了,分数清零,退出游戏。")
            break
    elif ChoiseAliens == 'Middle Alien':
        state_two = ['1', '2', '6', '7', '8']
        The_Random = random.choice(state_two)
        print("你选择了 Middle Alien")
        if The_Random in state_one:
            print(f"恭喜你 \033[94m {Data['The_name']} \033[0m ,击杀成功,获得 5 分")
            Data['The_marks'] += aliens_name_and_mark['Middle Alien']
            print(f"当前总分:\033[35m{Data['The_marks']}\033[0m 分\n\n\n")
        else:
            print(f"很遗憾 \033[94m{Data['The_name']}\033[0m ,你尝试击杀 Middle Alien 失败了,分数清零,退出游戏。")
            break
    elif ChoiseAliens == 'Big Alien':
        state_two = ['1', '6', '7', '8']
        The_Random = random.choice(state_two)
        print("你选择了 Big Alien")
        if The_Random in state_one:
            print(f"恭喜你 \033[94m{Data['The_name']}\033[0m ,击杀成功,获得 10 分")
            Data['The_marks'] += aliens_name_and_mark['Big Alien']
            print(f"当前总分:\033[35m{Data['The_marks']}\033[0m 分\n\n\n")
        else:
            print(f"很遗憾 \033[94m{Data['The_name']}\033[0m ,你尝试击杀 Big Alien 失败了,分数清零,退出游戏。")
            break
    else:
        print("您需要输入对应的\033[94m名称\033[0m,而不是其它内容。")

代码分析

分析说明

本文的代码分析,主要是讲所使用的主要语法,不会具体分析每行代码的作用,这需要自行理解。

注释

Python 中,注释用 井号# 进行标识。井号后的内容将会被 Python 解释器 忽略,在本文内附上的代码是没有功能性注释的,只有作者注释。

模块引入

代码 第9-10行 分别引入了 random 模块和 time 模块。

import random
import time

这两个模块的作用分别是随机处理、使 Python 线程休眠指定时间。

random 的用法曾在 Python学习日记 – 坐标移动#random 模块 中讲过,这里就不再多说。

time 的作用技术使 Python 线程休眠指定时间,而这个时间是按照秒为单位的,让我们尝试一下吧:

name = input("你的名字:")
time.sleep(1)
print(f"你好{name}")

这是运行结果

你的名字:Magneto
你好Magneto

上述代码的第一行在 Python 线程开始运行后,立马执行,询问名字,在得到用户输入的值后,执行第二行的代码,Python 解释器在第二行得到指令,要求休眠 1秒 进而休眠,在 Python 线程休眠了 1秒 后,才继续执行第三行的代码,输出名字。

字典 和 for 语句

在 Python 中,字典是使用 { } 花括号括起来的内容,其中包括两个内容,分别是键(key)和值(value),我们称之为键值对,每一个键对应一个值,在 KillAliens 中,第12-17行 是一个字典,第18行 是一个字典,这两个字典书写格式不同,但都是字典,没有任何区别,第12-17行 的书写格式是为了解决美观问题,即我们在 Python 中被要求规范书写代码,这是一个良好的习惯。

使用字典,是为了方便 for 语句的输出,让我们写一个 字典 和 for 语句的输出试试吧:

name_and_money = {
    'Mark': '10',
    'Tom': '20',
}
for name, money in name_and_moneu.items():
    print(f"{name} 有 {money} 元。")

为了方便观看学习,我将每个键值对分开写了。运行结果:

Mark 有 10 元。
Tome 有 20 元。

for 语句中,有严格的顺序对应,name 对应键,money 对应值,而 items() 是为了循环输出,直到字典没有更多的键值对可以打印才跳出循环。

而在 for 语句内的 print 可以使用上述对键值对的命名,也就是可以使用 name 和 money 对应字典内的键和值,进行读取。

除了 for 语句外,字典也可以被直接读和写,但这仅针对值的读和写。

让我们先看读取

# 首先定义字典
name_and_money = {
    'Mark': '10',
    'Tom': '20',
}
# 让我们读取字典
print(f"他有{name_and_money['Mark']}元")

print 中使用 { },代表读取特定区域的内容,而在其中加入 [ ] ,是为了读取特定区域内的某项特定值。

在上述代码中,使用 {name_and_money['Mark']} 读取了 name_and_money 字典中 Mark 这个键所对应的值 10 。让我们来看看输出结果

他有10元

现在让我们看看写入

# 首先定义字典
name_and_money = {
    'Mark': 10,
    'Tom': 20,
}
# 让我们读取原本的字典
print(f"他原来有{name_and_money['Mark']}元")
# 数字+1,即进行运算
name_and_money['Mark'] += 1
# 让我们读取新的的字典
print(f"但他现在有{name_and_money['Mark']}元")

让我们看看输出结果

他原来有10元
但他现在有11元

值得注意的是,与读取部分不同,我没有给这个值带 引号 ' ' 这是因为,带上引号就代表了这是一个字串符,需要我们转换它为浮点数才能继续进行运算,而不带引号,就代表了这是一个纯粹的数字,可以直接运算了。

当然,这是运算写入,也可以直接写入

# 首先定义字典
name_and_boyfriend = {
    'Mark': 'Williams',
    'Tom': 'Brown',
}
# 让我们读取原本的字典
print(f"他的前男友是{name_and_boyfriend['Mark']}")
# 覆盖值
name_and_boyfriend['Mark'] = 'Wilson'
# 让我们读取新的的字典
print(f"他现男友是{name_and_boyfriend['Mark']}")

我们在这里举了一个男朋友的例子,直接覆盖替换了键所对的值。

他的前男友是Williams
他现男友是Wilson

这里覆盖使用的是字串符,数字也是同样的道理。

值得注意的是,如此覆盖的修改是永久性的。

让我们看看是什么意思

# 首先定义字典
name_and_boyfriend = {
    'Mark': 'Williams',
    'Tom': 'Brown',
}
# for 语句循环
for name, boyfriend in name_and_boyfriend.items():
    print(f'{name}曾经的男朋友是{boyfriend}')
# 让我们读取原本的字典
print(f"他的前男友是{name_and_boyfriend['Mark']}")
# 覆盖值
name_and_boyfriend['Mark'] = 'Wilson'
# 让我们读取新的的字典
print(f"他现男友是{name_and_boyfriend['Mark']}")
# for 语句循环
for name, boyfriend in name_and_boyfriend.items():
    print(f'{name}现在的男朋友是{boyfriend}')
Mark曾经的男朋友是Williams
Tom曾经的男朋友是Brown
他的前男友是Williams
他现男友是Wilson
Mark现在的男朋友是Wilson
Tom现在的男朋友是Brown

Tom作为对照组,是没有变过的,他的男朋友一直是Brown,而Mark在更改后,for 语句读取字典也同样读取的是修改后的值。

if-elif-else 进阶

KillAlines 中,使用了 if 语句的进阶,在 if 语句中,嵌套 if 语句,并且使用了 in 语法,让我们使用 KillAlines 节选的代码,进行修改后讲解吧。

# 引入 random 随机模块
import random
# 对照数字
state_one = ['1', '2', '3', '4', '5']
# 输入对应的名字,这里写的是下面 if 语句所对的名称
ChoiseAliens = input("请输入对应名称:\n\t")
# if 语句判断,如果 ChoiseAliens 的值是 Small Alien 则执行 if 语句内的内容
if ChoiseAliens == 'Small Alien':
    # 实验组,移交 The_Random 进行随机处理。
    state_two = ['1', '2', '3', '4', '5', '6', '7', '8']
    The_Random = random.choice(state_two)
    print("你选择了 Small Alien")
    # 嵌套 if 语句,所生成的随机数如果在对照组中,则返回下值
    if The_Random in state_one:
        print(f"恭喜你,击杀成功,获得 1 分")
   # 嵌套 if 语句,子语句,所生成的随机数如果不在对照组中,则返回下值
    else:
        print(f"很遗憾,你尝试击杀 Small Alien 失败了")
# if 语句,子语句判断,如果 ChoiseAliens 的值是 A Alien 则执行
elif ChoiseAliens == 'A Alien':
    # 实验组,移交 The_Random 进行随机处理。
    state_two = ['1', '2', '3', '6', '7', '8']
    The_Random = random.choice(state_two)
    print("你选择了 A Alien")
    # 嵌套 if 语句,所生成的随机数如果在对照组中,则返回下值
    if The_Random in state_one:
        print(f"恭喜你 ,击杀成功,获得 2 分")
    else:
   # 嵌套 if 语句,子语句,所生成的随机数如果不在对照组中,则返回下值
        print(f"很遗憾 ,你尝试击杀 A Alien 失败了")
# if 语句,子语句判断,如果都输入内容都不在if和elif中,则返回下值
else:
     print("您需要输入的是指定名称而不是其它内容。")

为了展示不同的结果,我进行了多次运行。

# 第一次
请输入对应名称:
	Small Alien
你选择了 Small Alien
恭喜你,击杀成功,获得 1 分

# 第二次运行
请输入对应名称:
	A Alien
你选择了 A Alien
很遗憾 ,你尝试击杀 A Alien 失败了

# 第三次运行
请输入对应名称:
	Magneto
您需要输入的是指定名称而不是其它内容。

第一次运行,我们走了 if 的判断,随机挑选的一个数,在对照组 state_one 中,所以我们返回了成功,第二次运行,我们走了 elif 判断,随机挑选的一个数,不在对照组 state_one 中,所以我们返回了失败,第三次运行,我们输入了 Magneto,ifelif 判断都不符合规则,移交 else 处理,返回了提示。

在 KillAliens 中,这样有效避免了输入不存在的内容,导致程序报错。

While 循环

While 循环在 KillAliens 中,仅仅进行了简单使用,不进行过多讲解,可以查看 Python3 循环语句 | 菜鸟教程 进行学习。

尾声

KillAlines 是我写的一个较为复杂的程序,算是一个简单的文字小游戏,仅通过 Python 完成的记分系统、判断系统、击杀系统,都是很完善且较为简单的,但这些数据仅存在线程当中,仍然有很大

此文由 Magneto 发布,本文采用《CC BY-NC-ND 4.0》协议,转载必须注明作者和本文链接。

评论

  1. Macintosh Chrome
    2年前
    2022-6-12 23:43:19

    我爱Python

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
小恐龙
酷安
颜文字
Emoji
花!
上一篇
下一篇