我的教授的牌组
没有可悲的牌。
但它确实有这个!
注意: 这个项目是一个可选的额外分数机会。其目的是练习面向对象的编程,以及尝试实现一个比课程中其他一些项目更短的游戏。在 4 月 1 日星期五之前提交整个项目,你可以得到 2 分的奖励。
要想开始,请下载所有项目代码的 压缩文件 。
在这个项目中,我们将实现一个卡牌游戏!这个游戏的灵感来自于类似的 魔术:集会 。
这个游戏有点复杂,虽然没有它的名字那么多。它是这样的:
有两个玩家。每个玩家都有一手牌和一副牌,每轮开始时,每个玩家从自己的牌组中随机抽一张牌。如果玩家在抽牌时卡组是空的,他们就输掉游戏。
卡片有一个名字,一个攻击值,和一个防御值。每一轮,每个玩家从自己的手中选择一张牌来玩。一旦双方都选择了一张牌,就会计算和比较牌的力量统计。权力大的一方赢得这一轮。每张牌的力量值计算如下:
(player card's attack) - (opponent card's defense)
例如,假设玩家 1 打出一张 2000 攻击和 1000 防御的牌,玩家 2 打出一张 1500 攻击和 3000 防御的牌。他们的牌的力量计算如下:
P1: 2000 - 3000 = 2000 - 3000 = -1000
P2: 1500 - 1000 = 1500 - 1000 = 500
所以玩家 2 将赢得这一轮。
第一个赢得 8 轮的玩家赢得比赛!
为了使游戏更加有趣,我们将为我们的卡片添加特殊效果。一张牌可以是 AI 、 Tutor 、 TA 或 Instructor 的类型,每种类型在被打出时都有不同的效果。所有的效果都是在该回合中计算力量之前应用的:
AI
卡将允许你通过抽牌将你牌组的前两张牌加入你的手牌。Tutor
牌将把你手中第一张牌的副本加入你的手牌,代价是失去当前回合。TA
牌会丢弃你手牌中 power
最大的牌,并将丢弃的牌的攻击力和防御力加到自己各自的统计中。Instructor
牌可以存活多个回合,只要它的 power
不是负数。但是,在回合开始时,它的攻击力和防御力会分别减少 1000 。这个游戏使用了几个不同的文件。
classes.py
中找到。cardgame.py
中找到,它负责运行游戏。你不需要打开或阅读这个文件就可以获得全额学分。cards.py
中查看所有的标准卡片和默认牌组;在这里,你可以加入更多的卡片,改变你和对手使用的牌组。如果你熟悉原始游戏,你可能会注意到这些卡牌在创建时并没有考虑到平衡问题,所以可以随意修改统计信息,并根据需要添加或删除卡牌。一旦你实现了这个游戏,你可以通过输入以下内容来启动它:
python3 cardgame.py
在玩游戏时,你可以退出游戏,用 Ctrl-C
或 Ctrl-D
返回到命令行。
以后可以随时参考这一系列的规则,让我们开始制作游戏吧!
该项目根据正确性可获得 2 个额外的分数。
你将交出以下文件:
classes.py
你不需要修改或上交任何其他文件来完成这个项目。要提交该项目,请运行以下命令:
python3 ok --submit
你将能够在 Ok 仪表板 上查看你的提交。
对于我们要求你完成的功能,可能有一些我们提供的初始代码。如果你不愿意使用这些代码,可以随时删除它,然后从头开始。你也可以在你认为合适的时候添加新的功能定义。
但是,请不要修改任何其他函数或编辑任何未列出的文件。 这样做可能会导致你的代码无法通过我们的自动评分器测试。另外,请不要改变任何函数的签名(名称、参数顺序或参数数量)。
在整个项目中,你应该测试你的代码的正确性。经常测试是很好的做法,这样就可以很容易地分离出任何问题。然而,你不应该测试得太频繁,以使自己有时间思考问题。
我们提供了一个名为 ok
的自动评分器,以帮助你测试你的代码并跟踪你的进度。在你第一次运行自动评分器时,你会被要求 用你的网络浏览器登录你的 Ok 账户 。请这样做。每次你运行 ok
时,它都会在我们的服务器上备份你的工作和进度。
ok
的主要目的是为了测试你的实现。
我们建议您在 完成每个问题后 提交。只有你的最后一次提交才会被打分。在你遇到提交问题时,多备份你的代码对我们来说也很有用。 如果你忘记提交,你的最后一份备份将自动转换为提交。
如果你不希望我们记录你的工作备份或你的进度信息,你可以运行
python3 ok --local
有了这个选项,任何信息都不会被发送到我们的课程服务器。如果你想以交互方式测试你的代码,你可以运行
python3 ok -q [question number] -i
并插入相应的问题编号(例如 01
)。这将运行该问题的测试,直到第一个测试失败为止,然后给你一个机会来交互测试你写的函数。
你也可以使用 OK 中的调试打印功能,写上
print("DEBUG:", x)
这将在你的终端中产生一个输出,而不会导致 OK 测试失败,产生额外的输出。
在尝试下面的任何问题之前,一定要看一下 classes.py
底部的 Deck
类。游戏的核心机制是操纵玩家的可用牌组; Deck
类的许多方法将在整个项目中被证明是有用的。
为了玩纸牌游戏,我们需要有纸牌,所以让我们做一些吧!我们首先要实现纸牌类的基本功能。我们首先要实现 Card
类的基础。
首先,在 classes.py
中实现 Card
类的构造函数。这个构造函数需要三个参数:
name
attack
值defense
值每个 Card
实例都应该使用名为 name
、 attack
和 defense
的实例属性来记录这些值。
你还应该在 Card
中实现 power
方法,该方法将另一张卡片作为输入,并计算出当前卡片的力量。如果你想复习一下力量的计算方法,请参考 游戏规则 。
使用 Ok 来测试你的代码:
python3 ok -q Card.__init__
python3 ok -q Card.power
对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第一部分的问题将在不同的
ok
测试下一起考虑,这部分的问题包括在本节的最后。
现在我们有了卡片,我们可以制作一副牌,但我们仍然需要玩家来实际使用它们。我们现在要完成 Player
类的实现。
一个 Player
实例有三个实例属性:
name
是玩家的名字。当你玩游戏时,你可以输入你的名字,它将被转换为一个字符串,传递给构造函数。deck
是 Deck
类的一个实例。你可以用它的 .draw()
方法从里面抽牌。hand
是一个 Card
实例的列表。每个玩家开始时手中都应该有 5 张牌,从他们的牌组 deck
中抽取。在游戏过程中,手牌中的每张牌都可以通过它在列表中的索引来选择。当玩家从牌组中抽出一张新牌时,它将被添加到这个列表的末尾。完成 Player
的构造函数的实现,使 self.hand
被设置为一个从玩家的牌组 deck
中抽出的 5 张牌的列表。
接下来,在 Player
类中实现抽牌 draw
和出牌 play
方法。抽牌 draw
方法从牌组中抽出一张牌并将其加入玩家的手牌中。出牌 play
方法从玩家的手牌中取出并返回一张给定索引的牌。
提示:在实现
Player.__init__
和Player.draw
时,当试图从牌组deck
中抽牌时,尽可能使用类方法。
使用 Ok 来测试你的代码:
python3 ok -q Player.__init__
python3 ok -q Player.draw
python3 ok -q Player.play
对于这个小项目,我们提供了 doctests 来逐步测试你的代码;注意,第 1 部分的问题将在一个不同的
ok
测试下一起考虑,这个测试包括在该部分的最后。
完成这个问题后,你就完成了第 1 部分,你就可以玩这个游戏的工作版本了!
使用 Ok 来测试你的代码:
python3 ok -q 01
此外,键入:
python3 cardgame.py
开始玩“魔术”的游戏:Lambda-ing!
这个版本还没有不同卡牌的效果。在下一部分中,我们将实现各种牌的效果。
为了使卡牌游戏更加有趣,让我们为我们的卡牌添加效果!我们可以通过为每个卡牌类实现一个 effect
函数来实现。该函数接收对手的牌、当前玩家和对手的玩家。
你可以在 classes.py
中找到以下问题。
重要的是: 对于下面的部分, 不要 覆盖任何在
你应该在这上面添加你的实现所表示的行
。此外,在某些effect
方法中,有一些预先指定的变量,用来决定何时打印文本。请确保在你的实现中把这些变量设置为正确的值,以便在发生时打印文本。
在 AICard
类中,实现 AI 的 effect
方法。 AICard
将允许你通过从你的牌组中抽牌 draw
将你牌组的前两张牌加入你的手牌。
使用 Ok 来测试你的代码:
python3 ok -q AICard.effect
对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第二部分的问题将在不同的
ok
测试下一并考虑,该测试包含在该部分的最后。
在 TutorCard
类中,实现 Tutors 的 effect
方法。 TutorCard
会将手牌中第一张牌的副本添加到手牌中,代价是失去当前回合。注意,如果手中没有牌, TutorCard
不会向手中添加任何牌,但仍必须输掉这一轮。
要实现“输”的功能,只需覆盖
TutorCard
的power
方法,返回-float('inf')
。此外,一定要增加牌的副本,而不是所选的牌本身!类方法可能会派上用场。
使用 Ok 来测试你的代码:
python3 ok -q TutorCard.effect
对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第二部分的问题将在不同的
ok
测试下一起考虑,这部分的问题包括在本节的最后。
在 TACard
类中,实现 TA 的 effect
方法。 TACard
丢弃你手中威力 power
最大的牌,并将被丢弃的牌的攻击力和防御力加到自己各自的统计中。 弃牌 会将该牌从你的手牌 hand
中移除。如果手上没有牌, TACard
就不应该为其效果做任何事情。
使用 Ok 来测试你的代码:
python3 ok -q TACard.effect
对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第二部分的问题将在不同的
ok
测试下一并考虑,该测试包含在该部分的最后。
在 InstructorCard
类中,实现教官的 effect
方法。一个 InstructorCard
可以存活多个回合,只要它在一个回合结束时有非负的攻击 attack
或防御 defense
。然而,在回合开始时,它的攻击和防御会被永久地各减少 1000 。
为了实现“生存”的功能,
InstructorCard
应该重新加入玩家的手中。
使用 Ok 来测试你的代码:
python3 ok -q InstructorCard.effect
对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第二部分的问题将在不同的
ok
测试下一并考虑,该测试包含在该部分的最后。
在你完成这个问题后,你将拥有一个功能齐全的“魔法:Lambda-ing”游戏!
使用 Ok 来测试你的代码:
python3 ok -q 02
另外,输入:
python3 cardgame.py
来启动一个游戏。
但这不一定是终点;我们鼓励你用更多的卡片类型、效果,甚至在你的卡组中加入更多的自定义卡片来发挥创意!
请确保提交本项目:
python3 ok --submit