• Principle of Computing (Python)学习笔记(5) BFS Searching + Zombie Apocalypse


    1 Generators  
    Generator和list comprehension非常类似
    Generators are a kind of iterator that are defined like functions. 

    http://www.codeskulptor.org/#examples_generators.py

    https://wiki.python.org/moin/Generators

    generater function的函数体中必须写上yield, 能够写或者不写return。

    Generators functions allow you to declare a function that behaves like an iterator, i.e. it can be used in a for loop.
    Each time the next(), method is applied to the resulting generator, the code is run until the next yield expression, and the yield expression's value is returned from that method call. Thus, the creation of the generator does not wait for all of its elements to be generator, and the generator could even represent an infinite number of elements.

    # A list comprehension
    print "max in list:", max([num * 2 - 3 for num in range(7)])
    
    # A generator expression
    print "max in gen:", max(num * 2 - 3 for num in range(7))
    
    # A generator function
    def genfunc(limit):
        num = 0
        while num < limit:
            yield num  #generator function一般和iteration搭配使用。yield说明这个值产生了,放在一边,如今循环继续进行。等循环结束了。再回来处理之前yield产生的值。
            num = num + 1
    
    print genfunc(7)
    # Iteration using a generator function
    print "Iterate over generator:"
    for number in genfunc(7):
        print number


    2 stack and queue

    stack http://www.codeskulptor.org/#user36_ZHLkI0d7kb_2.py

    queue  http://www.codeskulptor.org/#user35_AtoP6ttM6w_0.py




    3 inheritance
    http://www.codeskulptor.org/#examples_inheritance.py
    http://www.codeskulptor.org/#examples_inheritance2.py


    4 grid collision
    http://www.codeskulptor.org/#poc_physics_quadratic.py
    https://class.coursera.org/principlescomputing-001/wiki/view?

    page=fun_growth

    https://class.coursera.org/principlescomputing-001/wiki/view?page=grids



    5 grid类的实现  
    http://www.codeskulptor.org/#poc_grid.py 
    注意当中的”def get_index(self, point, cell_size):”的转化方法。把实际的screen position转化为了index

    6 Conway’s game of life 模拟
    game of life 简单介绍 http://en.wikipedia.org/wiki/Conway's_Game_of_Life
    game of life 进行grid操作的练习 http://www.codeskulptor.org/#poc_gol_student.py

    7 BFS
    BFS动画 野火烧不尽 春风吹又生 
    http://www.codeskulptor.org/#poc_wildfire_student.py
    http://www.codeskulptor.org/#poc_wildfire_gui.py
    http://www.codeskulptor.org/#poc_grid.py
    BFS原理 https://class.coursera.org/principlescomputing-001/wiki/view?page=bfs

    8 grid的用途 使用bucket sorting进行string sorting
    https://class.coursera.org/principlescomputing-001/wiki/view?page=strings
    http://www.codeskulptor.org/#poc_string_sort.py
    # 产生26个字母组成的list
    list= [ chr(ord("a") + char_num) for char_num in range(26)]
    print list


    9 stack and queue
    老师实现的queue http://www.codeskulptor.org/#poc_queue.py
    自己实现的stackhttp://www.codeskulptor.org/#user36_ZHLkI0d7kb_2.py

    10 Zombie Apocalypse
    http://www.codeskulptor.org/#poc_zombie_template.py
    1)  Passable cells in the grid correspond to EMPTY cells while FULL cells are impassable
    2)  However, several humans and zombies may inhabit the same grid cell. 

    3) 注意用for each in list1仅仅能读取list1中的元素,不能改动list1中的元素,假设要改动的话。要使用下标操作,如

    4) zombie和human移动的原理是这种。
    首先对zombie计算一个distance_grid,这个distance_grid中的每一个cell都表达从当前cell到距离近期的一个zombie的距离,接下来,move_human的时候,就从human周围的cell中选一个distance_grid相应值最大的cell,这样human 就移动到了一个human最安全的点。

    类似。对human计算一个distance_grid。中的每一个cell都表达从当前cell到距离近期的一个human的距离,接下来,move_zombie的时候,就从zombie周围的cell中选一个distance_grid相应值最小的cell,这样human 就移动到了一个最接近human的点。

    5) 题目做了非常多简化。

    比方计算distance_grid的时候。无论是zombie还是human。都假定当前cell的相邻cell仅仅有4个,而不是8个。

    当zombie追上human的时候,仅仅是grid改变了颜色,假设下一步继续human move,human还是活着的。

    for idx in range(len(list1)): 
        list1[idx] += 1 
    


    我的作业

    """
    Student portion of Zombie Apocalypse mini-project
    """
    
    import random
    import poc_grid
    import poc_queue
    import poc_zombie_gui
    
    # global constants
    EMPTY = 0 
    FULL = 1
    FOUR_WAY = 0
    EIGHT_WAY = 1
    OBSTACLE = "obstacle"
    HUMAN = "human"
    ZOMBIE = "zombie"
    
    
    class Zombie(poc_grid.Grid):
        """
        Class for simulating zombie pursuit of human on grid with
        obstacles
        """
    
        def __init__(self, grid_height, grid_width, obstacle_list = None, 
                     zombie_list = None, human_list = None):
            """
            Create a simulation of given size with given obstacles,
            humans, and zombies
            """
            poc_grid.Grid.__init__(self, grid_height, grid_width)
            if obstacle_list != None:
                for cell in obstacle_list:
                    self.set_full(cell[0], cell[1])
            if zombie_list != None:
                self._zombie_list = list(zombie_list)
            else:
                self._zombie_list = []
            if human_list != None:
                self._human_list = list(human_list)  
            else:
                self._human_list = []
            
        def clear(self):
            """
            Set cells in obstacle grid to be empty
            Reset zombie and human lists to be empty
            """
            poc_grid.Grid.clear(self)
            self._zombie_list = []
            self._human_list = []
            
        def add_zombie(self, row, col):
            """
            Add zombie to the zombie list
            """
            self._zombie_list.append((row,col))
                    
        def num_zombies(self):
            """
            Return number of zombies
            """
            return len(self._zombie_list)
              
        def zombies(self):
            """
            Generator that yields the zombies in the order they were
            added.
            """
            num = 0
            while num < self.num_zombies():
                yield self._zombie_list[num]
                num += 1 
            return
    
        def add_human(self, row, col):
            """
            Add human to the human list
            """
            self._human_list.append((row,col))
            
        def num_humans(self):
            """
            Return number of humans
            """
            return len(self._human_list)
        
        def humans(self):
            """
            Generator that yields the humans in the order they were added.
            """
            num = 0
            while num<self.num_humans():
                yield self._human_list[num]
                num += 1
            return
            
        def compute_distance_field(self, entity_type):
            """
            Function computes a 2D distance field
            Distance at member of entity_queue is zero
            Shortest paths avoid obstacles and use distance_type distances
            """
            visited = poc_grid.Grid(self._grid_height, self._grid_width)
            distance_field = [[ self._grid_width * self._grid_height for dummy_col in range(self._grid_width)]
                           for dummy_row in range(self._grid_height)]
            if entity_type == HUMAN:  
                boundary = poc_queue.Queue()              
                for each in self._human_list:
                    visited.set_full(each[0],each[1])
                    distance_field[each[0]][each[1]] = 0
                    boundary.enqueue(each)
                while len(boundary)>0:
                    cur_cell = boundary.dequeue()
                    four_neighbors = poc_grid.Grid.four_neighbors(self,cur_cell[0],cur_cell[1])
                    for each_neighbor in four_neighbors:
                        if  visited.is_empty(each_neighbor[0],each_neighbor[1]) and poc_grid.Grid.is_empty(self, each_neighbor[0], each_neighbor[1]) :
                            visited.set_full(each_neighbor[0],each_neighbor[1])
                            if distance_field[cur_cell[0]][cur_cell[1]]+1 < distance_field[each_neighbor[0]][ each_neighbor[1]]:
                                distance_field[each_neighbor[0]][ each_neighbor[1]] = distance_field[cur_cell[0]][cur_cell[1]]+1
                            boundary.enqueue(each_neighbor)                
            elif  entity_type == ZOMBIE:
                boundary = poc_queue.Queue()                          
                for each in self._zombie_list:
                    visited.set_full(each[0],each[1])
                    distance_field[each[0]][each[1]] = 0
                    boundary.enqueue(each)
                while len(boundary)>0:               
                    cur_cell = boundary.dequeue()
                    four_neighbors = poc_grid.Grid.four_neighbors(self,cur_cell[0],cur_cell[1])                
                    for each_neighbor in four_neighbors:
                        if  visited.is_empty(each_neighbor[0],each_neighbor[1]) and poc_grid.Grid.is_empty(self, each_neighbor[0], each_neighbor[1]):
                            visited.set_full(each_neighbor[0],each_neighbor[1])                        
                            if distance_field[cur_cell[0]][cur_cell[1]]+1 < distance_field[each_neighbor[0]][ each_neighbor[1]]:
                                distance_field[each_neighbor[0]][ each_neighbor[1]] = distance_field[cur_cell[0]][cur_cell[1]]+1
                            boundary.enqueue(each_neighbor)                
            return   distance_field          
                        
        def move_humans(self, zombie_distance):
            """
            Function that moves humans away from zombies, diagonal moves
            are allowed
            """
            for idx in range(len(self._human_list)):
                eight_neighbor_human = poc_grid.Grid.eight_neighbors(self, self._human_list[idx][0],self._human_list[idx][1])    
                max_distance = zombie_distance[self._human_list[idx][0]][self._human_list[idx][1]]
                max_pos =(self._human_list[idx][0],self._human_list[idx][1]) 
                for eight_neighbor in eight_neighbor_human:
                    if zombie_distance[eight_neighbor[0]][eight_neighbor[1]]> max_distance:
                        max_distance = zombie_distance[eight_neighbor[0]][eight_neighbor[1]]
                        max_pos =(eight_neighbor[0],eight_neighbor[1])
                self._human_list[idx]=(max_pos[0],max_pos[1])
        
        def move_zombies(self, human_distance):
            """
            Function that moves zombies towards humans, no diagonal moves
            are allowed
            """
            for idx in range(len(self._zombie_list)):
                four_neighbor_zombie = poc_grid.Grid.four_neighbors(self, self._zombie_list[idx][0],self._zombie_list[idx][1])    
                min_distance = human_distance[self._zombie_list[idx][0]][self._zombie_list[idx][1]]
                min_pos =(self._zombie_list[idx][0],self._zombie_list[idx][1]) 
                for four_neighbor in four_neighbor_zombie:
                    if human_distance[four_neighbor[0]][four_neighbor[1]]< min_distance:
                        min_distance = human_distance[four_neighbor[0]][four_neighbor[1]]
                        min_pos =(four_neighbor[0],four_neighbor[1])
                self._zombie_list[idx]=(min_pos[0],min_pos[1])
    
    # Start up gui for simulation - You will need to write some code above
    # before this will work without errors
    #test_zombie =  Zombie(3, 3, [], [], [(2, 2)])
    #print test_zombie.compute_distance_field('human')
    poc_zombie_gui.run_gui(Zombie(20, 15))
    



  • 相关阅读:
    c语言学习指针变量
    SQL字符串函数
    [转]HttpWebRequest使用注意(发生阻塞的解决办法)
    Image.FormFile的锁文件解决
    不联网在win8安装framework3.5
    metro app损坏,修复以及商店速度慢的解决方法
    关于C#使用来电通的来电通内部原理浅析
    winform模拟qq聊天界面的小功能textbox1输入自动跳到textbox2
    C#下的路由器后台登录
    dropbox文件夹路径丢失变回默认文件的解决方法
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5093580.html
Copyright © 2020-2023  润新知