def distance_field(grid, position, obstacles): """ Compute a distance field on a grid in a given position, with the given obstacles. """ boundary = Queue() # bsf uses queue dynamics boundary.enqueue((position[0], position[1])) # put the starting grid in the queue visited = [[EMPTY for _ in xrange(WIDTH)] for _ in xrange(HEIGHT)] visited[position[0]][position[1]] = FULL # set the starting cell to visited field = Grid(HEIGHT, WIDTH, STRMAP) # we'll store the distance field as a grid field.set_all_to(-1) # -1 will symbolize unreachable cells # Set obstacles for obstacle in obstacles: grid.set_obstacle(obstacle[0], obstacle[1]) field.set_obstacle(obstacle[0], obstacle[1]) field.set_empty(position[0], position[1]) # set the root position while boundary: # while the queue is not empty current = boundary.dequeue() # get a grid cell from the queue neighbors = grid.four_neighbors(current[0], current[1]) # get the four neighbor cells: # up, down, left, and right for neighbor in neighbors: # for every neighbor cell # If the cell hasn't been visited and has no obstacles: if not visited[neighbor[0]][neighbor[1]] and grid.is_empty(neighbor[0], neighbor[1]): visited[neighbor[0]][neighbor[1]] = FULL # set it as visited boundary.enqueue(neighbor) # add it to the queue field.set_to(neighbor[0], neighbor[1], # set the distance from the root field.get_cell(current[0], current[1]) + 1) return field
def bfs(grid, row, col): """ Perform a breath-first search in the given grid, starting in the given cell. """ boundary = Queue() # bsf uses queue dynamics boundary.enqueue((row, col)) # put the starting grid in the queue visited = [[EMPTY for _ in xrange(WIDTH)] for _ in xrange(HEIGHT)] visited[row][col] = FULL # set the starting cell to visited while boundary: # while the queue is not empty current = boundary.dequeue() # get a grid cell from the queue grid.set_marked(current[0], current[1]) # (this is for the print) neighbors = grid.four_neighbors(current[0], current[1]) # get the four neighbor cells: print grid # up, down, left, and right for neighbor in neighbors: # for every neighbor cell if not visited[neighbor[0]][neighbor[1]]: # if it hasn't been visited visited[neighbor[0]][neighbor[1]] = FULL # set it as visited boundary.enqueue(neighbor) # add it to the queue grid.set_full(neighbor[0], neighbor[1]) # (this is for the print) print grid