Example #1
0
    def __init__(self, text: Text, padding: Vector2D = Vector2D(20, 10), position: Vector2D = Vector2D.zero(),
                 color: Color = None,
                 onclick=None):
        super(Button, self).__init__()

        # look
        self.text = text
        self._position = position

        self.padding = padding
        self._size = Vector2D(
            self.text.rect.size[0] + self.padding.x,
            self.text.rect.size[1] + self.padding.y
        )

        self.text.center(Vector2D.center(self.position, self.size))

        # color
        if color is None:
            color = colors.TRANSPARENT
        self._mutable_color = color
        self._original_color = color

        # behaviour
        self.onhover = Hover(DIM_LIGHT, ORIGINAL_COLOR)
        self.onclick = onclick

        if self.onclick is None:
            self.onclick = lambda button: None

        # used to draw
        self.surface = self.make()
Example #2
0
    def get_viable_neigbours(self):

        vectors = []

        size = Vector2D(len(self.grid), len(self.grid[0]))
        for x in [self.current.x - 1, self.current.x, self.current.x + 1]:
            for y in [self.current.y - 1, self.current.y, self.current.y + 1]:

                # index out of range
                if x < 0 or x > size.x - 1 or y < 0 or y > size.y - 1:
                    continue

                # current pos
                if x == self.current.x and y == self.current.y:
                    continue

                tile = self.grid[x][y]
                state = Tile.int_to_state(tile)

                if state in [Tile.UNVISITED, Tile.NEIGHBOURS, Tile.END]:
                    vectors.append(Vector2D(x, y))

                    # update cost
                    grid_cost = self.costgrid[x][y]
                    calculated_cost = Vector2D(x, y).manhattan(
                        self.current) + Vector2D(x, y).manhattan(self.end)

                    if grid_cost == -1 or grid_cost > calculated_cost:
                        self.costgrid[x][y] = calculated_cost
                        self.visited[tuple([x, y])] = self.current

                    if state != Tile.END:
                        self.grid[x][y] = Tile.state_to_int(Tile.NEIGHBOURS)

        return vectors
Example #3
0
    def __init__(self, size: Vector2D, info_text: Text, position=Vector2D(0, 20), padding=Vector2D(0, 0)):

        self.size = size
        self.position = position
        self.padding = padding

        self.info_text = info_text
        self.info_text.text = 'Select start'

        self.tilepadding = Vector2D(0, 0)
        screen_size = Vector2D.tuple(pygame.display.get_surface().get_rect().size)
        space = Vector2D(
            screen_size.x - position.x - padding.x,
            screen_size.y - position.y - padding.y
        )

        self.tilesize = Vector2D(
            int((space.x - (self.size.x * self.tilepadding.x)) / self.size.x),
            int((space.y - (self.size.y * self.tilepadding.y)) / self.size.y),
        )

        self.grid = []
        for x in range(size.x):
            l = [0] * size.y
            self.grid.append(l)

        self.tiles = []
        for x in range(size.x):
            l = [None] * size.y
            self.tiles.append(l)

        self.remake_tiles(self.grid)

        self.drawable = Switch(True)

        self.mouse_left_down = Switch(False)
        self.mouse_left_down_type = None

        self.start = None
        self.end = None

        self.algorithm = None

        def onflip(val):
            if self.algorithm.solution_length == -1:
                self.info_text.text = 'No solution found'
                return

            self.info_text.text = 'Running' if val else f'Found solution of length {self.algorithm.solution_length}'

        self.running = Switch(False, onflip=onflip)

        self.misc = {}
Example #4
0
    def remake_tiles(self, positions):
        for gridposition in positions:
            x, y = gridposition

            position = Vector2D(
                y * self.tilesize.y + y * self.tilepadding.x + self.position.x + self.padding.x,
                x * self.tilesize.x + x * self.tilepadding.y + self.position.y + self.padding.y,
            )

            tile = Tile(Tile.int_to_state(self.grid[x][y]), gridpos=Vector2D(x, y), position=position,
                        size=self.tilesize)

            self.tiles[x][y] = tile
Example #5
0
    def update_tiles(self, grid):
        size = Vector2D(len(grid), len(grid[0]))

        for x in range(size.x):
            for y in range(size.y):
                position = Vector2D(
                    y * self.tilesize.y + y * self.tilepadding.x + self.position.x + self.padding.x,
                    x * self.tilesize.x + x * self.tilepadding.y + self.position.y + self.padding.y,
                )

                tile = Tile(Tile.int_to_state(self.grid[x][y]), gridpos=Vector2D(x, y), position=position,
                            size=self.tilesize)

                self.tiles[x][y] = tile
Example #6
0
    def generate_bars(self, sizes):
        """
        creates the bars if they aren't already, else updates them

        :param sizes: sizes of bars
        :return:
        """
        bar_width = self.surface.get_rect().size[0] / self.size

        for i, y in enumerate(sizes):

            try:
                bar = self.bars[y]
                bar.position = Vector2D.custom(self.surface,
                                               i * bar_width,
                                               y - 1,
                                               inverty=True)
                continue
            except KeyError:
                bar = Rectangle(Vector2D.custom(self.surface,
                                                i * bar_width,
                                                y - 1,
                                                inverty=True),
                                Vector2D(bar_width, y),
                                color=Color.lerp(y / self.max, colors.RED,
                                                 colors.GREEN, colors.BLUE)
                                if self.color is None else self.color)

                self.bars[y] = bar
