예제 #1
0
파일: entity.py 프로젝트: PIRXrav/pyhack
class Sword:
    """
    coup d'épée venant du joueur
    """
    DELTA_POSS = list(Vect(0, 0).g_rect(Vect(1, 1)))

    def __init__(self, pos, dammage):

        self.pos = pos
        self.cpt = len(self.DELTA_POSS) - 1
        self.dammage = dammage

    def update(self, mat_collide, player_pos):
        """
        Met à jour l'enemie
        """

        if self.cpt < 0:
            return True

        self.pos = player_pos + self.DELTA_POSS[self.cpt]
        self.cpt -= 1
        return False

    def render(self):
        """
        render
        """
        return chars.C_SWORDS[-self.cpt % len(chars.C_SWORDS)]
예제 #2
0
파일: entity.py 프로젝트: PIRXrav/pyhack
    def __init__(self):
        """
        Personnage
        """
        self.pos = Vect(0, 0)
        self.direction = Vect(1, 0)
        self.distance_view = 7

        self.bullet = self.BULLET_MAX
        self.hp = self.HP_MAX
        self.level = 0
        self.money = self.START_MONEY
        self.sword_damage = 1
        self.gun_damage = 2
예제 #3
0
    def __init__(self):
        """
        Initialise l'affichage
        """
        # Sauvegarde du terminal
        self._my_fd = sys.stdin.fileno()
        self._old = termios.tcgetattr(self._my_fd)

        # Désactivation echo stdin
        new = termios.tcgetattr(self._my_fd)
        new[3] = new[3] & ~termios.ECHO  # lflags
        termios.tcsetattr(self._my_fd, termios.TCSADRAIN, new)
        # Lancement ecran second + Désactivation curseur
        print("\033[?1049h\033[H" + "\033[?25l", end="")
        sys.stdout.flush()
        # Bufferisarion de stdout
        self._BUFFER_SIZE = 500 * 500
        sys.stdout = open(sys.stdout.fileno(), "w", self._BUFFER_SIZE)

        # Méthodes d'édition
        self.my_print = sys.stdout.write
        self.my_flush = sys.stdout.flush

        # Taille de l'écran
        self.size = Vect(0, 0)
예제 #4
0
파일: entity.py 프로젝트: PIRXrav/pyhack
 def update(self, mat_collide, depl_vect):
     """
     Met à jour la position du personnage en fonction des evenements
     et de mat_collide
     """
     if depl_vect != Vect(0, 0):
         self.direction = depl_vect
         new_pos = self.pos + depl_vect
         # Tests de collision (Diagonales)
         if mat_collide[new_pos.x][self.pos.y]:
             # premier chemin libre en x
             if mat_collide[new_pos.x][new_pos.y]:
                 # deuxieme chemin libre en y
                 self.pos = new_pos
             else:
                 # deuxieme chemin bloque en y
                 self.pos.x = new_pos.x
         elif mat_collide[self.pos.x][new_pos.y]:
             # premier chemin libre en y
             if mat_collide[new_pos.x][new_pos.y]:
                 # deuxieme chemin libre en x
                 self.pos = new_pos
             else:
                 # deuxieme chemin bloque en x
                 self.pos.y = new_pos.y
         else:
             # Aucun chemin libre
             # Do nothind
             pass
예제 #5
0
 def g_xy(self):
     """
     Generateur sur tous les points de la salle
     """
     for x in range(self.size.x):
         for y in range(self.size.y):
             yield self.p[0] + Vect(x, y)
