def do_init(): # position everyone randomly about the canvas (x_min, y_min, x_max, y_max) = agentsim.gui.get_canvas_coords() # because we create additional zombies, we want to remove them # from the simulation before we start. We might as well remove all # the persons and start fresh. for p in Person.get_all_instances(): Person.del_instance(p) # create all the new people at the party create_persons(init_num_normals, init_num_defenders, init_num_zombies) # position them randomly about for p in Person.get_all_instances(): i = 3 while not position_randomly(p, x_min, x_max, y_min, y_max) and i > 0 : i -= 1 # if after 3 tries we could not position p, then make it leave the party if i <= 0: print("Could not position {} into random spot".format(p.get_name())) p.leave() # have all the people arrive at the simulation before we start for p in Person.get_all_instances(): p.arrive()
def do_step(): # Buffer all the move_by calls and do at once. # Note that this does not buffer other state changes made in objects, # such as a teleport - we really should have that facility for a proper # simulation of a time step # we should also enforce the restriction on the move limit for each # type of object. At the moment, you can get around this limit by calling # move_by in the compute_next_move method! moves = [ ] # give the defenders a chance to tell the normals what to do # and try to teleport any zombies for p in Defender.get_all_present_instances(): moves.append( (p,) + p.compute_next_move() ) # then give the normals a chance for p in Normal.get_all_present_instances(): moves.append( (p,) + p.compute_next_move() ) # and finally the zombies, which may have been teleported to new positions for p in Zombie.get_all_present_instances(): moves.append( (p,) + p.compute_next_move() ) # then execute the moves, even though other state may have been changed # earlier for (p, delta_x, delta_y) in moves: p.move_by(delta_x, delta_y) # then convert normals into zombies if the zombies are close enough # Warning: z - number of zombies, n - number of normals, then the # time complexity of this is O( z n ) for z in Zombie.get_all_present_instances(): for n in Normal.get_all_present_instances(): d_e_e = z.distances_to(n)[3] d_touch = z.get_touching_threshold() # print(z.get_name(), n.get_name(), d_e_e, d_touch) if d_e_e <= d_touch: x = n.get_xpos() y = n.get_ypos() new_z = Zombie(size=n.get_size(), haircolor='green', xpos = x, ypos = y, move_limit=person_move_limit) new_z.arrive() n.leave() Person.del_instance(n)