Ejemplo n.º 1
0
    def add(self, screen, block_size, line_width, tile_list, color, start_tile, end_tile, last):
        for tile in tile_list:
            # Ignore the start tile as we don't want to treat it like a normal one
            if tile.x == start_tile.x and tile.y == start_tile.y:
                continue
            # If the end tile was added to the queue don't change its color and other values
            if tile.x == end_tile.x and tile.y == end_tile.y:
                tile.last = last
                self.queue.put(tile)
                continue

            # Don't add blocked tiles as they cannot be traversed
            if tile.blocked:
                continue

            if tile not in self.duplicate_checker:
                # Changing the last value of the tile
                tile.last = last

                # Changing the tile's color
                tile.color = color

                # Updating the f cost of our tile so it can be ordered accordingly in the queue
                tile.update_cost(start_tile, end_tile)

                # Redrawing our added tiles
                DrawingFunctions.draw_tile(screen, block_size, line_width, tile)

                self.queue.put(tile)
                self.duplicate_checker.add(tile)
def draw_blocked_tiles():
    finished = False  # Loop control variable
    mouse_down = False  # Variable for mouse hold
    right_mouse_down = False

    while not finished:

        for event in pygame.event.get():
            if event == pygame.QUIT:  # On quit button clicked
                finished = True
                continue

            if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT_CLICK:  # On left mouse click
                mouse_down = True

            if event.type == pygame.MOUSEBUTTONDOWN and event.button == RIGHT_CLICK:
                right_mouse_down = True

            if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT_CLICK:
                mouse_down = False

            if event.type == pygame.MOUSEBUTTONUP and event.button == RIGHT_CLICK:
                right_mouse_down = False

            if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:  # If enter button is clicked
                finished = True

            if mouse_down or right_mouse_down:
                # Getting the click position and adjusting it to our grid
                position = pygame.mouse.get_pos()
                x, y = position
                x, y = x // BLOCK_SIZE, y // BLOCK_SIZE

                # Getting the clicked tile and changing it to be blocked and have the appropriate color
                tile = grid.get_tile(x, y)

                # Making sure the end and start tiles aren't blocked
                if tile.x == start_tile.x and tile.y == start_tile.y:
                    continue
                if tile.x == end_tile.x and tile.y == end_tile.y:
                    continue

                if mouse_down:
                    tile.blocked = True
                    tile.color = BLACK

                    # Drawing the tile
                    DrawingFunctions.draw_tile(screen, BLOCK_SIZE, LINE_WIDTH,
                                               tile)

                else:
                    tile.blocked = False
                    tile.color = WHITE

                    DrawingFunctions.draw_tile(screen, BLOCK_SIZE, LINE_WIDTH,
                                               tile)

            pygame.display.update()
def display_shortest_path(last_tile):
    while last_tile.last is not None:
        last_tile.color = BLUE
        DrawingFunctions.draw_tile(screen, BLOCK_SIZE, LINE_WIDTH, last_tile)
        pygame.display.update()
        last_tile = last_tile.last
def main():

    # Drawing our screen
    DrawingFunctions.draw_grid(screen, WHITE, BLACK, SCREEN_WIDTH,
                               SCREEN_HEIGHT, BLOCK_SIZE, LINE_WIDTH)
    pygame.display.update()

    # Getting coordinates for the start and end tiles
    tkinter_input()

    # If the start tile equals the end tile just quit
    if start_tile.x == end_tile.x and start_tile.y == end_tile.y:
        return

    # Drawing start and end tiles
    DrawingFunctions.draw_first_tiles(screen, BLOCK_SIZE, LINE_WIDTH,
                                      start_tile, end_tile, BLUE)

    # Drawing our blocked tiles
    draw_blocked_tiles()

    # Setting up regular variables
    tile_queue = TileQueue()

    # Initializing our queue
    start_tile_neighbours = grid.get_neighbour_tiles(start_tile.x,
                                                     start_tile.y)
    tile_queue.add(screen, BLOCK_SIZE, LINE_WIDTH, start_tile_neighbours,
                   GREEN, start_tile, end_tile, start_tile)

    # Setting up loop variables
    running = True

    while running:

        # Pulling out the best tile
        best_tile = tile_queue.get()

        # If the algorithm reached the end tile break
        if best_tile.x == end_tile.x and best_tile.y == end_tile.y:
            display_shortest_path(best_tile)
            time.sleep(5)
            break

        best_tile.color = RED
        DrawingFunctions.draw_tile(screen, BLOCK_SIZE, LINE_WIDTH, best_tile)

        # Adding the best tile's neighbours to the queue
        neighbours = grid.get_neighbour_tiles(best_tile.x, best_tile.y)
        tile_queue.add(screen, BLOCK_SIZE, LINE_WIDTH, neighbours, GREEN,
                       start_tile, end_tile, best_tile)

        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        if tile_queue.empty():
            running = False

        pygame.display.update()