예제 #1
0
    def drawWall(cls,
                 p1: Position,
                 p2: Position,
                 vertical: bool = False,
                 horizontal: bool = False) -> None:
        """
        Affiche une ligne de plusieurs murs

        INPUT :
            p1 : Position, position de la première cellule
            p2 : Position, position de la dernière cellule
            vertical : bool, si c'est un mur vertical
            horizontal : bool, si c'est un mur horizontal

        EXCEPTIONS :
            ValueError : si l'état du mur est inconnu, ou si aucune couleur
                         n'est associée à l'état
        """

        if vertical:
            p1_screen = (p1 + (0.5, 0)) * cls.cell_size
            p2_screen = (p2 + (0.5, 1)) * cls.cell_size
            etat = Map.getWall(p1)
        else:
            p1_screen = (p1 + (0, 0.5)) * cls.cell_size
            p2_screen = (p2 + (1, 0.5)) * cls.cell_size
            etat = Map.getWall(p1)

        if etat != Map.EMPTY:
            width = cls.WALL_WIDTH

            if etat == Map.RED_WALL:
                # Si c'est un mur rouge, on le met en gras

                width = 5

            try:
                color = cls.color_scheme[etat]
            except KeyError as e:
                raise ValueError("État de mur inconnu : " + str(etat)) from e

            # On dessine une ligne allant de p1 à p2
            cls.grille.create_line(p1_screen.x,
                                   p1_screen.y,
                                   p2_screen.x,
                                   p2_screen.y,
                                   fill=color,
                                   width=width)
예제 #2
0
    def applyAlgorith(self):
        left_dir = Direction.all_directions[(self.dir_id +
                                             self.increment_direction_id) % 4]
        front_dir = Direction.all_directions[self.dir_id % 4]

        self.move_forward = True

        if Map.isWallPosValid(self.new_p + left_dir / 2) and Map.getWall(
                self.new_p + left_dir / 2) == Map.EMPTY:
            # Si le mur de droite est valide et est vide...

            self.dir_id += self.increment_direction_id
            # On tourne dans la direction choisie
        elif not Map.isCellPosValid(self.new_p + front_dir) or Map.getWall(
                self.new_p + front_dir / 2) == Map.WALL:
            # Sinon si la case devant est hors du plateau ou il y a un mur en face...

            self.dir_id += (self.increment_direction_id + 2) % 4
            # On tourne dans la direction opposée

            self.move_forward = False

        left_dir = Direction.all_directions[(self.dir_id +
                                             self.increment_direction_id) % 4]
        front_dir = Direction.all_directions[self.dir_id % 4]
        # On recalcule les directions

        if self.move_forward:
            # S'il faut avancer on avance
            self.old_p = Position(self.new_p)
            self.new_p = self.new_p + front_dir
            self.go_forward_frame += 1

        self.nb_iter += 1

        if self.nb_iter == 4 * Map.width * Map.height:
            raise GenericResolution.NoSolutionError()
예제 #3
0
    def getRandomDirection(p: Position) -> (Direction, None):
        """
        Fonction permettant d'obtenir une direction aléatoire valide.

        INPUT :
            p : Position, une position
            visited_pos : list liste tuple, la liste des cases déjà visitées

        OUTPUT :
            res : Direction ou None si aucune direction n'est valide
        """

        list_dir = Direction.getRandomDirectionList()
        # On récupère les directions triées aléatoirement

        res = None

        for dir in list_dir:
            new_p = p + dir

            if Map.isCellPosValid(new_p):
                # Si la nouvelle case est bien dans le plateau
                """
                if visited_pos[new_p.x][new_p.y] is None:
                    # Si cette nouvelle case n'a jamais été visitée

                    if Map.getWall(p + dir/2) == Map.WALL:
                        # S'il y a bien un mur à briser

                        res = dir
                """

                if Map.getWall(p + dir / 2) == Map.WALL:
                    # S'il y a bien un mur à briser

                    res = dir

        return res
예제 #4
0
    def draw(cls) -> None:
        """
        Procédure pour dessiner à l'écran.
        """

        t1 = time.time()
        # Repère temporel pour savoir la durée d'un affichage

        if not cls.is_running:
            # Si la fenêtre est fermée on arrête
            return

        cls.grille.delete(Tk.ALL)
        # On réinitialise la grille

        ########################################################################
        # On dessine les cellules

        # On va parcourir la map ligne par ligne
        # pour chercher les cellules adjacentes de même couleur
        # pour ne dessiner qu'un seul rectange plutot que plusieurs carrés.
        # tkinter supporte mal plusieurs centaines de formes à afficher

        for y in range(Map.height):
            first_p = Position((0, y))
            old_p = Position(first_p)

            for x in range(Map.width):
                new_p = Position((x, y))

                if Map.getCell(first_p) == Map.getCell(new_p):
                    pass
                else:
                    cls.drawCell(first_p, old_p)
                    first_p = Position(new_p)

                old_p = Position(new_p)

            cls.drawCell(first_p, old_p)

        ########################################################################
        # On dessine les murs

        # Murs verticaux
        for x in range(Map.width - 1):
            first_p = Position((x + 0.5, 0))
            old_p = Position(first_p)

            for y in range(Map.height):
                new_p = Position((x + 0.5, y))

                if Map.getWall(first_p) == Map.getWall(new_p):
                    pass
                else:
                    cls.drawWall(first_p, old_p, vertical=True)

                    first_p = Position(new_p)

                old_p = Position(new_p)

            cls.drawWall(first_p, old_p, vertical=True)

        # Murs horizontaux
        for y in range(Map.height - 1):
            first_p = Position((0, y + 0.5))
            old_p = Position(first_p)

            for x in range(Map.width):
                new_p = Position((x, y + 0.5))

                if Map.getWall(first_p) == Map.getWall(new_p):
                    pass
                else:
                    cls.drawWall(first_p, old_p, horizontal=True)

                    first_p = Position(new_p)

                old_p = Position(new_p)

            cls.drawWall(first_p, old_p, horizontal=True)

        ########################################################################
        # On dessine les 4 murs extérieurs

        # Mur vertical gauche
        cls.grille.create_line(3,
                               0,
                               3,
                               Map.height * cls.cell_size,
                               fill=Display.BLACK,
                               width=cls.WALL_WIDTH)

        # Mur vertical droit
        cls.grille.create_line(cls.width,
                               0,
                               cls.width,
                               Map.height * cls.cell_size,
                               fill=Display.BLACK,
                               width=cls.WALL_WIDTH)

        # Mur horizontal en haut
        cls.grille.create_line(0,
                               3,
                               Map.width * cls.cell_size,
                               3,
                               fill=Display.BLACK,
                               width=cls.WALL_WIDTH)

        # Mur horizontal en bas
        cls.grille.create_line(0,
                               Map.height * cls.cell_size,
                               Map.width * cls.cell_size,
                               Map.height * cls.cell_size,
                               fill=Display.BLACK,
                               width=cls.WALL_WIDTH)

        cls.frame_count += 1

        cls.updateTitle()

        delta_t = time.time() - t1
        # Calcul du temps mis

        cls.draw_time = delta_t

        cls.window.after(1, cls.beforeDraw)