[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 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 = 'Ant'
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