"""CS 61A presents Ants Vs. SomeBees."""import random
from ucb import main, interact, trace
from collections import OrderedDict
################# Core Classes #################classPlace:"""A Place holds insects and has an exit to another Place."""def__init__(self, name, exit=None):"""Create a Place with the given NAME and EXIT.
name -- A string; the name of this Place.
exit -- The Place reached by exiting this Place (may be None).
"""
self.name = name
self.exit = exit
self.bees =[]# A list of Bees
self.ant =None# An Ant
self.entrance =None# A Place# Phase 1: Add an entrance to the exit# BEGIN Problem 2"*** YOUR CODE HERE ***"if self.exit !=None:
exit.entrance = self
# END Problem 2defadd_insect(self, insect):"""
Asks the insect to add itself to the current place. This method exists so
it can be enhanced in subclasses.
"""
insect.add_to(self)defremove_insect(self, insect):"""
Asks the insect to remove itself from the current place. This method exists so
it can be enhanced in subclasses.
"""
insect.remove_from(self)def__str__(self):return self.name
classInsect:"""An Insect, the base class of Ant and Bee, has armor and a Place."""
damage =0
is_watersafe =False# ADD CLASS ATTRIBUTES HEREdef__init__(self, armor, place=None):"""Create an Insect with an ARMOR amount and a starting PLACE."""
self.armor = armor
self.place = place # set by Place.add_insect and Place.remove_insectdefreduce_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()defaction(self, gamestate):"""The action performed each turn.
gamestate -- The GameState, used to access game state information.
"""defdeath_callback(self):# overriden by the guipassdefadd_to(self, place):"""Add this Insect to the given Place
By default just sets the place attribute, but this should be overriden in the subclasses
to manipulate the relevant attributes of Place
"""
self.place = place
defremove_from(self, place):
self.place =Nonedef__repr__(self):
cname =type(self).__name__
return'{0}({1}, {2})'.format(cname, self.armor, self.place)classAnt(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 HEREdef__init__(self, armor=1):"""Create an Ant with an ARMOR quantity."""
Insect.__init__(self, armor)defcan_contain(self, other):returnFalsedefcontain_ant(self, other):assertFalse,"{0} cannot contain an ant".format(self)defremove_ant(self, other):assertFalse,"{0} cannot contain an ant".format(self)defadd_to(self, place):if place.ant isNone:
place.ant = self
else:# BEGIN Problem Optional 2assert place.ant isNone,'Two ants in {0}'.format(place)# END Problem Optional 2
Insect.add_to(self, place)defremove_from(self, place):if place.ant is self:
place.ant =Noneelif place.ant isNone:assertFalse,'{0} is not in {1}'.format(self, place)else:# queen or container (optional) or other situation
place.ant.remove_ant(self)
Insect.remove_from(self, place)classHarvesterAnt(Ant):"""HarvesterAnt produces 1 additional food per turn for the colony."""
name ='Harvester'
implemented =True# OVERRIDE CLASS ATTRIBUTES HERE
food_cost =2defaction(self, gamestate):"""Produce 1 additional food for the colony.
gamestate -- The GameState, used to access game state information.
"""# BEGIN Problem 1"*** YOUR CODE HERE ***"
gamestate.food = gamestate.food +1# END Problem 1classThrowerAnt(Ant):"""ThrowerAnt throws a leaf each turn at the nearest Bee in its range."""
name ='Thrower'
implemented =True
damage =1# ADD/OVERRIDE CLASS ATTRIBUTES HERE
food_cost =3
min_range =0
max_range =float('inf')defnearest_bee(self, beehive):"""Return the nearest Bee in a Place that is not the HIVE (beehive), connected to
the ThrowerAnt's Place by following entrances.
This method returns None if there is no such Bee (or none in range).
"""# BEGIN Problem 3 and 4
self.prospective_bees_place = self.place
self.distance =0whileTrue:if self.prospective_bees_place.bees ==[]:if self.prospective_bees_place.entrance == beehive:returnNoneelse:
self.prospective_bees_place = self.prospective_bees_place.entrance
self.distance = self.distance +1else:#discover a beeif self.min_range <= self.distance <= self.max_range:return rANTdom_else_none(self.prospective_bees_place.bees)else: