CS61A-Spring2022

Project 0: (Extra Credit) Magic: the Lambda-ing

我的教授的牌组

没有可悲的牌。

但它确实有这个!

说明

注意: 这个项目是一个可选的额外分数机会。其目的是练习面向对象的编程,以及尝试实现一个比课程中其他一些项目更短的游戏。在 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 的类型,每种类型在被打出时都有不同的效果。所有的效果都是在该回合中计算力量之前应用的:

这个游戏使用了几个不同的文件。

一旦你实现了这个游戏,你可以通过输入以下内容来启动它:

python3 cardgame.py

在玩游戏时,你可以退出游戏,用 Ctrl-CCtrl-D 返回到命令行。

以后可以随时参考这一系列的规则,让我们开始制作游戏吧!

组织工作

该项目根据正确性可获得 2 个额外的分数。

你将交出以下文件:

你不需要修改或上交任何其他文件来完成这个项目。要提交该项目,请运行以下命令:

python3 ok --submit

你将能够在 Ok 仪表板 上查看你的提交。

对于我们要求你完成的功能,可能有一些我们提供的初始代码。如果你不愿意使用这些代码,可以随时删除它,然后从头开始。你也可以在你认为合适的时候添加新的功能定义。

但是,请不要修改任何其他函数或编辑任何未列出的文件。 这样做可能会导致你的代码无法通过我们的自动评分器测试。另外,请不要改变任何函数的签名(名称、参数顺序或参数数量)。

在整个项目中,你应该测试你的代码的正确性。经常测试是很好的做法,这样就可以很容易地分离出任何问题。然而,你不应该测试得太频繁,以使自己有时间思考问题。

我们提供了一个名为 ok 的自动评分器,以帮助你测试你的代码并跟踪你的进度。在你第一次运行自动评分器时,你会被要求 用你的网络浏览器登录你的 Ok 账户 。请这样做。每次你运行 ok 时,它都会在我们的服务器上备份你的工作和进度。

ok 的主要目的是为了测试你的实现。

我们建议您在 完成每个问题后 提交。只有你的最后一次提交才会被打分。在你遇到提交问题时,多备份你的代码对我们来说也很有用。 如果你忘记提交,你的最后一份备份将自动转换为提交。

如果你不希望我们记录你的工作备份或你的进度信息,你可以运行

python3 ok --local

有了这个选项,任何信息都不会被发送到我们的课程服务器。如果你想以交互方式测试你的代码,你可以运行

python3 ok -q [question number] -i 

并插入相应的问题编号(例如 01 )。这将运行该问题的测试,直到第一个测试失败为止,然后给你一个机会来交互测试你写的函数。

你也可以使用 OK 中的调试打印功能,写上

print("DEBUG:", x) 

这将在你的终端中产生一个输出,而不会导致 OK 测试失败,产生额外的输出。

Part 1: Basic Game

在尝试下面的任何问题之前,一定要看一下 classes.py 底部的 Deck 类。游戏的核心机制是操纵玩家的可用牌组; Deck 类的许多方法将在整个项目中被证明是有用的。

Q1: Making Cards

为了玩纸牌游戏,我们需要有纸牌,所以让我们做一些吧!我们首先要实现纸牌类的基本功能。我们首先要实现 Card 类的基础。

首先,在 classes.py 中实现 Card 类的构造函数。这个构造函数需要三个参数:

每个 Card 实例都应该使用名为 nameattackdefense 的实例属性来记录这些值。

你还应该在 Card 中实现 power 方法,该方法将另一张卡片作为输入,并计算出当前卡片的力量。如果你想复习一下力量的计算方法,请参考 游戏规则

使用 Ok 来测试你的代码:

python3 ok -q Card.__init__
python3 ok -q Card.power

对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第一部分的问题将在不同的 ok 测试下一起考虑,这部分的问题包括在本节的最后。

Q2: Making a Player

现在我们有了卡片,我们可以制作一副牌,但我们仍然需要玩家来实际使用它们。我们现在要完成 Player 类的实现。

一个 Player 实例有三个实例属性:

完成 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!

这个版本还没有不同卡牌的效果。在下一部分中,我们将实现各种牌的效果。

Part 2: Card Effects

为了使卡牌游戏更加有趣,让我们为我们的卡牌添加效果!我们可以通过为每个卡牌类实现一个 effect 函数来实现。该函数接收对手的牌、当前玩家和对手的玩家。

你可以在 classes.py 中找到以下问题。

重要的是: 对于下面的部分, 不要 覆盖任何在 你应该在这上面添加你的实现所表示的行 。此外,在某些 effect 方法中,有一些预先指定的变量,用来决定何时打印文本。请确保在你的实现中把这些变量设置为正确的值,以便在发生时打印文本。

Q3: AIs: Resourceful Resources

AICard 类中,实现 AI 的 effect 方法。 AICard 将允许你通过从你的牌组中抽牌 draw 将你牌组的前两张牌加入你的手牌。

使用 Ok 来测试你的代码:

python3 ok -q AICard.effect

对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第二部分的问题将在不同的 ok 测试下一并考虑,该测试包含在该部分的最后。

TutorCard 类中,实现 Tutors 的 effect 方法。 TutorCard 会将手牌中第一张牌的副本添加到手牌中,代价是失去当前回合。注意,如果手中没有牌, TutorCard 不会向手中添加任何牌,但仍必须输掉这一轮。

要实现“输”的功能,只需覆盖 TutorCardpower 方法,返回 -float('inf') 。此外,一定要增加牌的副本,而不是所选的牌本身!类方法可能会派上用场。

使用 Ok 来测试你的代码:

python3 ok -q TutorCard.effect

对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第二部分的问题将在不同的 ok 测试下一起考虑,这部分的问题包括在本节的最后。

Q5: TAs: Power Transfer

TACard 类中,实现 TA 的 effect 方法。 TACard 丢弃你手中威力 power 最大的牌,并将被丢弃的牌的攻击力和防御力加到自己各自的统计中。 弃牌 会将该牌从你的手牌 hand 中移除。如果手上没有牌, TACard 就不应该为其效果做任何事情。

使用 Ok 来测试你的代码:

python3 ok -q TACard.effect

对于这个小项目,我们提供了 doctests 来逐步测试你的代码;请注意,第二部分的问题将在不同的 ok 测试下一并考虑,该测试包含在该部分的最后。

Q6: Instructors: Immovable

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