📣 4th of July限时特惠: VIP通行证立减$68
楼主: lilirr
跳转到指定楼层
上一主题 下一主题
收起左侧

专门开一个帖分享cs61a的答案

 
🔗
 楼主| lilirr 2019-8-19 10:26:03 | 只看该作者
全局:
ants project

  1. """CS 61A presents Ants Vs. SomeBees."""

  2. import random
  3. from ucb import main, interact, trace
  4. from collections import OrderedDict

  5. ################
  6. # Core Classes #
  7. ################

  8. class Place(object):
  9.     """A Place holds insects and has an exit to another Place."""

  10.     def __init__(self, name, exit=None):
  11.         """Create a Place with the given NAME and EXIT.

  12.         name -- A string; the name of this Place.
  13.         exit -- The Place reached by exiting this Place (may be None).
  14.         """
  15.         self.name = name
  16.         self.exit = exit
  17.         self.bees = []        # A list of Bees
  18.         self.ant = None       # An Ant
  19.         self.entrance = None  # A Place
  20.         # Phase 1: Add an entrance to the exit
  21.         # BEGIN Problem 2
  22.         "*** YOUR CODE HERE ***"
  23.         if self.exit:
  24.             self.exit.entrance = self
  25.         # END Problem 2

  26.     def add_insect(self, insect):
  27.         """Add an INSECT to this Place.

  28.         There can be at most one Ant in a Place, unless exactly one of them is
  29.         a BodyguardAnt (Phase 6), in which case there can be two. If add_insect
  30.         tries to add more Ants than is allowed, an assertion error is raised.

  31.         There can be any number of Bees in a Place.
  32.         """
  33.         if insect.is_ant:
  34.             if self.ant is None:
  35.                 self.ant = insect
  36.             else:
  37.                 # BEGIN Problem 9
  38.                 if self.ant.can_contain(insect):
  39.                     self.ant.ant = insect
  40.                 elif insect.can_contain(self.ant):
  41.                     self.ant,self.ant.ant = insect,self.ant
  42.                 else:
  43.                     assert self.ant is None, 'Two ants in {0}'.format(self)
  44.                 # END Problem 9
  45.         else:
  46.             self.bees.append(insect)
  47.         insect.place = self

  48.     def remove_insect(self, insect):
  49.         """Remove an INSECT from this Place.

  50.         A target Ant may either be directly in the Place, or be contained by a
  51.         container Ant at this place. The true QueenAnt may not be removed. If
  52.         remove_insect tries to remove an Ant that is not anywhere in this
  53.         Place, an AssertionError is raised.

  54.         A Bee is just removed from the list of Bees.
  55.         """
  56.         if insect.is_ant:
  57.             # Special handling for QueenAnt
  58.             # BEGIN Problem 13
  59.             "*** YOUR CODE HERE ***"
  60.             #什么都不做直接写return 就好
  61.             if isinstance(insect,QueenAnt):#ant位置上是queen
  62.                 if insect.firstqueen:
  63.                     return
  64.             # END Problem 13

  65.             # Special handling for BodyguardAnt
  66.             if self.ant is insect:
  67.                 if hasattr(self.ant, 'container') and self.ant.container:
  68.                     self.ant = self.ant.ant
  69.                 else:
  70.                     self.ant = None
  71.             else:
  72.                 if hasattr(self.ant, 'container') and self.ant.container and self.ant.ant is insect:
  73.                     self.ant.ant = None
  74.                 else:
  75.                     assert False, '{0} is not in {1}'.format(insect, self)
  76.         else:
  77.             self.bees.remove(insect)

  78.         insect.place = None

  79.     def __str__(self):
  80.         return self.name


  81. class Insect(object):
  82.     """An Insect, the base class of Ant and Bee, has armor and a Place."""

  83.     is_ant = False
  84.     damage = 0
  85.     watersafe = False

  86.     def __init__(self, armor, place=None):
  87.         """Create an Insect with an ARMOR amount and a starting PLACE."""
  88.         self.armor = armor
  89.         self.place = place  # set by Place.add_insect and Place.remove_insect

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

  93.         >>> test_insect = Insect(5)
  94.         >>> test_insect.reduce_armor(2)
  95.         >>> test_insect.armor
  96.         3
  97.         """
  98.         self.armor -= amount
  99.         if self.armor <= 0:
  100.             self.place.remove_insect(self)

  101.     def action(self, colony):
  102.         """The action performed each turn.

  103.         colony -- The AntColony, used to access game state information.
  104.         """

  105.     def __repr__(self):
  106.         cname = type(self).__name__
  107.         return '{0}({1}, {2})'.format(cname, self.armor, self.place)


  108. class Bee(Insect):
  109.     """A Bee moves from place to place, following exits and stinging ants."""

  110.     name = 'Bee'
  111.     damage = 1
  112.     watersafe = True

  113.     def sting(self, ant):
  114.         """Attack an ANT, reducing its armor by 1."""
  115.         ant.reduce_armor(self.damage)

  116.     def move_to(self, place):
  117.         """Move from the Bee's current Place to a new PLACE."""
  118.         self.place.remove_insect(self)
  119.         place.add_insect(self)

  120.     def blocked(self):
  121.         """Return True if this Bee cannot advance to the next Place."""
  122.         # Phase 4: Special handling for NinjaAnt
  123.         # BEGIN Problem 7
  124.         return self.place.ant is not None and self.place.ant.blocks_path
  125.         # END Problem 7

  126.     def action(self, colony):
  127.         """A Bee's action stings the Ant that blocks its exit if it is blocked,
  128.         or moves to the exit of its current place otherwise.

  129.         colony -- The AntColony, used to access game state information.
  130.         """
  131.         if self.blocked():
  132.             self.sting(self.place.ant)
  133.         elif self.armor > 0 and self.place.exit is not None:
  134.             self.move_to(self.place.exit)


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

  137.     is_ant = True
  138.     implemented = False  # Only implemented Ant classes should be instantiated
  139.     food_cost = 0
  140.     blocks_path = True
  141.     container = False
  142.     def __init__(self, armor=1):
  143.         """Create an Ant with an ARMOR quantity."""
  144.         Insect.__init__(self, armor)
  145.         
  146.     def can_contain(self, other):
  147.         # BEGIN Problem 9
  148.         "*** YOUR CODE HERE ***"
  149.         if self.container and not other.container and not self.ant:
  150.             return True
  151.         # END Problem 9


  152. class HarvesterAnt(Ant):
  153.     """HarvesterAnt produces 1 additional food per turn for the colony."""

  154.     name = 'Harvester'
  155.     implemented = True
  156.     food_cost = 2
  157.     def action(self, colony):
  158.         """Produce 1 additional food for the COLONY.

  159.         colony -- The AntColony, used to access game state information.
  160.         """
  161.         # BEGIN Problem 1
  162.         "*** YOUR CODE HERE ***"
  163.         colony.food += 1
  164.         # END Problem 1


  165. class ThrowerAnt(Ant):
  166.     """ThrowerAnt throws a leaf each turn at the nearest Bee in its range."""

  167.     name = 'Thrower'
  168.     implemented = True
  169.     damage = 1
  170.     food_cost = 3
  171.     min_range = 0
  172.     max_range = float('inf')
  173.     def nearest_bee(self, hive):
  174.         """Return the nearest Bee in a Place that is not the HIVE, connected to
  175.         the ThrowerAnt's Place by following entrances.

  176.         This method returns None if there is no such Bee (or none in range).
  177.         """
  178.         # BEGIN Problem 3 and 4
  179.         #好好复习和梳理这道题的逻辑,卡了我很久... = =
  180.         Beerange = 0
  181.         Beeplace = self.place
  182.         while Beerange < self.min_range:
  183.             Beeplace = Beeplace.entrance
  184.             Beerange += 1
  185.         while not Beeplace.bees and Beeplace != hive: #第一个有bee的place并且不是hive
  186.             Beeplace = Beeplace.entrance
  187.             Beerange += 1
  188.         if Beerange > self.max_range or Beeplace == hive:
  189.             return None
  190.         elif Beerange >= self.min_range and Beerange <= self.max_range: #在满足了有bee的要求以后
  191.             return random_or_none(Beeplace.bees)
  192.         else:
  193.             return None

  194.         # END Problem 3 and 4

  195.     def throw_at(self, target):
  196.         """Throw a leaf at the TARGET Bee, reducing its armor."""
  197.         if target is not None:
  198.             target.reduce_armor(self.damage)

  199.     def action(self, colony):
  200.         """Throw a leaf at the nearest Bee in range."""
  201.         self.throw_at(self.nearest_bee(colony.hive))

  202. def random_or_none(s):
  203.     """Return a random element of sequence S, or return None if S is empty."""
  204.     if s:
  205.         return random.choice(s)


  206. ##############
  207. # Extensions #
  208. ##############

  209. class Water(Place):
  210.     """Water is a place that can only hold 'watersafe' insects."""

  211.     def add_insect(self, insect):
  212.         """Add INSECT if it is watersafe, otherwise reduce its armor to 0."""
  213.         # BEGIN Problem 11
  214.         "*** YOUR CODE HERE ***"
  215.         Place.add_insect(self,insect)
  216.         if not insect.watersafe:
  217.             insect.reduce_armor(insect.armor)
  218.         # END Problem 11


  219. class FireAnt(Ant):
  220.     """FireAnt cooks any Bee in its Place when it expires."""

  221.     name = 'Fire'
  222.     damage = 3
  223.     # BEGIN Problem 5
  224.     implemented = True   # Change to True to view in the GUI
  225.     food_cost = 5
  226.     armor = 1
  227.     # END Problem 5

  228.     def reduce_armor(self, amount):
  229.         """Reduce armor by AMOUNT, and remove the FireAnt from its place if it
  230.         has no armor remaining. If the FireAnt dies, damage each of the bees in
  231.         the current place.
  232.         """
  233.         # BEGIN Problem 5
  234.         "*** YOUR CODE HERE ***"
  235.         self.armor -= amount
  236.         if not self.armor:
  237.             beels = self.place.bees[:]
  238.             for bee in beels:
  239.                 bee.armor -= self.damage
  240.                 if not bee.armor:
  241.                     self.place.bees.remove(bee)
  242.             self.place.ant = None
  243.         # END Problem 5


  244. class LongThrower(ThrowerAnt):
  245.     """A ThrowerAnt that only throws leaves at Bees at least 5 places away."""

  246.     name = 'Long'
  247.     # BEGIN Problem 4
  248.     implemented = True # Change to True to view in the GUI
  249.     food_cost = 2
  250.     min_range = 5
  251.     max_range = float('inf')
  252.     # END Problem 4


  253. class ShortThrower(ThrowerAnt):
  254.     """A ThrowerAnt that only throws leaves at Bees at most 3 places away."""

  255.     name = 'Short'
  256.     # BEGIN Problem 4
  257.     implemented = True # Change to True to view in the GUI
  258.     food_cost = 2
  259.     max_range = 3
  260.     min_range = 0
  261.     # END Problem 4


  262. # BEGIN Problem 8
  263. # The WallAnt class
  264. class WallAnt(Ant):
  265.     name = 'Wall'
  266.     implemented = True
  267.     food_cost = 4
  268.     armor = 4
  269.     def __init__(self, armor=4):
  270.         Insect.__init__(self,armor)
  271.         
  272. # END Problem 8


  273. class NinjaAnt(Ant):
  274.     """NinjaAnt does not block the path and damages all bees in its place."""

  275.     name = 'Ninja'
  276.     damage = 1
  277.     # BEGIN Problem 7
  278.     implemented = True   # Change to True to view in the GUI
  279.     blocks_path = False
  280.     food_cost = 5
  281.     # END Problem 7

  282.     def action(self, colony):
  283.         # BEGIN Problem 7
  284.         "*** YOUR CODE HERE ***"
  285.         for bee in self.place.bees[:]:
  286.             bee.armor -= self.damage
  287.             if bee.armor <= 0:
  288.                 self.place.bees.remove(bee)
  289.         # END Problem 7


  290. # BEGIN Problem 12
  291. # The ScubaThrower class
  292. class ScubaThrower(ThrowerAnt):
  293.     food_cost = 6
  294.     armor = 1
  295.     name = 'Scuba'
  296.     implemented = True
  297.     watersafe = True
  298. # END Problem 12


  299. class HungryAnt(Ant):
  300.     """HungryAnt will take three turns to digest a Bee in its place.
  301.     While digesting, the HungryAnt can't eat another Bee.
  302.     """
  303.     name = 'Hungry'
  304.     # BEGIN Problem 6
  305.     implemented = True   # Change to True to view in the GUI
  306.     food_cost = 4
  307.     armor = 1
  308.     left_time = 0
  309.     # END Problem 6
  310.     def __init__(self):
  311.         # BEGIN Problem 6
  312.         "*** YOUR CODE HERE ***"
  313.         self.time_to_digest = 3
  314.         self.digesting = 0

  315.         # END Problem 6

  316.     def eat_bee(self, bee):
  317.         # BEGIN Problem 6
  318.         "*** YOUR CODE HERE ***"
  319.         if bee:
  320.             self.digesting = 1
  321.             bee.armor = 0
  322.             self.place.bees.remove(bee)
  323.             self.left_time = self.time_to_digest
  324.         # END Problem 6

  325.     def action(self, colony):
  326.         # BEGIN Problem 6
  327.         "*** YOUR CODE HERE ***"
  328.         #注意这个if的层次,最后一个if必须执行

  329.         if self.digesting == 0:
  330.             self.eat_bee(random_or_none(self.place.bees))
  331.         elif self.digesting:
  332.             self.left_time -= 1
  333.         if self.left_time == 0:
  334.             self.digesting = 0
  335.             self.left_time = self.time_to_digest
  336.         # END Problem 6


  337. class BodyguardAnt(Ant):
  338.     """BodyguardAnt provides protection to other Ants."""
  339.     name = 'Bodyguard'
  340.     # BEGIN Problem 9                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
  341.     implemented = True   # Change to True to view in the GUI
  342.     container = True
  343.     food_cost = 4
  344.     armor = 2
  345.     # END Problem 9

  346.     def __init__(self):
  347.         Ant.__init__(self, 2)
  348.         self.ant = None  # The Ant hidden in this bodyguard

  349.     def contain_ant(self, ant):
  350.         # BEGIN Problem 9
  351.         "*** YOUR CODE HERE ***"
  352.         self.ant = ant
  353.         # END Problem 9

  354.     def action(self, colony):
  355.         # BEGIN Problem 9
  356.         "*** YOUR CODE HERE ***"
  357.         if self.ant:
  358.             self.place.ant = self
  359.             return self.ant.action(colony)
  360.         # END Problem 9

  361. class TankAnt(BodyguardAnt):
  362.     """TankAnt provides both offensive and defensive capabilities."""
  363.     name = 'Tank'
  364.     damage = 1
  365.     # BEGIN Problem 10
  366.     implemented = True  # Change to True to view in the GUI
  367.     food_cost = 6
  368.     armor = 2
  369.     # END Problem 10

  370.     def action(self, colony):
  371.         # BEGIN Problem 10
  372.         "*** YOUR CODE HERE ***"
  373.         if self.damage:
  374.             for bee in self.place.bees[:]:
  375.                 bee.reduce_armor(self.damage)
  376.         BodyguardAnt.action(self,colony)
  377.         # END Problem 10

  378. # BEGIN Problem 13
  379. class QueenAnt(ScubaThrower):  # You should change this line
  380. # END Problem 13
  381.     """The Queen of the colony. The game is over if a bee enters her place."""

  382.     name = 'Queen'
  383.     # BEGIN Problem 13
  384.     implemented = True   # Change to True to view in the GUI
  385.     food_cost = 7
  386.     armor = 1
  387.     firstqueen = True
  388.     doubled_ls = []
  389.     container = False
  390.     # END Problem 13

  391.     def __init__(self):
  392.         # BEGIN Problem 13
  393.         "*** YOUR CODE HERE ***"
  394.         ScubaThrower.__init__(self)
  395.         self.firstqueen = QueenAnt.firstqueen
  396.         QueenAnt.firstqueen = False
  397.         # END Problem 13

  398.     def action(self, colony):
  399.         """A queen ant throws a leaf, but also doubles the damage of ants
  400.         in her tunnel.

  401.         Impostor queens do only one thing: reduce their own armor to 0.
  402.         """
  403.         # BEGIN Problem 13
  404.         "*** YOUR CODE HERE ***"
  405.         db_place = self.place.exit
  406.         if self.firstqueen:
  407.             ThrowerAnt.action(self,colony)
  408.             while db_place:#当没有走到tunnel尽头时
  409.                 if db_place.ant:
  410.                     if db_place.exit:
  411.                         if db_place.ant.container:
  412.                             if db_place.ant.ant and not db_place.ant.ant in self.doubled_ls:
  413.                                 db_place.ant.ant.damage *= 2
  414.                                 self.doubled_ls.append(db_place.ant.ant)                           
  415.                         if db_place.ant not in self.doubled_ls:#无论有没有两个ant都要执行
  416.                             db_place.ant.damage *= 2
  417.                             self.doubled_ls.append(db_place.ant)
  418.                     else:#前面有ant且在tunnel尽头
  419.                         bees_win()
  420.                 db_place = db_place.exit
  421.         else:
  422.             self.reduce_armor(self.armor)
  423.         # END Problem 13

  424.     def reduce_armor(self, amount):
  425.         """Reduce armor by AMOUNT, and if the True QueenAnt has no armor
  426.         remaining, signal the end of the game.
  427.         """
  428.         # BEGIN Problem 13
  429.         "*** YOUR CODE HERE ***"
  430.         self.armor -= amount
  431.         if self.firstqueen and self.armor <= 0 :
  432.             self.place.remove_insect(self)
  433.             bees_win()
  434.         else:
  435.             self.place.remove_insect(self)
  436.         # END Problem 13

  437. class AntRemover(Ant):
  438.     """Allows the player to remove ants from the board in the GUI."""

  439.     name = 'Remover'
  440.     implemented = False

  441.     def __init__(self):
  442.         Ant.__init__(self, 0)


  443. ##################
  444. # Status Effects #
  445. ##################

  446. def make_slow(action):
  447.     """Return a new action method that calls ACTION every other turn.

  448.     action -- An action method of some Bee
  449.     """
  450.     # BEGIN Problem EC
  451.     "*** YOUR CODE HERE ***"
  452.     return lambda colony: None if colony.time % 2 else action(colony)
  453.     # END Problem EC

  454. def make_stun(action):
  455.     """Return a new action method that does nothing.

  456.     action -- An action method of some Bee
  457.     """
  458.     # BEGIN Problem EC
  459.     "*** YOUR CODE HERE ***"
  460.     return lambda colony: None
  461.     # END Problem EC

  462. def apply_effect(effect, bee, duration):
  463.     """Apply a status effect to a BEE that lasts for DURATION turns."""
  464.     # BEGIN Problem EC
  465.     "*** YOUR CODE HERE ***"
  466.     original_action = bee.action
  467.     affected_action = effect(bee.action)

  468.     def new_action(colony):
  469.         nonlocal duration
  470.         if duration:
  471.             affected_action(colony)
  472.             duration -= 1
  473.         else:
  474.             original_action(colony)
  475.     bee.action = new_action
  476.    
  477.     # END Problem EC


  478. class SlowThrower(ThrowerAnt):
  479.     """ThrowerAnt that causes Slow on Bees."""

  480.     name = 'Slow'
  481.     # BEGIN Problem EC
  482.     implemented = True   # Change to True to view in the GUI
  483.     food_cost = 4
  484.     armor = 1
  485.     slow_time = 0
  486.     # END Problem EC

  487.     def throw_at(self, target):
  488.         if target:
  489.             apply_effect(make_slow, target, 3)


  490. class StunThrower(ThrowerAnt):
  491.     """ThrowerAnt that causes Stun on Bees."""

  492.     name = 'Stun'
  493.     # BEGIN Problem EC
  494.     implemented = True   # Change to True to view in the GUI
  495.     food_cost = 6
  496.     armor = 1
  497.     # END Problem EC

  498.     def throw_at(self, target):
  499.         if target:
  500.             apply_effect(make_stun, target, 1)


  501. ##################
  502. # Bees Extension #
  503. ##################

  504. class Wasp(Bee):
  505.     """Class of Bee that has higher damage."""
  506.     name = 'Wasp'
  507.     damage = 2

  508. class Hornet(Bee):
  509.     """Class of bee that is capable of taking two actions per turn, although
  510.     its overall damage output is lower. Immune to status effects.
  511.     """
  512.     name = 'Hornet'
  513.     damage = 0.25

  514.     def action(self, colony):
  515.         for i in range(2):
  516.             if self.armor > 0:
  517.                 super().action(colony)

  518.     def __setattr__(self, name, value):
  519.         if name != 'action':
  520.             object.__setattr__(self, name, value)

  521. class NinjaBee(Bee):
  522.     """A Bee that cannot be blocked. Is capable of moving past all defenses to
  523.     assassinate the Queen.
  524.     """
  525.     name = 'NinjaBee'

  526.     def blocked(self):
  527.         return False

  528. class Boss(Wasp, Hornet):
  529.     """The leader of the bees. Combines the high damage of the Wasp along with
  530.     status effect immunity of Hornets. Damage to the boss is capped up to 8
  531.     damage by a single attack.
  532.     """
  533.     name = 'Boss'
  534.     damage_cap = 8
  535.     action = Wasp.action

  536.     def reduce_armor(self, amount):
  537.         super().reduce_armor(self.damage_modifier(amount))

  538.     def damage_modifier(self, amount):
  539.         return amount * self.damage_cap/(self.damage_cap + amount)

  540. class Hive(Place):
  541.     """The Place from which the Bees launch their assault.

  542.     assault_plan -- An AssaultPlan; when & where bees enter the colony.
  543.     """

  544.     def __init__(self, assault_plan):
  545.         self.name = 'Hive'
  546.         self.assault_plan = assault_plan
  547.         self.bees = []
  548.         for bee in assault_plan.all_bees:
  549.             self.add_insect(bee)
  550.         # The following attributes are always None for a Hive
  551.         self.entrance = None
  552.         self.ant = None
  553.         self.exit = None

  554.     def strategy(self, colony):
  555.         exits = [p for p in colony.places.values() if p.entrance is self]
  556.         for bee in self.assault_plan.get(colony.time, []):
  557.             bee.move_to(random.choice(exits))
  558.             colony.active_bees.append(bee)


  559. class AntColony(object):
  560.     """An ant collective that manages global game state and simulates time.

  561.     Attributes:
  562.     time -- elapsed time
  563.     food -- the colony's available food total
  564.     queen -- the place where the queen resides
  565.     places -- A list of all places in the colony (including a Hive)
  566.     bee_entrances -- A list of places that bees can enter
  567.     """

  568.     def __init__(self, strategy, hive, ant_types, create_places, dimensions, food=2):
  569.         """Create an AntColony for simulating a game.

  570.         Arguments:
  571.         strategy -- a function to deploy ants to places
  572.         hive -- a Hive full of bees
  573.         ant_types -- a list of ant constructors
  574.         create_places -- a function that creates the set of places
  575.         dimensions -- a pair containing the dimensions of the game layout
  576.         """
  577.         self.time = 0
  578.         self.food = food
  579.         self.strategy = strategy
  580.         self.hive = hive
  581.         self.ant_types = OrderedDict((a.name, a) for a in ant_types)
  582.         self.dimensions = dimensions
  583.         self.active_bees = []
  584.         self.configure(hive, create_places)

  585.     def configure(self, hive, create_places):
  586.         """Configure the places in the colony."""
  587.         self.queen = QueenPlace('AntQueen')
  588.         self.places = OrderedDict()
  589.         self.bee_entrances = []
  590.         def register_place(place, is_bee_entrance):
  591.             self.places[place.name] = place
  592.             if is_bee_entrance:
  593.                 place.entrance = hive
  594.                 self.bee_entrances.append(place)
  595.         register_place(self.hive, False)
  596.         create_places(self.queen, register_place, self.dimensions[0], self.dimensions[1])

  597.     def simulate(self):
  598.         """Simulate an attack on the ant colony (i.e., play the game)."""
  599.         num_bees = len(self.bees)
  600.         try:
  601.             while True:
  602.                 self.hive.strategy(self)            # Bees invade
  603.                 self.strategy(self)                 # Ants deploy
  604.                 for ant in self.ants:               # Ants take actions
  605.                     if ant.armor > 0:
  606.                         ant.action(self)
  607.                 for bee in self.active_bees[:]:     # Bees take actions
  608.                     if bee.armor > 0:
  609.                         bee.action(self)
  610.                     if bee.armor <= 0:
  611.                         num_bees -= 1
  612.                         self.active_bees.remove(bee)
  613.                 if num_bees == 0:
  614.                     raise AntsWinException()
  615.                 self.time += 1
  616.         except AntsWinException:
  617.             print('All bees are vanquished. You win!')
  618.             return True
  619.         except BeesWinException:
  620.             print('The ant queen has perished. Please try again.')
  621.             return False

  622.     def deploy_ant(self, place_name, ant_type_name):
  623.         """Place an ant if enough food is available.

  624.         This method is called by the current strategy to deploy ants.
  625.         """
  626.         constructor = self.ant_types[ant_type_name]
  627.         if self.food < constructor.food_cost:
  628.             print('Not enough food remains to place ' + ant_type_name)
  629.         else:
  630.             ant = constructor()
  631.             self.places[place_name].add_insect(ant)
  632.             self.food -= constructor.food_cost
  633.             return ant

  634.     def remove_ant(self, place_name):
  635.         """Remove an Ant from the Colony."""
  636.         place = self.places[place_name]
  637.         if place.ant is not None:
  638.             place.remove_insect(place.ant)

  639.     @property
  640.     def ants(self):
  641.         return [p.ant for p in self.places.values() if p.ant is not None]

  642.     @property
  643.     def bees(self):
  644.         return [b for p in self.places.values() for b in p.bees]

  645.     @property
  646.     def insects(self):
  647.         return self.ants + self.bees

  648.     def __str__(self):
  649.         status = ' (Food: {0}, Time: {1})'.format(self.food, self.time)
  650.         return str([str(i) for i in self.ants + self.bees]) + status

  651. class QueenPlace(Place):
  652.     """QueenPlace at the end of the tunnel, where the queen resides."""

  653.     def add_insect(self, insect):
  654.         """Add an Insect to this Place.

  655.         Can't actually add Ants to a QueenPlace. However, if a Bee attempts to
  656.         enter the QueenPlace, a BeesWinException is raised, signaling the end
  657.         of a game.
  658.         """
  659.         assert not insect.is_ant, 'Cannot add {0} to QueenPlace'
  660.         raise BeesWinException()

  661. def ants_win():
  662.     """Signal that Ants win."""
  663.     raise AntsWinException()

  664. def bees_win():
  665.     """Signal that Bees win."""
  666.     raise BeesWinException()

  667. def ant_types():
  668.     """Return a list of all implemented Ant classes."""
  669.     all_ant_types = []
  670.     new_types = [Ant]
  671.     while new_types:
  672.         new_types = [t for c in new_types for t in c.__subclasses__()]
  673.         all_ant_types.extend(new_types)
  674.     return [t for t in all_ant_types if t.implemented]

  675. class GameOverException(Exception):
  676.     """Base game over Exception."""
  677.     pass

  678. class AntsWinException(GameOverException):
  679.     """Exception to signal that the ants win."""
  680.     pass

  681. class BeesWinException(GameOverException):
  682.     """Exception to signal that the bees win."""
  683.     pass

  684. def interactive_strategy(colony):
  685.     """A strategy that starts an interactive session and lets the user make
  686.     changes to the colony.

  687.     For example, one might deploy a ThrowerAnt to the first tunnel by invoking
  688.     colony.deploy_ant('tunnel_0_0', 'Thrower')
  689.     """
  690.     print('colony: ' + str(colony))
  691.     msg = '<Control>-D (<Control>-Z <Enter> on Windows) completes a turn.\n'
  692.     interact(msg)

  693. def start_with_strategy(args, strategy):
  694.     """Reads command-line arguments and starts a game with those options."""
  695.     import argparse
  696.     parser = argparse.ArgumentParser(description="Play Ants vs. SomeBees")
  697.     parser.add_argument('-d', type=str, metavar='DIFFICULTY',
  698.                         help='sets difficulty of game (test/easy/medium/hard/insane)')
  699.     parser.add_argument('-w', '--water', action='store_true',
  700.                         help='loads a full layout with water')
  701.     parser.add_argument('--food', type=int,
  702.                         help='number of food to start with when testing', default=2)
  703.     args = parser.parse_args()

  704.     assault_plan = make_normal_assault_plan()
  705.     layout = dry_layout
  706.     tunnel_length = 9
  707.     num_tunnels = 3
  708.     food = args.food

  709.     if args.water:
  710.         layout = wet_layout
  711.     if args.d in ['t', 'test']:
  712.         assault_plan = make_test_assault_plan()
  713.         num_tunnels = 1
  714.     elif args.d in ['e', 'easy']:
  715.         assault_plan = make_easy_assault_plan()
  716.         num_tunnels = 2
  717.     elif args.d in ['n', 'normal']:
  718.         assault_plan = make_normal_assault_plan()
  719.         num_tunnels = 3
  720.     elif args.d in ['h', 'hard']:
  721.         assault_plan = make_hard_assault_plan()
  722.         num_tunnels = 4
  723.     elif args.d in ['i', 'insane']:
  724.         assault_plan = make_insane_assault_plan()
  725.         num_tunnels = 4

  726.     hive = Hive(assault_plan)
  727.     dimensions = (num_tunnels, tunnel_length)
  728.     return AntColony(strategy, hive, ant_types(), layout, dimensions, food).simulate()


  729. ###########
  730. # Layouts #
  731. ###########

  732. def wet_layout(queen, register_place, tunnels=3, length=9, moat_frequency=3):
  733.     """Register a mix of wet and and dry places."""
  734.     for tunnel in range(tunnels):
  735.         exit = queen
  736.         for step in range(length):
  737.             if moat_frequency != 0 and (step + 1) % moat_frequency == 0:
  738.                 exit = Water('water_{0}_{1}'.format(tunnel, step), exit)
  739.             else:
  740.                 exit = Place('tunnel_{0}_{1}'.format(tunnel, step), exit)
  741.             register_place(exit, step == length - 1)

  742. def dry_layout(queen, register_place, tunnels=3, length=9):
  743.     """Register dry tunnels."""
  744.     wet_layout(queen, register_place, tunnels, length, 0)


  745. #################
  746. # Assault Plans #
  747. #################

  748. class AssaultPlan(dict):
  749.     """The Bees' plan of attack for the Colony.  Attacks come in timed waves.

  750.     An AssaultPlan is a dictionary from times (int) to waves (list of Bees).

  751.     >>> AssaultPlan().add_wave(4, 2)
  752.     {4: [Bee(3, None), Bee(3, None)]}
  753.     """

  754.     def add_wave(self, bee_type, bee_armor, time, count):
  755.         """Add a wave at time with count Bees that have the specified armor."""
  756.         bees = [bee_type(bee_armor) for _ in range(count)]
  757.         self.setdefault(time, []).extend(bees)
  758.         return self

  759.     @property
  760.     def all_bees(self):
  761.         """Place all Bees in the hive and return the list of Bees."""
  762.         return [bee for wave in self.values() for bee in wave]

  763. def make_test_assault_plan():
  764.     return AssaultPlan().add_wave(Bee, 3, 2, 1).add_wave(Bee, 3, 3, 1)

  765. def make_easy_assault_plan():
  766.     plan = AssaultPlan()
  767.     for time in range(3, 16, 2):
  768.         plan.add_wave(Bee, 3, time, 1)
  769.     plan.add_wave(Wasp, 3, 4, 1)
  770.     plan.add_wave(NinjaBee, 3, 8, 1)
  771.     plan.add_wave(Hornet, 3, 12, 1)
  772.     plan.add_wave(Boss, 15, 16, 1)
  773.     return plan

  774. def make_normal_assault_plan():
  775.     plan = AssaultPlan()
  776.     for time in range(3, 16, 2):
  777.         plan.add_wave(Bee, 3, time, 2)
  778.     plan.add_wave(Wasp, 3, 4, 1)
  779.     plan.add_wave(NinjaBee, 3, 8, 1)
  780.     plan.add_wave(Hornet, 3, 12, 1)
  781.     plan.add_wave(Wasp, 3, 16, 1)

  782.     #Boss Stage
  783.     for time in range(21, 30, 2):
  784.         plan.add_wave(Bee, 3, time, 2)
  785.     plan.add_wave(Wasp, 3, 22, 2)
  786.     plan.add_wave(Hornet, 3, 24, 2)
  787.     plan.add_wave(NinjaBee, 3, 26, 2)
  788.     plan.add_wave(Hornet, 3, 28, 2)
  789.     plan.add_wave(Boss, 20, 30, 1)
  790.     return plan

  791. def make_hard_assault_plan():
  792.     plan = AssaultPlan()
  793.     for time in range(3, 16, 2):
  794.         plan.add_wave(Bee, 4, time, 2)
  795.     plan.add_wave(Hornet, 4, 4, 2)
  796.     plan.add_wave(Wasp, 4, 8, 2)
  797.     plan.add_wave(NinjaBee, 4, 12, 2)
  798.     plan.add_wave(Wasp, 4, 16, 2)

  799.     #Boss Stage
  800.     for time in range(21, 30, 2):
  801.         plan.add_wave(Bee, 4, time, 3)
  802.     plan.add_wave(Wasp, 4, 22, 2)
  803.     plan.add_wave(Hornet, 4, 24, 2)
  804.     plan.add_wave(NinjaBee, 4, 26, 2)
  805.     plan.add_wave(Hornet, 4, 28, 2)
  806.     plan.add_wave(Boss, 30, 30, 1)
  807.     return plan

  808. def make_insane_assault_plan():
  809.     plan = AssaultPlan()
  810.     plan.add_wave(Hornet, 5, 2, 2)
  811.     for time in range(3, 16, 2):
  812.         plan.add_wave(Bee, 5, time, 2)
  813.     plan.add_wave(Hornet, 5, 4, 2)
  814.     plan.add_wave(Wasp, 5, 8, 2)
  815.     plan.add_wave(NinjaBee, 5, 12, 2)
  816.     plan.add_wave(Wasp, 5, 16, 2)

  817.     #Boss Stage
  818.     for time in range(21, 30, 2):
  819.         plan.add_wave(Bee, 5, time, 3)
  820.     plan.add_wave(Wasp, 5, 22, 2)
  821.     plan.add_wave(Hornet, 5, 24, 2)
  822.     plan.add_wave(NinjaBee, 5, 26, 2)
  823.     plan.add_wave(Hornet, 5, 28, 2)
  824.     plan.add_wave(Boss, 30, 30, 2)
  825.     return plan


  826. from utils import *
  827. @main
  828. def run(*args):
  829.     Insect.reduce_armor = class_method_wrapper(Insect.reduce_armor,
  830.             pre=print_expired_insects)
  831.     start_with_strategy(args, interactive_strategy)
