CS_61A_ant_类的使用

 

    def reduce_armor(self, amount):
        """Reduce armor by AMOUNT, and remove the FireAnt from its place if it
        has no armor remaining.

        Make sure to damage each bee in the current place, and apply the bonus
        if the fire ant dies.
        """
        # BEGIN Problem 5
        "*** YOUR CODE HERE ***"
        def reflected_damage(amount):
            remaining_bees = []
            #for bee in self.place.bees:
                #if bee.armor > amount:
                    #remaining_bees.append(bee)# 好像这三行也不需要
            for bee in self.place.bees.copy():
                Insect.reduce_armor(bee,amount)
            #self.place.bees = remaining_bees 不需要
        reflected_damage(amount)
        print("DEBUG: remaining bees armor",[bee.armor for bee in self.place.bees])
        if self.armor <= amount:
            reflected_damage(self.damage)
            print("DEBUG: remaining bees armor",[bee.armor for bee in self.place.bees])
        Ant.reduce_armor(self,amount)

 

我的困难就是不知道如何使用Insect的reduce_armor,以下是Insect中,reduce_armor的定义,可以看到,有两个参数,其中的self 是自动引用。emm其实也就是一个属于Insect类的,有两个参数的函数,只不过他在这个类中代入的self。

以及,如何在改变list 内容的时候,继续进行迭代。他的方法是创建副本,[ self.place.bees.copy() ] 进行迭代,因为我只要用到里面的bee就行了,就相当于一个普通的list,我只需要里面的数字就行了。

 

【这个时候就是要注意到,bees是一个列表,但是里面存储的是bee这个对象,而不是一个数字,所以可以直接使用Insect.reduce_armor(bee,amount),最后再更改self.place.bees】

 

可以注意到,这个函数中没有使用remove_from这个函数,是在使用reduce_armor的时候自动调用,所以如果我继续在函数中使用reduce_armor,就会产生对象不存在的问题。

    def reduce_armor(self, amount):
        """Reduce armor by AMOUNT, and remove the insect from its place if it
        has no armor remaining.

        >>> test_insect = Insect(5)
        >>> test_insect.reduce_armor(2)
        >>> test_insect.armor
        3
        """
        self.armor -= amount
        if self.armor <= 0:
            self.place.remove_insect(self)
            self.death_callback()

 

 1 class A:
 2     def ping(self):
 3         print('ping',self)
 4         
 5 class B(A):
 6     def pong(self):
 7         print('pong',self)
 8     
 9 class C(A):
10     def pong(self):
11         print("PONG",self)
12 
13 class D(B,C):
14 
15     def ping(self):
16         super().ping()
17         print('post-ping:',self)
18 
19     def pngpong(self):
20         self.ping()
21         super().ping() # A.ping()
22         self.pong() # B.pong()
23         super().pong() # B.pong()
24         C.pong(self) # C.pong()

以上是多态的调用顺序,按照申明的顺序使用

