Des fourmis et des phéromones - 3ème partie

Avec un peu de retard, la pénultième partie

Je pense en effet que la prochaine sera la dernière, même s’il reste du boulot pour avoir des fourmis moins bêtes…

Comme expliqué lors de la seconde partie (oui, on peut dire second(e) même s’il y en a plus que deux), on va mettre en place les phéromones. Pour ça, pas besoin de changer le fichier ant.py, les phéromones sont gérés dans le fichier principal, et lors de l’affichage.

simu.py

Pour gérer les phéromones, on va utiliser un dictionnaire : pour chaque taux de phéromones présent, on associe la liste des coordonnées sur la grille pour lesquelles il y a des phéromones à ce taux. Ça permet de reconstruire un tableau à deux dimensions qui contient le taux des phéromones. On le déclare dans l’initialisation :

self.phero = {} # { taux : [liste de [x, y]]}

Ensuite, on va changer notre fonction animate pour mettre à jour le dictionnaire de phéromones :

  1. à chaque étape, les phéromones s’évaporent un peu ;
  2. on reconstruit ensuite le tableau des phéromones ;
  3. chaque fourmi dépose un peu de phéromones avant de se déplacer.
#atténuation des phéromones présentes (5 de moins à chaque endroit)
newPhero = {}
for lLev in self.phero:
    newLev = lLev - 5
    if (newLev > 0):
        newPhero[newLev] = self.phero[lLev]
self.phero = newPhero

#reconstruction de la grille des phéromones
gridPhero = [[0 for _ in range(self.ymax)] for _ in range(self.xmax)]
for lLev in self.phero:
    for [i, j] in self.phero[lLev]:
        gridPhero[i][j] = lLev

self.compteur += 1
for fourmi in self.lAnts:
    ##ajout de la phéromone
    ###on récupère l'ancienne valeur
    oldPhero = gridPhero[fourmi.coord[0]][fourmi.coord[1]]
    ###s'il y avait des phéromones, on enlève l'ancienne valeur
    if oldPhero:
        if fourmi.coord in self.phero.get(oldPhero):
            self.phero.get(oldPhero).remove(fourmi.coord)
    ###on met à jour avec la nouvelle valeur (50 de plus)
    gridPhero[fourmi.coord[0]][fourmi.coord[1]] = oldPhero + 50
    self.phero.setdefault(oldPhero + 50, []).append(fourmi.coord[:])

    ##déplacement de la fourmi
    fourmi.move()

#maj de la grille
self.centralWidget.animate(self.phero)

La dernière étape consistant à rafraîchir le widget central en lui donnant le dictionnaire des phéromones.

display.py

Là aussi, seule la fonction animae change vraiment. À chaque rafraîchissement on va :

  1. supprimer les anciennes phéromones ;
  2. ajouter les nouvelles ;
  3. déplacer les fourmis.

Tout comme les fourmis, on gère les phéromones par des petits rectangles que l’on ajoute/supprime de la scène :

#on supprime de la scène les anciens carrés de phéromones
if self.lPhero:
    print len(self.lPhero)
    for phero in self.lPhero:
        self.scene.removeItem(phero)
        self.lPhero.remove(phero)

#et on ajoute les nouveaux
for lLev in dictPhero:
    for phero in dictPhero[lLev]:
        item = self.scene.addRect(phero[0]*w/x, phero[1]*h/y, w/x, h/y, self.pen,
                           QtGui.QBrush(QtGui.QColor(max(0, 255 - lLev), 255, 255)))
        item.setZValue(1)
        self.lPhero.append(item)

#et on déplace les fourmis
for (nitem, ant) in enumerate(self.lAnts):
    [i, j] = ant.coord
    item = self.lItems[nitem]
    item.setRect(i*w/x, j*h/y, w/x, h/y)
    #que l'on place au premier plan
    item.setZValue(2)

Rien de bien compliqué en somme… Comme d’hab, les sources sont sur bitbucket. La prochaine fois, les fourmis seront moins crétines et arriveront à détecter les phéromones pour être guidées vers de la nourriture et rentrer au bercail.

Autres billets

Date: <2013-03-01>

Generated by Emacs 24.3.1 (Org mode 8.2.4) - Show Org source (htmlized)

CSS inspired by Tontof, colors by Chaotic Soul

Validate