예제 #6
0
def main():
    """
    TU
    """
    tab = [[1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
           [1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
           [1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
           [1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
           [1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]

    start = Vect(0, 0)
    end = Vect(7, 6)

    path = calc_path_astart(tab, start, end)
    assert len(path), 'erreur A*'
    print(path)
예제 #7
0
파일: core.py 프로젝트: PIRXrav/pyhack
 def get_user_depl(events):
     """
     retourne le vecteur de deplacement
     """
     # position desire (componsation des fleches opposées)
     return Vect(
         int(Key.right in events) - int(Key.left in events),
         int(Key.up in events) - int(Key.down in events))
예제 #8
0
 def g_pos(self):
     """
     Retourne un générateur sur tous les position de l'écran
     dans l'ordre d'affichage
     """
     for scr_y in range(self.size.y - 1, 0, -1):
         for scr_x in range(self.size.x):
             yield Vect(scr_x, scr_y)
예제 #9
0
 def get_size(self):
     """
     Met a jour la taille de l'écran
     """
     # bof ...
     H, W = map(int, os.popen('stty size', 'r').read().split())
     assert H * W <= self._BUFFER_SIZE
     self.size = Vect(W, H)
     return self.size
예제 #10
0
 def g_xyCollide(self):
     """
     Retourne les points accessible a @
     Retourne un génerateur de Vect
     Permet la création de matrice des collision
     """
     for x in range(1, self.size.x - 1):
         for y in range(1, self.size.y - 1):
             yield self.p[0] + Vect(x, y)
예제 #11
0
def calc_path_astart(mat_collide, start, end):
    """
    Couche de compatibilite
    """
    return list(
        map(
            lambda tup: Vect(tup[0], tup[1]),
            astar(numpy.array(mat_collide), (start.x, start.y),
                  (end.x, end.y))))
예제 #12
0
파일: entity.py 프로젝트: PIRXrav/pyhack
 def g_case_visible(self, mat_collide):
     """
     retourne sur toutes les cases visibles
     par self dans mat_collide
     """
     # Nb : prend les segments depuis un cercle et non un rect
     # n'est pas OK
     border = self.pos.g_rect(Vect(self.distance_view, self.distance_view))
     for bordure_pos in border:
         for pos in self.pos.g_bresenham_line(bordure_pos):
             if self.pos.distance(pos) >= self.distance_view:
                 break
             if not Vect(0, 0) <= pos < Vect(len(mat_collide),
                                             len(mat_collide[0])):
                 break
             if not mat_collide[pos.x][pos.y]:
                 yield pos
                 break
             yield pos
예제 #13
0
def main():
    """
    Entry point
    """
    try:

        SIZE_Y = 30
        SIZE_X = 60
        screen = [[True for _ in range(SIZE_Y + 2)] for _ in range(SIZE_X + 2)]

        for _ in range(4):
            p1 = Vect(0, 0) | Vect(SIZE_X, SIZE_Y)
            p2 = Vect(0, 0) | Vect(SIZE_X, SIZE_Y)
            for pos in p1.g_bresenham_line(p2):
                screen[pos.x][pos.y] = False
                screen[pos.x + 1][pos.y] = False

        # Calculs
        center = Vect(30, 15)
        for pos in g_case_visible(screen, center, 10):
            screen[pos.x][pos.y] = 'F'

        screen[center.x][center.y] = '@'

        # affichage
        for y in range(SIZE_Y):
            for x in range(SIZE_X):
                char = screen[x][SIZE_Y - y - 1]
                if char is False:
                    print_char = "\033[0;34;41m" + ' ' + "\033[0m"
                if char is True:
                    print_char = ' '
                if char == 'F':
                    print_char = "\033[0;34;43m" + ' ' + "\033[0m"
                if char == '@':
                    print_char = "\033[0;31;45m" + ' ' + "\033[0m"
                if char == 'B':
                    print_char = "\033[0;34;40m" + 'X' + "\033[0m"
                print(print_char, end='')
            print("")
    finally:
        print("END")
예제 #14
0
def g_case_visible(tab_collide, center, radius):
    """
    retourne sur toutes les cases visibles
    depuis un point center dans un rayon radius
    """
    # Nb : prend les segments depuis un cercle et non un rect
    # n'est pas OK
    border = center.g_rect(Vect(radius, radius))
    for bordure_pos in border:
        for pos in center.g_bresenham_line(bordure_pos):
            if center.distance(pos) >= radius:
                break
            if not tab_collide[pos.x][pos.y]:
                break
            yield pos
예제 #15
0
파일: core.py 프로젝트: PIRXrav/pyhack
        def render_menu():
            """
            Render state = menu
            """
            # for scr in g_scr_pos:
            #    self.buffer_window[scr.x][scr.y] = ' '

            scr_center = scr_size // 2
            box_cote = Vect(scr_size.x // 4, scr_size.y // 8)
            for pos in scr_center.g_rect(box_cote):
                self.buffer_window[pos.x][pos.y] = chars.C_PAUSE_BORDER
            for pos in scr_center.g_rect_fill_no_border(box_cote):
                self.buffer_window[pos.x][pos.y] = chars.C_PAUSE_FILL

            for i, char in enumerate("texte"):
                self.buffer_window[scr_center.x - 3 + i][scr_center.y] = char
예제 #16
0
    def __init__(self, pos_xmax, pos_ymax):
        """
        initialise une pièce
                p[1]        p[2]
                +---------+ (X2, Y2) : self.p[2]
                |    L    |
                |H   C   H|         X2 = X0 + L - 1
                |    L    |         Y2 = X0 + H - 1
                +---------+         (L, H) : self.size
        (X0, Y0)p[0]        p[3]
        pos_max est un point existant

        """
        pmax = Vect(pos_xmax, pos_ymax)
        self.size = (self._VECT_COTE_MIN | self._VECT_COTE_MAX) + Vect(2, 2)
        self.p = [None for _ in range(4)]
        self.p[0] = Vect(0, 0) | (pmax - self.size)
        norm_size = self.size - Vect(1, 1)
        self.p[1] = self.p[0] + (norm_size & Vect(False, True))
        self.p[2] = self.p[0] + (norm_size & Vect(True, True))
        self.p[3] = self.p[0] + (norm_size & Vect(True, False))
        self.center = self.p[0] + norm_size // 2
예제 #17
0
    def connect(self, other_room):
        """
        crée le chemin entre les deux salles
        """
        assert not self.isRoomCollide(other_room), "Les salles se superposent"

        door1 = self.newRandomPointInRoom()
        door2 = other_room.newRandomPointInRoom()

        path = []

        m = randint(0, 1)
        depl = door1.dirrectionTo(door2) & Vect(m, 1 - m)

        if depl == Vect(1, 0):
            door1.x = self.p[2].x
            door2.x = other_room.p[0].x
        elif depl == Vect(-1, 0):
            door1.x = self.p[0].x
            door2.x = other_room.p[2].x
        elif depl == Vect(0, 1):
            door1.y = self.p[2].y
            door2.y = other_room.p[0].y
        elif depl == Vect(0, -1):
            door1.y = self.p[0].y
            door2.y = other_room.p[2].y
        cur_point = door1 + depl
        # On crée un chemin tant que l'on arrive pas dans la other_room
        while cur_point != door2:
            path.append(cur_point)
            # Deplacement en x ou y aléatoire
            m = randint(0, 1)
            cur_point += cur_point.dirrectionTo(door2) & Vect(m, 1 - m)

        assert len(path) >= self._OFFSET_COLLIDE, 'Chemin trop court'
        # On retourne un tripet porte, chemin, porte
        return (door1, path, door2)
예제 #18
0
 def vect(self):
     vect = Vect(self._name, self._executions)
     return vect
예제 #19
0
 def newRandomPointInRoom(self):
     """
     Retourne un point dans la pièce (Pas dans les murs)
     """
     return (self.p[0] + Vect(1, 1)) | (self.p[2] - Vect(1, 1))
예제 #20
0
 def isPointCollideWithMargin1(self, point):
     """
     Retourne si le point touche la salle avec une marge de 1 vers l'exterieur
     """
     return self.p[0] - Vect(1, 1) <= point <= self.p[2]
예제 #21
0
파일: core.py 프로젝트: PIRXrav/pyhack
 def isScrPosInScr(scr_pos):
     return Vect(0, 0) <= scr_pos < scr_size
예제 #22
0
파일: core.py 프로젝트: PIRXrav/pyhack
        def render_run():
            """
            Render state = run
            """
            def scr2mat(scr_pos):
                return scr_pos + self.player.pos - scr_size // 2

            def mat2scr(mat_pos):
                return mat_pos - self.player.pos + scr_size // 2

            def isScrPosInScr(scr_pos):
                return Vect(0, 0) <= scr_pos < scr_size

            # Rendu du fond
            for scr in g_scr_pos:
                mat_pos = scr2mat(scr)
                # Dans matrice et Visible
                if Vect(0, 0) <= mat_pos < Vect(self._XMAX, self._YMAX) and \
                   (self.mat_view[mat_pos.x][mat_pos.y] or self.RULE_VISION):
                    self.buffer_window[scr.x][scr.y] = \
                        self.mat_render[mat_pos.x][mat_pos.y]
                else:
                    self.buffer_window[scr.x][scr.y] = ' '

            # Rendu des entitées
            for entity in chain(self.bullets, self.swords, self.monsters,
                                self.treasure, [self.player], [self.door]):
                scr_pos = mat2scr(entity.pos)
                if isScrPosInScr(scr_pos) \
                   and self.mat_view[entity.pos.x][entity.pos.y] \
                   or self.RULE_VISION:
                    self.buffer_window[scr_pos.x][scr_pos.y] = entity.render()

            # Rendu du joueur
            scr_pos = mat2scr(self.player.pos)
            self.buffer_window[scr_pos.x][scr_pos.y] = self.player.render()

            # Text
            top_bar = "Town : Koku <> ./ [***] " + os_info
            bot_bat1 = str(self.player) + " \
                       | Monsters : " + str(len(self.monsters))
            bot_bat2 = ("[" +
                        str(chars.C_BAR_DECORATIONS[self.cpt_monster % 4]) +
                        "]" + "| Level : " + str(self.player.level) +
                        "| Gold : " + str(self.player.money) + "| Sword : " +
                        str(self.player.sword_damage) + "| Gun : " +
                        str(self.player.gun_damage) + "| Monster lvl : " +
                        str(self.monster_life))

            for i, ch in enumerate(
                    zip_longest(top_bar,
                                bot_bat1,
                                bot_bat2,
                                range(scr_size.x),
                                fillvalue=' ')):
                self.buffer_window[i][scr_size.y - 1] = (ch[0])
                self.buffer_window[i][1] = (ch[1])
                self.buffer_window[i][2] = (ch[2])

            # Bousolle
            for y, string in enumerate(
                ["   N   ", "   ^   ", "W<-o->E", "   v   ", "   S   "]):
                for x, char in enumerate(string):
                    self.buffer_window[scr_size.x - 7 + x][5 - y] = (char)
예제 #23
0
class Room():
    """
    Classe définissant une pièce. Elle permet de l'initialiser
    et de la connecter à d'autres.
    """
    # Dimentions maximales minimales
    _VECT_COTE_MIN = Vect(10, 6)
    _VECT_COTE_MAX = Vect(10, 8)

    # Espace autour de la pièce
    _OFFSET_COLLIDE = 2

    def __init__(self, pos_xmax, pos_ymax):
        """
        initialise une pièce
                p[1]        p[2]
                +---------+ (X2, Y2) : self.p[2]
                |    L    |
                |H   C   H|         X2 = X0 + L - 1
                |    L    |         Y2 = X0 + H - 1
                +---------+         (L, H) : self.size
        (X0, Y0)p[0]        p[3]
        pos_max est un point existant

        """
        pmax = Vect(pos_xmax, pos_ymax)
        self.size = (self._VECT_COTE_MIN | self._VECT_COTE_MAX) + Vect(2, 2)
        self.p = [None for _ in range(4)]
        self.p[0] = Vect(0, 0) | (pmax - self.size)
        norm_size = self.size - Vect(1, 1)
        self.p[1] = self.p[0] + (norm_size & Vect(False, True))
        self.p[2] = self.p[0] + (norm_size & Vect(True, True))
        self.p[3] = self.p[0] + (norm_size & Vect(True, False))
        self.center = self.p[0] + norm_size // 2

    def newRandomPointInRoom(self):
        """
        Retourne un point dans la pièce (Pas dans les murs)
        """
        return (self.p[0] + Vect(1, 1)) | (self.p[2] - Vect(1, 1))

    def g_corners(self):
        """
        Retourne les 4 coins de la salle
        """
        return (point for point in self.p)

    def isPointCollide(self, point):
        """
        Retourne si le point touche la salle (mur inclus)
        """
        return self.p[0] <= point <= self.p[2]

    def isPointCollideWithMargin1(self, point):
        """
        Retourne si le point touche la salle avec une marge de 1 vers l'exterieur
        """
        return self.p[0] - Vect(1, 1) <= point <= self.p[2]

    def isRoomCollide(self, other_room):
        """
        Retourne si l'autre salle est en Collision
        A une distance (offset) près
        """
        offset = self._OFFSET_COLLIDE
        # La distance minimale entre les salles
        if other_room.p[0].x >= self.p[0].x + self.size.x + offset or \
           other_room.p[0].x + other_room.size.x + offset <= self.p[0].x or \
           other_room.p[0].y >= self.p[0].y + self.size.y + offset or \
           other_room.p[0].y + other_room.size.y + offset <= self.p[0].y:
            return False
        return True

    def connect(self, other_room):
        """
        crée le chemin entre les deux salles
        """
        assert not self.isRoomCollide(other_room), "Les salles se superposent"

        door1 = self.newRandomPointInRoom()
        door2 = other_room.newRandomPointInRoom()

        path = []

        m = randint(0, 1)
        depl = door1.dirrectionTo(door2) & Vect(m, 1 - m)

        if depl == Vect(1, 0):
            door1.x = self.p[2].x
            door2.x = other_room.p[0].x
        elif depl == Vect(-1, 0):
            door1.x = self.p[0].x
            door2.x = other_room.p[2].x
        elif depl == Vect(0, 1):
            door1.y = self.p[2].y
            door2.y = other_room.p[0].y
        elif depl == Vect(0, -1):
            door1.y = self.p[0].y
            door2.y = other_room.p[2].y
        cur_point = door1 + depl
        # On crée un chemin tant que l'on arrive pas dans la other_room
        while cur_point != door2:
            path.append(cur_point)
            # Deplacement en x ou y aléatoire
            m = randint(0, 1)
            cur_point += cur_point.dirrectionTo(door2) & Vect(m, 1 - m)

        assert len(path) >= self._OFFSET_COLLIDE, 'Chemin trop court'
        # On retourne un tripet porte, chemin, porte
        return (door1, path, door2)

    def distance(self, other_room):
        """
        Retourne la distance entre deux salles (Des centres)
        """
        return self.p[0].distanceSquare(other_room.p[0])

    def g_xy(self):
        """
        Generateur sur tous les points de la salle
        """
        for x in range(self.size.x):
            for y in range(self.size.y):
                yield self.p[0] + Vect(x, y)

    def g_xyRender(self, middle_char):
        """
        Indique le type de char a chaque xy :
        Retourne un couple ! (Vect , char)
        """
        from tableborder import BORDERS
        line_style = 2
        for pos in self.g_xy():
            if pos == self.p[0]:
                type_char = BORDERS[line_style].low_left
            elif pos == self.p[1]:
                type_char = BORDERS[line_style].top_left
            elif pos == self.p[2]:
                type_char = BORDERS[line_style].top_right
            elif pos == self.p[3]:
                type_char = BORDERS[line_style].low_right
            elif pos.x == self.p[0].x or pos.x == self.p[2].x:
                type_char = BORDERS[line_style].vertical
            elif pos.y == self.p[0].y or pos.y == self.p[2].y:
                type_char = BORDERS[line_style].horizontal
            else:
                type_char = middle_char
            yield (pos, type_char)

    def g_xyCollide(self):
        """
        Retourne les points accessible a @
        Retourne un génerateur de Vect
        Permet la création de matrice des collision
        """
        for x in range(1, self.size.x - 1):
            for y in range(1, self.size.y - 1):
                yield self.p[0] + Vect(x, y)