进一步,关于class attribute and instance attribute,class attribute 的声明,是在类中定义的,而不是在函数内部定义。instance attribute 是在initiate function——[ def __init__(self, ...] 中定义的,class attribute是所有对象所共有的,而instance是单个对象独有的,与其他对象独立。

并且如果是class attribute ,在子类中也是class attribute,重载这个class attribute只需要在类中说明一下就行了,不需要在 initial function中说明,而如果是instance attribute,则子类必须要在initial function中声明,例子: armor and food_cost

class Ant(Insect):
    """An Ant occupies a place and does work for the colony."""

    implemented = False  # Only implemented Ant classes should be instantiated
    food_cost = 0
    # ADD CLASS ATTRIBUTES HERE
    blocks_path  = True

    def __init__(self, armor=1):
        """Create an Ant with an ARMOR quantity."""
        Insect.__init__(self, armor)

class WallAnt(Ant):
    name = "Wall"
    damage = 1
    food_cost = 4 #class  attribute 
    implemented = True
    def __init__(self, armor=4):
        Ant.__init__(self, armor) # armor is instance attribute

 

额外的加分

  1 class Bee(Insect):
  2     """A Bee moves from place to place, following exits and stinging ants."""
  3 
  4     name = "Bee"
  5     damage = 1
  6     # OVERRIDE CLASS ATTRIBUTES HERE
  7     is_watersafe = True
  8 
  9     def __init__(self, armor, place=None):
 10         super().__init__(armor, place)
 11         self.direction = 1
 12         self.already_scared = False
 13 
 14     def sting(self, ant):
 15         """Attack an ANT, reducing its armor by 1."""
 16         ant.reduce_armor(self.damage)
 17 
 18     def move_to(self, place):
 19         """Move from the Bee's current Place to a new PLACE."""
 20         self.place.remove_insect(self)
 21         place.add_insect(self)
 22 
 23     def blocked(self):
 24         """Return True if this Bee cannot advance to the next Place."""
 25         # Phase 4: Special handling for NinjaAnt
 26         # BEGIN Problem 7
 27         # return self.place.ant is not None
 28         if self.place.ant is None or (self.place.ant.blocks_path is False):
 29             return False
 30         else:
 31             return True
 32         # END Problem 7
 33 
 34     def action(self, gamestate):
 35         """A Bee's action stings the Ant that blocks its exit if it is blocked,
 36         or moves to the exit of its current place otherwise.
 37 
 38         gamestate -- The GameState, used to access game state information.
 39         """
 40         destination = self.place.exit
 41         # Extra credit: Special handling for bee direction
 42         # BEGIN EC
 43         "*** YOUR CODE HERE ***"
 44         # if bee's direction is -1,then destination is self.place.entrance
 45         # if self.place.entrance is Hive,then the bee doesn't action
 46         # END EC
 47         if self.direction == -1:
 48             destination = self.place.entrance
 49             if isinstance(destination, Hive):
 50                 destination = self.place
 51 
 52         if self.blocked():
 53             self.sting(self.place.ant)
 54         elif self.armor > 0 and destination is not None:
 55             self.move_to(destination)
 56 
 57     def add_to(self, place):
 58         place.bees.append(self)
 59         Insect.add_to(self, place)
 60 
 61     def remove_from(self, place):
 62         place.bees.remove(self)
 63         Insect.remove_from(self, place)
 64 
 65 
 66 ############
 67 # Statuses #
 68 ############
 69 
 70 
 71 def make_slow(action, bee):
 72     """Return a new action method that calls ACTION every other turn.
 73 
 74     action -- An action method of some Bee
 75     """
 76     # BEGIN Problem EC
 77     "*** YOUR CODE HERE ***"
 78 
 79     def slow_action(gamestate):
 80         if gamestate.time % 2 == 0:
 81             action(gamestate)
 82 
 83     return slow_action
 84     # END Problem EC
 85 
 86 
 87 def make_scare(action, bee):
 88     """Return a new action method that makes the bee go backwards.
 89 
 90     action -- An action method of some Bee
 91     """
 92     # BEGIN Problem EC
 93     "*** YOUR CODE HERE ***"
 94 
 95     def scare_action(gamestate):
 96         # make the bee's direction divert
 97         # then make the bee act ,if already 2 turns ,make the bee's direction turn back 1
 98         bee.direction = -1
 99         action(gamestate)
100         bee.direction = 1
101 
102     return scare_action
103     # END Problem EC
104 
105 
106 def apply_status(status, bee, length):
107     """Apply a status to a BEE that lasts for LENGTH turns."""
108     # BEGIN Problem EC
109     "*** YOUR CODE HERE ***"
110     original_action = bee.action
111     new_action = status(bee.action, bee)
112 
113     def alt_action(gamestate):
114         nonlocal length
115         if length > 0:
116             new_action(gamestate)
117             length -= 1
118         else:
119             original_action(gamestate)
120 
121     bee.action = alt_action
122     # END Problem EC
123 
124 
125 class SlowThrower(ThrowerAnt):
126     """ThrowerAnt that causes Slow on Bees."""
127 
128     name = "Slow"
129     food_cost = 4
130     # BEGIN Problem EC
131     implemented = True  # Change to True to view in the GUI
132     # END Problem EC
133 
134     def throw_at(self, target):
135         if target:
136             apply_status(make_slow, target, 3)
137 
138 
139 class ScaryThrower(ThrowerAnt):
140     """ThrowerAnt that intimidates Bees, making them back away instead of advancing."""
141 
142     name = "Scary"
143     food_cost = 6
144     # BEGIN Problem EC
145     implemented = True  # Change to True to view in the GUI
146     # END Problem EC
147 
148     def throw_at(self, target):
149         # BEGIN Problem EC
150         "*** YOUR CODE HERE ***"
151         # if the target bee is not be scare ,then it is true
152         # then call the apply_status method
153         if target.already_scared is False:
154             apply_status(make_scare, target, 2)
155             target.already_scared = True
156         # END Problem EC

apply_status 可以好好看看

posted @ 2023-04-14 15:38  哎呦_不想学习哟~  阅读(129)  评论(0)    收藏  举报