复制代码
回复

使用道具 举报

全局:

谢谢分享,也遇到这问题。。。
回复

使用道具 举报

本楼:
全局:
谢谢分享!
回复

使用道具 举报

🔗
heyleejoe 2020-10-28 06:27:30 | 只看该作者
全局:
lilirr 发表于 2019-7-15 11:00
lab02

[mw_shl_code=python,true]"""Lab 2: Lambda Expressions and Higher Order Functions"""

没有冒犯的意思,但觉得这题还是用 return lambda x:lambda y:func(x,y) 比较符合题意!
谢谢楼主分享!
回复

使用道具 举报

🔗
xiangyamang 2021-1-17 12:58:14 | 只看该作者
全局:
谢谢lz!好人一生平安
回复

使用道具 举报

🔗
方解石 2021-2-24 16:46:35 | 只看该作者
全局:
smoothiethu 发表于 2019-7-27 11:19
谢谢!虽然我还是没找到test的答案= =

你找到了吗。。。这个line1 到底要填啥啊。。。
回复

使用道具 举报

全局:
谢谢分享!!!mark!!!
回复

使用道具 举报

全局:
smoothiethu 发表于 2019-7-24 18:09
请问这个hog的problem6 的OK测试1的line1 应该是是什么啊一直过不去

(line 1)? 3 0
(line 2)? 3 3
(line 3)? 3 6
回复

使用道具 举报

🔗
向日葵wyu 2022-5-14 21:53:03 | 只看该作者
全局:
不错的楼主 继续加油
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表