Example #7
0
    def center(self, position):
        size = self.surface.get_rect().size

        self.position = Vector2D(position.x - (size[0] / 2),
                                 position.y - (size[1] / 2))

        self.autocenter = True
Example #8
0
    def clean_grid(self, types, to=Tile.UNVISITED):
        """
        replaces all the state types in :param types: with state :param to:

        :param types: state types to replace
        :param to: replacement state
        """

        if Tile.END in types:
            self.end = None
            self.info_text.text = 'Select end'

        if Tile.START in types:
            self.start = None
            self.info_text.text = 'Select start'

        to = Tile.state_to_int(to)

        size = Vector2D(len(self.grid), len(self.grid[0]))
        for x in range(size.x):
            for y in range(size.y):
                tile = self.grid[x][y]

                if Tile.int_to_state(tile) in types:
                    self.grid[x][y] = to
Example #9
0
    def __init__(self,
                 text: Text,
                 size: Vector2D = None,
                 position: Vector2D = Vector2D.zero(),
                 color: Color = None,
                 onclick=None):
        super(Button, self).__init__()

        # look
        self.text = text
        self.size = size
        if self.size is None:
            self.size = Vector2D(100, 35)
        self._position = position

        self.text.center(Vector2D.center(self.position, self.size))

        # color
        if color is None:
            color = colors.TRANSPARENT
        self._mutable_color = color
        self._original_color = color

        # behaviour
        self.onhover = Hover(DIM_LIGHT, ORIGINAL_COLOR)
        self.onclick = onclick

        if self.onclick is None:
            self.onclick = lambda button: None
Example #10
0
 def print_grid(self):
     size = Vector2D(len(self.tiles), len(self.tiles[0]))
     for x in range(size.x):
         print('[', end='')
         for y in range(size.y):
             value = self.grid[x][y]
             print(value, end='')
             if y != size.y - 1:
                 print(', ', end='')
         print(']')
Example #11
0
 def print_grid(grid):
     size = Vector2D(len(grid), len(grid[0]))
     for x in range(size.x):
         print('[', end='')
         for y in range(size.y):
             value = grid[x][y]
             print(value, end='')
             if y != size.y - 1:
                 print(', ', end='')
         print(']')
Example #12
0
    def __init__(self, grid):
        self.grid = grid

        self.start = None
        self.end = None
        self.walls = []

        self.queue = []
        self.parent = {}
        self.gcost = {}

        self.path = ()

        self.current = None

        self.costgrid = []

        # analysis
        size = Vector2D(len(self.grid), len(self.grid[0]))
        for x in range(size.x):
            self.costgrid.append([-1] * size.y)

            for y in range(size.y):
                tile = self.grid[x][y]

                if Tile.int_to_state(tile) == Tile.START:
                    self.start = Vector2D(x, y)
                    self.costgrid[x][y] = 0

                elif Tile.int_to_state(tile) == Tile.END:
                    self.end = Vector2D(x, y)

                elif Tile.int_to_state(tile) == Tile.WALL:
                    self.walls.append(Vector2D(x, y))

        self.current = self.start
        self.gcost[tuple(self.current)] = 0

        self.solution_found = False
        self.solution_length = 0

        self.heuristic_modifier = 1.2
Example #13
0
    def text(self, text):
        self._text = text

        prev_rect = self.surface.get_rect()
        self.surface = self.font.render(self.text, True, self.color)

        # size changes depending on amount of text so position is changed
        self.position = Vector2D(
            self.position.x +
            (prev_rect.size[0] - self.surface.get_rect().size[0]) / 2,
            self.position.y)
Example #14
0
    def remake_tiles(self, grid):
        """
        recreates the whole tile grid for :param grid:

        :param grid: blueprint for recreation
        :return: None
        """
        size = Vector2D(len(grid), len(grid[0]))

        for x in range(size.x):
            for y in range(size.y):
                position = Vector2D(
                    y * self.tilesize.x + y * self.tilepadding.x + self.position.x + self.padding.x,
                    x * self.tilesize.y + x * self.tilepadding.y + self.position.y + self.padding.y,
                )

                tile = Tile(Tile.int_to_state(self.grid[x][y]), gridpos=Vector2D(x, y), position=position,
                            padding=Vector2D.zero())

                tile.size = self.tilesize

                self.tiles[x][y] = tile
Example #15
0
    def __init__(self,
                 text,
                 size=14,
                 italic=False,
                 color: Color = colors.BLACK,
                 font: Font = Roboto.MEDIUM):
        super(Text, self).__init__()

        self._text = text
        self._color = color

        self.font = font.get(size, italic)
        self.surface = self.font.render(text, True, color)
        self.position = Vector2D(0, 0)
