Le code des animaux

J'ai du pour cela remanier le code gérant les animaux, qui était jusque là calqué sur celui gérant les objets. Mais ce qui était valide pour les objets (à savoir des tableaux Numeric d'objets, à raison d'un tableau par zone ou par paquet de 9 zones) ne l'est plus pour des animaux qui bougent et peuvent passer d'une zone à l'autre.

Je suis du coup passé à des dictionnaire, dont la clé est la position de l'animal dans la zone, et la valeur l'instance de l'animal en question :

# Dictionnaire des animaux présents sur la zone
# clé = position
# valeur = objet el_faune.animal
self.an = {}
    def Ajoute_Animal(self, poszone, animal):
        """
        Ajoute un animal à la position poszone
        à condition que la position soit accessible,
        n'ai pas d'objet dessus,
        et qu'il n'y ait pas déjà un animal dessus
        """
        if self.est_accessible[poszone] and self.ob[poszone] == 0:
            if not self.an.has_key(poszone):
                self.an[poszone] = animal
                return True
        return False

Le dictionnaire joueur.z33_an contient l'ensemble des animaux présents dans les 9 zones autour du joueur.

Bouge de là !

Pour ensuite déplacer les animaux, on fait appel à la fonction Gere_Animaux à chaque fois qu'un tour passe:

    def Gere_Animaux(self):
        """
        Passage en revue de tous les animaux
        """
        # Dico temporaire
        z33_antemp = {}
        
        for pos_animal in self.z33_an:
            d = el.dist33(pos_animal, self.pos33)
            animal = self.z33_an[pos_animal]
            if d == 1:
                # L'animal attaque le joueur
                z33_antemp[pos_animal] = animal
            elif d < 8:
                # L'animal suit le joueur
                dep = False # Passe à True si une position plus proche est trouvée
                dirs = list(el.dirs)
                random.shuffle(dirs)
                for i in range(len(dirs)):
                    pos = (pos_animal[0] + dirs[i][0], pos_animal[1] + dirs[i][1])
                    dist = el.dist33(pos, self.pos33)
                    if self.z33_accessible[pos] and not z33_antemp.has_key(pos) \
                    and not self.z33_an.has_key(pos) and dist < d\
                    and (pos[0] <> self.pos33[0] or pos[1] <> self.pos33[1]):
                        z33_antemp[pos] = animal
                        dep = True
                        break
                if not dep:
                    # L'animal reste immobile
                    z33_antemp[pos_animal] = animal

            else:
                z33_antemp[pos_animal] = animal
                
        self.z33_an = z33_antemp

On étudie les 8 positions autour de chaque animal à proximité du joueur. Si une de ces positions est plus proche du joueur que la position actuelle de l'animal, alors l'animal se déplace vers cette position (à condition également qu'elle soit accessible, qu'il n'y ait pas d'autre animal ou le joueur dessus). Ici, une petite astuce, on mélange aléatoirement la liste des 8 positions envisagées, pour se débloquer des cas simples (par exemple, si le joueur tourne au coin d'une maison).

Résultat, avec ce bout de code plutôt simple, on se retrouve avec des hordes d'animaux aux basques, comme sur cette capture d'écran :

Bouge de là