[2021 Spring] CS61A Project 3: Ants Vs. SomeBees (Phase 3)
项目说明: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 3: More Ants!
继续添加蚂蚁类型
Problem 6 (2 pt)
WallAnt类似PVZ坚果墙,高生命不攻击。
Class | Food Cost | Initial Health |
---|---|---|
WallAnt | 4 | 4 |
action:坚果墙自身不行动,action方法从Insect类继承即可。
名称:wall.name = 'Wall'
health:初始化时传入,默认4
只要是需要实例化的Ant类,都要把implemented设为True。
补充一下注释比较好看。
代码:
# BEGIN Problem 6
# The WallAnt class
class WallAnt(Ant):
"""WallAnt does nothing each turn but it has a large health value."""
name = 'Wall'
food_cost = 4
implemented = True
def __init__(self, health=4):
super().__init__(health)
# END Problem 6
Problem 7 (3 pt)
HungryAnt类似PVZ大嘴花,可以吞掉自身位置的随机一只蜜蜂,但是吞掉蜜蜂后需要等待3回合的咀嚼CD,没有蜜蜂时不行动。
Class | Food Cost | Initial Health |
---|---|---|
HungryAnt | 4 | 1 |
思路:
chewing是实例属性,每个实例独立CD,初始化为0
名称:'Hungry'
chew_duration为类属性
action:
当self.chewing为0且当前位置有蜜蜂则随机选择一个,health置0,注意置0后要从当前位置清出。
其他情况CD不为0则减1。
代码:
# BEGIN Problem 7
# The HungryAnt Class
class HungryAnt(Ant):
"""A HungryAnt will select a random Bee from its place and eat it whole"""
name = 'Hungry'
food_cost = 4
implemented = True
chew_duration = 3
def __init__(self, health=1):
super().__init__(health)
self.chewing = 0
def action(self, gameState):
if self.chewing == 0 and self.place.bees[:]:
selected_bee = bee_selector(self.place.bees)
selected_bee.health = 0
selected_bee.reduce_health(0)
self.chewing = self.chew_duration
else:
if self.chewing != 0:
self.chewing -= 1
# END Problem 7
Problem 8 (3 pt)
BodyguardAnt类似PVZ南瓜头,是一种容器类蚂蚁ContainerAnt,套在其他蚂蚁上保护蚂蚁(同一位置)。被蜜蜂攻击时,南瓜头掉血,内部蚂蚁照常行动不掉血。南瓜头被消灭,内部蚂蚁依然留在该位置上(不再被保护)。
Class | Food Cost | Initial Health |
---|---|---|
BodyguardAnt | 4 | 2 |
南瓜头中的蚂蚁存放在南瓜头的contained_ant实例属性中,而The container Ant南瓜头存放在place的蚂蚁实例属性中。
ContainerAnt类:
- contain_ant方法:传入ant设置为南瓜头的contained_ant。
- action方法:内部存在蚂蚁时,调用该蚂蚁的action方法。
- can_contain方法:传入另一只蚂蚁other,在南瓜头内没有蚂蚁(contained_ant为None),且蚂蚁other不是南瓜头(容器类蚂蚁)时,返回True。
def can_contain(self, other):
# BEGIN Problem 8
"*** YOUR CODE HERE ***"
if self.contained_ant is None and not other.is_container():
return True
return False
# END Problem 8
def contain_ant(self, ant):
# BEGIN Problem 8
"*** YOUR CODE HERE ***"
self.contained_ant = ant
# END Problem 8
def action(self, gamestate):
# BEGIN Problem 8
"*** YOUR CODE HERE ***"
if self.contained_ant:
self.contained_ant.action(gamestate)
# END Problem 8
Ant类的add_to方法,允许一个container和一个非container蚂蚁占据同一个位置,规则如下:
- 原蚂蚁可以contain被加入的蚂蚁,原蚂蚁调用contain_ant。
- 被加入的蚂蚁可以contain原蚂蚁,被加入的蚂蚁调用contain_ant,注意修改place.ant。
- 前两条均不满足,触发AssertionError。
def add_to(self, place):
if place.ant is None:
place.ant = self
else:
# BEGIN Problem 8
if place.ant.can_contain(self) and place.ant.contained_ant is None:
place.ant.contain_ant(self)
elif self.is_container() and self.can_contain(place.ant):
self.contain_ant(place.ant)
place.ant = self
else:
assert place.ant is None, 'Two ants in {0}'.format(place)
# END Problem 8
Insect.add_to(self, place)
BodyguardAnt类:
BodyguardAnt.__init__设置ant的初始生命值。
class BodyguardAnt(ContainerAnt):
"""BodyguardAnt provides protection to other Ants."""
name = 'Bodyguard'
food_cost = 4
# OVERRIDE CLASS ATTRIBUTES HERE
# BEGIN Problem 8
implemented = True # Change to True to view in the GUI
def __init__(self, health=2):
super().__init__(health)
# END Problem 8
Problem 9 (1 pt)
TankAnt相当于加强版南瓜头,可以对当前位置的所有蜜蜂造成1点伤害。
Class | Food Cost | Initial Health |
---|---|---|
TankAnt | 6 | 2 |
action在BodyguardAnt的基础上,调用Bee.reduce_health即可。
代码:
# BEGIN Problem 9
# The TankAnt class
class TankAnt(ContainerAnt):
"""TankAnt provides protection to other Ants and make damage to Bees."""
name = 'Tank'
food_cost = 6
damage = 1
implemented = True
def __init__(self, health=2):
super().__init__(health)
def action(self, gamestate):
if self.contained_ant:
self.contained_ant.action(gamestate)
for bee in self.place.bees[:]:
bee.reduce_health(self.damage)
# END Problem 9