Example #16
0
    def clean_grid(self, types, to=Tile.UNVISITED):
        if Tile.END in types:
            self.end = None
            self.info_text.text = 'Select end'

        if Tile.START in types:
            self.start = None
            self.info_text.text = 'Select start'

        to = Tile.state_to_int(to)

        size = Vector2D(len(self.grid), len(self.grid[0]))
        for x in range(size.x):
            for y in range(size.y):
                tile = self.grid[x][y]

                if Tile.int_to_state(tile) in types:
                    self.grid[x][y] = to
Example #17
0
    def get_viable_neigbours(self) -> List[Vector2D]:
        """
        :return: vectors of all the viable neighbours(tiles that you can move to) of the current positon (self.current)
        """
        vectors = []

        size = Vector2D(len(self.grid), len(self.grid[0]))
        for x in [self.current.x - 1, self.current.x, self.current.x + 1]:
            for y in [self.current.y - 1, self.current.y, self.current.y + 1]:

                # index out of range
                if x < 0 or x > size.x - 1 or y < 0 or y > size.y - 1:
                    continue

                # current pos
                if x == self.current.x and y == self.current.y:
                    continue

                tile = self.grid[x][y]
                state = Tile.int_to_state(tile)

                if state in [Tile.UNVISITED, Tile.NEIGHBOURS, Tile.END]:
                    vectors.append(Vector2D(x, y))

                    # update grid cost / path cost
                    grid_cost = self.costgrid[x][y]

                    g = self.g(self.current) + self.distance(
                        self.current, Vector2D(x, y))
                    if grid_cost == -1:
                        self.gcost[(x,
                                    y)] = self.g(self.current) + self.distance(
                                        self.current, Vector2D(x, y))
                    else:
                        if self.gcost[(x, y)] > g:
                            self.gcost[(x, y)] = g

                    # update cost
                    calculated_cost = self.g(Vector2D(x, y)) + self.h(
                        Vector2D(x, y)) * self.heuristic_modifier

                    if grid_cost == -1 or grid_cost > calculated_cost:
                        self.costgrid[x][y] = calculated_cost
                        self.parent[(x, y)] = self.current

                    if state != Tile.END:
                        self.grid[x][y] = Tile.state_to_int(Tile.NEIGHBOURS)

        return vectors
Example #18
0
from core import colors, Switch, Vector2D, Color
from widgets import Text, WidgetManager, Button, Hover

from grid import GridManager

pygame.init()
size = width, height = 650, 670
screen = pygame.display.set_mode(size)

pygame.display.set_caption('A* visualizer')

info = Text('', color=colors.WHITE)
manager = WidgetManager([info])

grid = GridManager(Vector2D(40, 40), info)

framerate = 0
t0 = time.time()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        grid.event(event)
        manager.event(event)

    screen.fill(colors.BLACK)

    grid.update()
Example #19
0
bars_range = range(len(bars.sizes))

# change this as necessary to change sorting algorithm
# sorta = CocktailSort(bars.sizes[:])
# sorta = InsertionSort(bars.sizes[:])
# sorta = CycleSort(bars.sizes[:])
# sorta = QuickSort(bars.sizes[:], 0, len(bars.sizes) - 1)
sorta = algorithms.MergeSort(bars.sizes[:])

# limit queue size to be safe
ac = AlgorithmController(sorta, maxsize=10000)
ac.start()

# button to control algorithm flow
flip_button = Button(Text('', color=colors.WHITE),
                     size=Vector2D(70, 25),
                     color=Color(0, 0, 0, 0),
                     onclick=lambda _: should_sort.flip())
flip_button.position = Vector2D(
    Vector2D.center(screen.get_rect(),
                    screen.get_rect().size).x - (flip_button.size.x / 2), 0)
flip_button.onhover = Hover(BLACK_TEXT_WHITE_BACKGROUND,
                            WHITE_TEXT_TRANSPARENT_BACKGROUND)


def fbflip(val):
    flip_button.text.text = 'RUNNING' if val else 'STOPPED'


fbflip(should_sort.get())
should_sort.on_flip = fbflip
Example #20
0
pygame.init()
size = width, height = 700, 720
screen = pygame.display.set_mode(size, pygame.DOUBLEBUF)

# allowed events
pygame.event.set_allowed([
    pygame.QUIT, pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP,
    pygame.MOUSEMOTION, pygame.KEYUP
])

pygame.display.set_caption('A* visualizer')

info = Text('', color=colors.WHITE)
manager = WidgetManager([info])

grid = GridManager(Vector2D(50, 50), info)

framerate = 0
t0 = time.time()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            AppDatabase.database().save()
            sys.exit()

        grid.event(event)
        manager.event(event)

    screen.fill(colors.BLACK)
Example #21
0
 def all_tiles(self):
     size = Vector2D(len(self.tiles), len(self.tiles[0]))
     for x in range(size.x):
         for y in range(size.y):
             yield self.tiles[x][y]
Example #22
0
    def draw(self, surface):
        size = Vector2D(len(self.tiles), len(self.tiles[0]))

        for x in range(size.x):
            for y in range(size.y):
                self.tiles[x][y].draw(surface)