def __call__(self, **kwargs): """ Call the members' functions, and the group's action func if it has one. This should return the total of all agents who acted in a particular call. """ if DEBUG.debug_lib: print("Calling {} to act.".format(self.name)) total_acts = 0 total_moves = 0 del_list = [] self.duration -= 1 if self.duration > 0: if self.action is not None: # the action was defined outside this class, so pass self: self.action(self, **kwargs) for (key, member) in self.members.items(): if member.is_active(): (acted, moved) = member(**kwargs) total_acts += acted total_moves += moved else: # delete agents but not group: if not is_group(member): del_list.append(key) for key in del_list: del self.members[key] return total_acts, total_moves
def rand_place_members(self, members, max_move=None): """ Locate all members of this space in x, y grid. This randomly places members. """ if members is not None: for nm, mbr in members.items(): if not is_group(mbr): # by default don't locate groups self.place_member(mbr, max_move) else: # place composite's members self.rand_place_members(mbr.members, max_move)
def __iadd__(self, other): """ Add other to set self. If other is a group, add all its members. If other is an atom, add it. """ if other is None: return self if is_group(other): for key in other: join(self, other[key]) else: join(self, other) return self
def __add__(self, other): """ This implements set union and returns a new Group that is self union other. If other is an atomic agent, just add it to this group. """ if other is None: return self new_dict = copy(self.members) if is_group(other): new_dict.update(other.members) else: new_dict[other.name] = other new_grp = grp_from_nm_dict(self.name + "+" + other.name, new_dict) self.add_group(new_grp) other.add_group(new_grp) return new_grp
def place_member(self, mbr, max_move=None, xy=None, attempts=0): """ By default, locate a member at a random x, y spot in our grid. `max_move` constrains where that can be. Setting `xy` picks a particular spot to place member. `xy` must be a tuple! """ if self.is_full(): print(ALL_FULL) raise (SpaceFull(ALL_FULL)) if attempts > MAX_PLACE_ATTEMPTS: # we should create a better exception here, but this will work for # now: print(ALL_FULL, "attempts=", attempts) raise (SpaceFull(ALL_FULL)) if not is_group(mbr): if xy is not None: (x, y) = xy else: (x, y) = self.gen_new_pos(mbr, max_move) if self.is_empty(x, y): if mbr.is_located(): self.move_location(x, y, mbr.get_x(), mbr.get_y(), mbr.name) else: self.add_location(x, y, mbr) mbr.set_pos(x, y) return x, y elif (max_move is None) and (xy is None): # if the random position is already taken,x # find the member a new position # but if max_move is not None, the hood might be filled! # so we need something to detect # a full neighborhood as well. # and if xy is not None, the user asked for a particular # spot: don't give them another, but return None. return self.place_member(mbr, max_move, attempts=attempts + 1) else: return self.rand_place_members(mbr.members, max_move)
def consec_place_members(self, members, curr_col=0, curr_row=0): """ Locate all members of this space in x, y grid. Place members consecutively, starting from (0, 0) and moving to (1, 0), (2, 0), etc """ if members is not None: for nm, mbr in members.items(): if not is_group(mbr): if curr_col < self.width: self.place_member(mbr, xy=(curr_col, curr_row)) if DEBUG.debug_lib: print("Placing member at (" + str(curr_col) + "," + str(curr_row) + ")") curr_col += 1 if curr_col == self.width: if DEBUG.debug_lib: print("Moving up a row from", curr_row, "to", curr_row + 1) curr_col = 0 curr_row += 1 else: # place composite's members self.consec_place_members(mbr.members, curr_col, curr_row)
def is_mbr_comp(self, mbr): return is_group(self.members[mbr])