[2021 Spring] CS61A Project 3: Ants Vs. SomeBees (Phase 4)
项目说明:https://inst.eecs.berkeley.edu/~cs61a/sp21/proj/ants/
蚂蚁大战蜜蜂 灵感来源:植物大战僵尸(Plants Vs. Zombies,PVZ)
Phase 1: https://www.cnblogs.com/ikventure/p/14986805.html
Phase 2: https://www.cnblogs.com/ikventure/p/14988467.html
Phase 3: https://www.cnblogs.com/ikventure/p/14992754.html
Phase 4: https://www.cnblogs.com/ikventure/p/14994734.html
效果展示: https://www.cnblogs.com/ikventure/p/15001093.html
Phase 4: Water and Might
Problem 10 (2 pt)
目前place有Hive和基本场地两种类型,现在引入水池类型Water。
只有watersafe的insect可以放置在Water中,在Insect引入is_watersafe的类属性,蜜蜂可以飞,所以Bee.is_watersafe是True。
Water类:
add_insect方法,放置insect到place上,如果insect不是watersafe的,将该insect的生命值降至0,调用Insect类的reduce_health方法。
class Insect:
"""An Insect, the base class of Ant and Bee, has health and a Place."""
damage = 0
# ADD CLASS ATTRIBUTES HERE
is_watersafe = False
class Bee(Insect):
"""A Bee moves from place to place, following exits and stinging ants."""
name = 'Bee'
damage = 1
# OVERRIDE CLASS ATTRIBUTES HERE
is_watersafe = True
class Water(Place):
"""Water is a place that can only hold watersafe insects."""
def add_insect(self, insect):
"""Add an Insect to this place. If the insect is not watersafe, reduce
its health to 0."""
# BEGIN Problem 10
"*** YOUR CODE HERE ***"
super().add_insect(insect)
if not insect.is_watersafe:
insect.reduce_health(insect.health)
# END Problem 10
Problem 11 (2 pt)
引入水上射手ScubaThrower,继承自ThrowerAnt,可以放置在Water场地中,只需要重写name, is_watersafe, food_cost。
Class | Food Cost | Initial Health |
---|---|---|
ScubaThrower | 6 | 1 |
代码: |
# BEGIN Problem 11
# The ScubaThrower class
class ScubaThrower(ThrowerAnt):
"""ScubaThrower is a watersafe ThrowerAnt."""
name = 'Scuba'
food_cost = 6
is_watersafe = True
implemented = True
# END Problem 11
Extra Credit (2 pt)
引入QueenAnt,一种防水的ScubaThrower,除了标准的ScubaThrower.action,每次行动时,它身后的所有蚂蚁damage加倍(不包括FireAnt的反伤)。
Class | Food Cost | Initial Health |
---|---|---|
QueenAnt | 7 | 1 |
QueenAnt有三种特殊的规则:
- queen生命值降至0,蜜蜂胜利。任一蜜蜂到达tunnel终点,蜜蜂同样胜利。调用bees_win()。
- 只能存在一个真的queen,在第一个queen之后实例化的都是冒充者impostor,在第一次行动时生命值降为0,不会有增伤效果或者射手的效果;impostor死亡后游戏继续。
- 真queen不能被移除 ,尝试移除queen不会有效果,也不会造成异常。需要重写QueenAnt中的Ant.remove_from。
思路:
- 同一个类的所有实例拥有相同的类属性。要让第一个实例为真,后面的所有实例为假,可以先设置is_true为真,在第一个实例化后修改类属性。
- 通过Place.exit.ant获取QueenAnt后面的蚂蚁。
- 为了避免重复加倍蚂蚁的damage,需要对有倍伤buff的蚂蚁进行标记。在Ant中添加类属性buffed = False。
- 加倍伤buff时,注意容器类蚂蚁内部的contained蚂蚁damage也要加倍。
# BEGIN Problem EC
class QueenAnt(ScubaThrower): # You should change this line
# END Problem EC
"""The Queen of the colony. The game is over if a bee enters her place."""
name = 'Queen'
food_cost = 7
# OVERRIDE CLASS ATTRIBUTES HERE
# BEGIN Problem EC
implemented = True # Change to True to view in the GUI
is_truequeen = True
# END Problem EC
def __init__(self, health=1):
# BEGIN Problem EC
"*** YOUR CODE HERE ***"
super().__init__(health)
self.is_truequeen = QueenAnt.is_truequeen
if self.is_truequeen:
QueenAnt.is_truequeen = False
# END Problem EC
def action(self, gamestate):
"""A queen ant throws a leaf, but also doubles the damage of ants
in her tunnel.
Impostor queens do only one thing: reduce their own health to 0.
"""
# BEGIN Problem EC
"*** YOUR CODE HERE ***"
if not self.is_truequeen:
self.reduce_health(self.health)
else:
ScubaThrower.action(self, gamestate)
behind = self.place.exit
while behind:
if behind.ant:
if not behind.ant.buffed:
behind.ant.damage *= 2
behind.ant.buffed = True
if behind.ant.is_container() and behind.ant.contained_ant:
if not behind.ant.contained_ant.buffed:
behind.ant.contained_ant.damage *= 2
behind.ant.contained_ant.buffed = True
behind = behind.exit
# END Problem EC
def reduce_health(self, amount):
"""Reduce health by AMOUNT, and if the True QueenAnt has no health
remaining, signal the end of the game.
"""
# BEGIN Problem EC
"*** YOUR CODE HERE ***"
if not self.is_truequeen:
Insect.reduce_health(self, amount)
else:
self.health -= amount
if self.health <= 0:
bees_win()
def remove_from(self, place):
if not self.is_truequeen:
Ant.remove_from(self, place)
# END Problem EC