abbarnes

Zombie Apocalypse Sim [codeskulptor]

Dec 13th, 2017
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.90 KB | None | 0 0
  1. """
  2. Student portion of Zombie Apocalypse mini-project
  3. """
  4. #http://www.codeskulptor.org/#user43_yCIa8eafEzbL3Am_20.py
  5.  
  6. import random
  7. import poc_grid
  8. import poc_queue
  9. import poc_zombie_gui
  10.  
  11. # global constants
  12. EMPTY = 0
  13. FULL = 1
  14. FOUR_WAY = 0
  15. EIGHT_WAY = 1
  16. OBSTACLE = 5
  17. HUMAN = 6
  18. ZOMBIE = 7
  19.  
  20.  
  21. class Apocalypse(poc_grid.Grid):
  22.     """
  23.    Class for simulating zombie pursuit of human on grid with
  24.    obstacles
  25.    """
  26.  
  27.     def __init__(self, grid_height, grid_width, obstacle_list = None,
  28.                  zombie_list = None, human_list = None):
  29.         """
  30.        Create a simulation of given size with given obstacles,
  31.        humans, and zombies
  32.        """
  33.         poc_grid.Grid.__init__(self, grid_height, grid_width)
  34.         if obstacle_list != None:
  35.             for cell in obstacle_list:
  36.                 self.set_full(cell[0], cell[1])
  37.         if zombie_list != None:
  38.             self._zombie_list = list(zombie_list)
  39.         else:
  40.             self._zombie_list = []
  41.         if human_list != None:
  42.             self._human_list = list(human_list)  
  43.         else:
  44.             self._human_list = []
  45.        
  46.     def clear(self):
  47.         """
  48.        Set cells in obstacle grid to be empty
  49.        Reset zombie and human lists to be empty
  50.        """
  51.         poc_grid.Grid.clear(self)
  52.         self._zombie_list = []
  53.         self._human_list = []
  54.         return
  55.        
  56.     def add_zombie(self, row, col):
  57.         """
  58.        Add zombie to the zombie list
  59.        """
  60.         self._zombie_list.append((row,col))
  61.         return
  62.                
  63.     def num_zombies(self):
  64.         """
  65.        Return number of zombies
  66.        """
  67.         return len(self._zombie_list)  
  68.          
  69.     def zombies(self):
  70.         """
  71.        Generator that yields the zombies in the order they were
  72.        added.
  73.        """
  74.         for zombie in self._zombie_list:
  75.             yield zombie
  76.  
  77.     def add_human(self, row, col):
  78.         """
  79.        Add human to the human list
  80.        """
  81.         self._human_list.append((row,col))
  82.        
  83.     def num_humans(self):
  84.         """
  85.        Return number of humans
  86.        """
  87.         return len(self._human_list)
  88.    
  89.     def humans(self):
  90.         """
  91.        Generator that yields the humans in the order they were added.
  92.        """
  93.         for human in self._human_list:
  94.             yield human
  95.        
  96.     def print_all(self):
  97.         """
  98.        prints out a grid showing where humans, zombies, and blocks are.
  99.        """
  100.         grid_copy = list(self._cells)
  101.         for human in self.humans():
  102.             grid_copy[human[0]][human[1]] = 6
  103.         for zombie in self.zombies():
  104.             grid_copy[zombie[0]][zombie[1]] = 7
  105.        
  106.         ans = ""
  107.         for row in range(self._grid_height):
  108.             ans += str(grid_copy[row])
  109.             ans += "\n"
  110.         return ans
  111.    
  112.     def compute_distance_field(self, entity_type):
  113.         """
  114.        Function computes and returns a 2D distance field
  115.        Distance at member of entity_list is zero
  116.        Shortest paths avoid obstacles and use four-way distances
  117.        """
  118.         boundary = poc_queue.Queue()
  119.         visited = poc_grid.Grid(self.get_grid_height(),self.get_grid_width())
  120.         distance_field = [[self.get_grid_height()*self.get_grid_width() for dummy_col in range(self.get_grid_width())]
  121.                           for dummy_row in range(self.get_grid_height())]
  122.         #Que entities to boundary
  123.         if entity_type == HUMAN:
  124.             for human in self.humans():
  125.                 boundary.enqueue(human)
  126.         elif entity_type == ZOMBIE:
  127.             for zombie in self.zombies():
  128.                 boundary.enqueue(zombie)
  129.         else:
  130.             print "invalid input"
  131.             return
  132.         #set entity positions in visited grid as "full" and in distance_field as "0"
  133.         for item in boundary:
  134.             visited.set_full(item[0], item[1])
  135.             distance_field[item[0]][item[1]] = 0
  136.         #iterate to add new cells surrounding boundary members to boundary
  137.         #set new cells as full in visited and #steps in dist_field; dequeue original boundary cell
  138.         while boundary:
  139.             location = boundary.dequeue()
  140.             location_dist = distance_field[location[0]][location[1]]
  141.             adjacent = visited.four_neighbors(location[0], location[1])
  142.             for adj in adjacent:
  143.                 if self.is_empty(adj[0],adj[1]) and visited.is_empty(adj[0],adj[1]):
  144.                     boundary.enqueue(adj)
  145.                     visited.set_full(adj[0], adj[1])
  146.                     distance_field[adj[0]][adj[1]] = location_dist+1
  147.         return distance_field
  148.    
  149.     def is_cell_empty(self, cell):
  150.         """
  151.        returns if a cell is empty
  152.        """
  153.         #takes single tuple instead of row, col... allows function to be used as filter
  154.         return self.is_empty(cell[0], cell[1])
  155.                          
  156.     def move_humans(self, zombie_distance_field):
  157.         """
  158.        Function that moves humans away from zombies, diagonal moves
  159.        are allowed
  160.        """
  161.         new_humans = []
  162.         for human in self.humans():
  163.             possible_moves = filter(self.is_cell_empty, self.eight_neighbors(human[0], human[1]))
  164.             best_move = self.get_best_move(human, possible_moves, zombie_distance_field, True)
  165.             new_humans.append(best_move)
  166.         self._human_list = new_humans  
  167.    
  168.     def move_zombies(self, human_distance_field):
  169.         """
  170.        Function that moves zombies towards humans, no diagonal moves
  171.        are allowed
  172.        """
  173.         new_zombies = []
  174.         for zombie in self.zombies():
  175.             possible_moves = filter(self.is_cell_empty, self.four_neighbors(zombie[0], zombie[1]))
  176.             best_move = self.get_best_move(zombie, possible_moves, human_distance_field, False)
  177.             new_zombies.append(best_move)
  178.         self._zombie_list = new_zombies
  179.    
  180.     def get_best_move(self, current_position, possible_moves, distance_field, flee):
  181.         """
  182.        returns one of possible best moves for a zombie or human
  183.        """
  184.         best_move = []
  185.         best_move.append(current_position)
  186.         for move in possible_moves:
  187.             if flee:
  188.                 if distance_field[move[0]][move[1]] > distance_field[best_move[0][0]][best_move[0][1]]:
  189.                     best_move = [move]
  190.                 elif distance_field[move[0]][move[1]] == distance_field[best_move[0][0]][best_move[0][1]]:
  191.                     best_move.append(move)
  192.             elif not flee:
  193.                 if distance_field[move[0]][move[1]] < distance_field[best_move[0][0]][best_move[0][1]]:
  194.                     best_move = [move]
  195.                 elif distance_field[move[0]][move[1]] == distance_field[best_move[0][0]][best_move[0][1]]:
  196.                     best_move.append(move)
  197.         random.shuffle(best_move)
  198.         return best_move.pop()
  199.        
  200.  
  201. # Start up gui for simulation - You will need to write some code above
  202. # before this will work without errors
  203.  
  204. poc_zombie_gui.run_gui(Apocalypse(30, 40))
  205.  
  206. #game = Apocalypse(3, 3, [], [(2, 2)], [(1, 1)])
  207. #dist = [[4, 3, 2], [3, 2, 1], [2, 1, 0]]
  208. #print game
  209. #print
  210. #print "Print all:"
  211. #print game.print_all()
  212. #print
  213. ##dist = game.compute_distance_field(HUMAN)
  214. #print "distance field:"
  215. #for row in range(len(dist)):
  216. #    print dist[row]
  217. #game.move_humans(dist)
  218. #print "Moved humans"
  219. #print game.print_all()
  220.  
  221. #i = 0
  222. #j = 1
  223. #rows = 10
  224. #cols = 10
  225. #blocks = [(3,8)]
  226. ##zombies = [(i,col) for col in range(cols)]
  227. ##humans = [(j,col) for col in range(cols)]
  228. #zombies = [(0,4)]
  229. #humans = [(1,4)]
  230. #
  231. #game = Apocalypse(rows, cols, blocks, zombies, humans)
  232. #dist = game.compute_distance_field(ZOMBIE)
  233. #print "distance field:"
  234. #for row in range(len(dist)):
  235. #    print dist[row]
  236. #print
  237. #print game.print_all()
  238. #game.move_humans(dist)
  239. #print game.print_all()
  240. #game.clear()
  241. #print game
Advertisement
Add Comment
Please, Sign In to add comment