civilisation.individu.Human.java Source code

Java tutorial

Introduction

Here is the source code for civilisation.individu.Human.java

Source

/*
 * TurtleKit - An Artificial Life Simulation Platform
 * Copyright (C) 2000-2010 Fabien Michel, Gregory Beurier
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package civilisation.individu;

import java.awt.Color;
import java.awt.Graphics;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.io.Serializable;

import madkit.kernel.AgentAddress;

import org.jfree.chart.JFreeChart;

import civilisation.Civilisation;
import civilisation.Communaute;
import civilisation.Configuration;
import civilisation.DefineConstants;
import civilisation.amenagement.Amenagement;
import civilisation.amenagement.Amenagement_Efficacite;
import civilisation.amenagement.Amenagement_Route;
import civilisation.amenagement.TypeAmenagement;
import civilisation.group.Group;
import civilisation.group.GroupModel;
import civilisation.group.MessageString;
import civilisation.individu.cognitons.TypeCogniton;
import civilisation.inventaire.NInventaire;
import civilisation.inventaire.Objet;
import civilisation.pathfinder.Noeud;
import civilisation.world.World;
import civilisation.zones.ZoneComposite;
import civilisation.zones.ZoneElementaire;
import turtlekit.kernel.Turtle;
import turtlekit.kernel.Patch;

/** 
 * Main simulation agent.
 * Linked to a mind to select actions to do.
*/

@SuppressWarnings("serial")
public class Human extends Turtle implements Serializable {
    boolean leaveTrail = true;

    int visionRadius;
    Civilisation civ;
    Communaute communaute;
    //ArrayList<Batiment> privateBuildings;
    //ArrayList<Amenagement> privateFacilities;
    NInventaire inventaire;

    //Cible des interactions
    Human cibleInteraction = null;
    //Human qui lance une interaction sur cet humain
    Human initiateurInteraction = null;
    //Degats que l'individu inflige lors d'une I_Attaquer
    int degats = 1;
    public Amenagement targetMove = null;

    //Variable de chef et d'employs
    public Human chef = null;
    public ArrayList<Human> employes = new ArrayList<Human>();

    //Compteur L_Action everyXtick
    public int compteurTick = 0;

    //Valeur reduite sur un amenagement efficace
    public int strike = 1;

    public Boolean enMission = false;

    Patch cible = null;
    Human pere;
    Human mere;
    Human conjoint;
    Boolean woman;
    ArrayList<Human> enfants;
    String debugString;

    private static ArrayList<HumainListener> listeners = new ArrayList<HumainListener>();

    HashMap<String, Amenagement> privateFacilities = new HashMap<String, Amenagement>();
    HashMap<String, Double> attributes;

    /* For map drawing */
    public boolean isSelected = false;
    public boolean isShowGroup = false;
    public boolean isDie = false;

    Esprit esprit; //Mind controlling decision making of the agent

    ArrayList<Patch> chemin;
    int tempsPatch;
    ZoneElementaire champs;
    ZoneElementaire bois;

    public Human(Civilisation civ, Communaute communaute) {
        super("penser");
        pere = null;
        mere = null;
        initialisation(civ, communaute);
        chemin = new ArrayList<Patch>();
        tempsPatch = 2;
        bois = new ZoneElementaire();
        champs = new ZoneElementaire();
    }

    /**
     * Constructeur si l'agent ____________ des parents
     */
    public Human(Civilisation civ, Communaute communaute, Human pere, Human mere) {
        super("penser");
        this.pere = pere;
        this.mere = mere;
        initialisation(civ, communaute);
        chemin = new ArrayList<Patch>();
        tempsPatch = 2;
        bois = new ZoneElementaire();
        champs = new ZoneElementaire();
    }

    public void die() {

        //System.out.println("------------------------------------------------");
        //System.out.println("Un agent est mort au cours du projet : " + this.getEsprit().getPlanEnCours());
        //System.out.println("Vie : " + this.getVie());
        //if(this.chemin != null) System.out.println("Chemin : " + this.chemin);
        //System.out.println("Inventaire" + this.inventaire);

        //Utils.afficherTrace();
        //System.out.println("-------------------******-----------------------");

        //this.getEsprit().clearAllCognitons();   /*TODO*/
        isDie = true; //TODO : verifier
        //System.out.println("nb litnenr : " + listeners.size());

        for (HumainListener l : listeners) {
            System.out.println(l.getClass());
            l.onHumainDie(this);
        }

    }

    public void end() {
        super.end();

        /*Group[] grps = new Group[0];
        Group[] keys = esprit.groups.keySet().toArray(grps);
        for (int i = 0 ; i < keys.length; i++) {
           //System.out.println(keys[i].toString() + " i : " + i + " keys length : " + keys.length);
           keys[i].leaveGroup(esprit);
           //System.out.println("group leaved");
        }*/

        // temporaire : les amenagements prives disparraissent avec l'agent
        Iterator<Amenagement> it = privateFacilities.values().iterator();
        Amenagement a;
        while (it.hasNext()) {
            a = it.next();
            a.killAgent(a);
        }
    }

    /**
     * Standard agent initialization
     */
    private void initialisation(Civilisation civ, Communaute communaute) {
        this.civ = civ;
        inventaire = new NInventaire(this);
        esprit = new Esprit(this);

        this.communaute = communaute;
        //privateBuildings = new ArrayList<Batiment>();
        //privateFacilities = new ArrayList<Amenagement>();
        enfants = new ArrayList<Human>();

        attributes = new HashMap<String, Double>();
        for (int i = 0; i < this.getCiv().getAttributesNames().size(); i++) {
            attributes.put(this.getCiv().getAttributesNames().get(i), 0.0);
            putAttr(this.getCiv().getAttributesNames().get(i), this.getCiv().getAttributesStartingValues().get(i));
        }
        //System.out.println("TEST DANS CREATION HUMAINS : " + civ.getStartingCognitons());
        for (int i = 0; i < civ.getStartingCognitons().size(); i++) {
            this.getEsprit().addCogniton(civ.getStartingCognitons().get(i));
        }

    }

    /**
     * Call to the mind to select action to do.
     * @return task to do
     */
    public String penser() {
        if (isDie) {
            return null;
        } else {
            esprit.penser();
        }
        return "penser";
    }

    @Override
    public void activate() {
        super.activate();
        this.moveTo(communaute.getPatch().x, communaute.getPatch().y);
        setColor(civ.getCouleur());
        playRole(DefineConstants.Role_Human);

        //joint auto groups
        for (Group g : civ.getAutoGroups())
            g.joinGroup(esprit, g.getGroupModel().getAutoJoinRole());

        // join civ group
        createGroupIfAbsent(DefineConstants.Comunity_Civilisations, civ.getNom());
        requestRole(DefineConstants.Comunity_Civilisations, civ.getNom(), DefineConstants.Role_Human);

        for (HumainListener l : listeners)
            l.onHumainActivate(this);
        esprit.runInitiatePlan();
    }

    ////////////////////////////////////////////////////////////////   
    //////////// Human Movement (cleanup 30/06/2015)
    ////////////////////////////////////////////////////////////////   

    /**
     * The agent go back to his starting community.
     */
    public void rentrer() {
        this.moveTowards(this.communaute);
    }

    private void followPath() {
        if (chemin != null && !chemin.isEmpty()) {
            Patch cible = this.chemin.get(0);
            this.face(cible);
        }
        this.fd(1);
        if (this.chemin != null && !this.chemin.isEmpty() && this.chemin.get(0) != null) {
            this.chemin.remove(0);
        }
        if (leaveTrail) {
            emit("passage", 1.0f);
            if (this.smell("passage") > Configuration.passagesPourCreerRoute
                    && !this.getPatch().isMarkPresent("Route")) {
                Amenagement_Route troncon = new Amenagement_Route(this.getPatch());
                //this.getPatch().dropMark("Route", troncon);
            }
        }
    }

    public void moveTowards(int x, int y) {
        if (this.chemin.isEmpty()) {
            Patch but = new Patch();
            but.setCoordinates(x, y);
            face(but);
            this.chemin.addAll(this.getPathToPatch(but));
        }
        followPath();
    }

    public void moveTowards(Turtle but) {
        if (this.chemin.isEmpty()) {
            face(but);
            this.chemin.addAll(this.getPathToPatch(but.getPatch()));
        }
        followPath();
    }

    public void moveTowards(Patch but) {
        if (this.chemin.isEmpty()) {
            face(but);
            this.chemin.addAll(this.getPathToPatch(but));
        }
        followPath();
    }

    public void setTrailMode(boolean mode) {
        leaveTrail = mode;
    }

    /**
    * 
    * @param cible
    * @return le Patch raprochant le plus l'agent de sa cible, compte tenu des obstacles
    * l'agent sera amen_______________ a faire des choix qui n'optimiseront pas toujours sa decison, la 
    * faute a un manque d'information inherant a l'agent
    */

    public ArrayList<Patch> getPathToPatch(Patch cible) {
        return AStar(cible);
    }

    ///////////////////////////////////////////////////////////////////////////
    ///////////////// debut du bazard de Astar : a mettre dans une classe !!! (pattern strategie etc..)   
    ///////////////////////////////////////////////////////////////////////////

    public ArrayList<Patch> AStar(Patch cible) {
        int[][] map = new int[getWorldWidth()][getWorldHeight()];
        int minx = Math.min(cible.x, xcor());
        int maxx = Math.max(cible.x, xcor());
        int miny = Math.min(cible.y, ycor());
        int maxy = Math.max(cible.y, ycor());

        int addi = 0;
        int nb = 0;
        int min = 10000;
        for (int l = 0; l < Configuration.terrains.size(); l++) {
            if (Configuration.terrains.get(l).getInfranchissable() == false) {
                nb++;
                addi += Configuration.terrains.get(l).getPassabilite();
                if (Configuration.terrains.get(l).getPassabilite() < min) {
                    min = Configuration.terrains.get(l).getPassabilite();
                }
            }
        }
        int defaut = min /*addi/nb*/;
        for (int i = minx - Configuration.VisionRadius * 6; i < maxx + Configuration.VisionRadius * 6; i++) {
            for (int j = miny - Configuration.VisionRadius * 4; j < maxy + Configuration.VisionRadius * 4; j++) {
                if (i > 0 && i < getWorldWidth() && j > 0 && j < getWorldHeight()) {

                    map[i][j] = defaut;
                }

            }
        }

        for (int i = 0; i < Configuration.VisionRadius * 2; i++) {
            for (int j = 0; j < Configuration.VisionRadius * 2; j++) {
                //   Color couleur = getPatchColorAt(i - getVisionRadius(), j - getVisionRadius());

                if (xcor() + i - Configuration.VisionRadius < getWorldWidth()
                        && ycor() + j - Configuration.VisionRadius < getWorldHeight()
                        && xcor() + i - Configuration.VisionRadius > 0
                        && ycor() + j - Configuration.VisionRadius > 0) {
                    int passabilite = Configuration.couleurs_terrains.get(
                            getPatchAt(i - Configuration.VisionRadius, j - Configuration.VisionRadius).getColor())
                            .getPassabilite();
                    if (smellAt("passage", i - Configuration.VisionRadius, j - Configuration.VisionRadius) > 0) {
                        map[xcor() + i - Configuration.VisionRadius][ycor() + j
                                - Configuration.VisionRadius] = (int) (passabilite
                                        - (passabilite / 2 * 1 / smellAt("passage", i - Configuration.VisionRadius,
                                                j - Configuration.VisionRadius)));
                    } else {
                        map[xcor() + i - Configuration.VisionRadius][ycor() + j
                                - Configuration.VisionRadius] = passabilite;
                    }

                    if (getPatchAt(i - Configuration.VisionRadius, j - Configuration.VisionRadius)
                            .isMarkPresent("Route")) {
                        map[xcor() + i - Configuration.VisionRadius][ycor() + j - Configuration.VisionRadius] /= 2;
                    }

                    if (Configuration.couleurs_terrains.get(
                            getPatchAt(i - Configuration.VisionRadius, j - Configuration.VisionRadius).getColor())
                            .getInfranchissable() == true) {
                        map[xcor() + i - Configuration.VisionRadius][ycor() + j
                                - Configuration.VisionRadius] = Integer.MAX_VALUE;
                    }
                }

            }
        }
        /*   for(int i = 0; i < map.length; i++)
           {
        System.out.print("[");
        for(int j = 0;j < map[i].length;j++)
        {
           if(map[i][j] != 1000)
           {
              System.out.print(map[i][j]);
           }
        }
        System.out.println("]");
           }*/
        ArrayList<Noeud> liste_noeud = new ArrayList<Noeud>();
        ArrayList<Noeud> open_list = new ArrayList<Noeud>();
        ArrayList<Noeud> close_list = new ArrayList<Noeud>();
        Noeud noeud = new Noeud(getPatch().x, getPatch().y, 0, 0);
        noeud.setDistanceRacine(0);
        close_list.add(noeud);
        liste_noeud.add(noeud);
        int cpt = 1;
        for (int i = -1; i < 2; i++) {
            for (int j = -1; j < 2; j++) {
                int x = noeud.getPosX();
                int y = noeud.getPosY();
                if ((x + i < getWorldWidth() && x + i > 0) && (y + j < getWorldHeight() && y + j > 0)
                        && (i != 0 || j != 0) && map[x + i][y + j] != Integer.MAX_VALUE) {
                    Noeud noeu = new Noeud(x + i, y + j, 0, cpt);
                    int distanceRacine = map[x + i][y + j];
                    noeu.setDistanceRacine(distanceRacine);
                    open_list.add(noeu);
                    liste_noeud.add(noeu);
                    cpt++;
                }
            }
        }
        /*System.out.println("Open_list 1 : ");
        for(int i = 0; i < open_list.size();i++)
        {
        System.out.println("Noeud : "+open_list.get(i).getId()+" x : "+open_list.get(i).getPosX()+" y : "+open_list.get(i).getPosY()+ " distance : "+open_list.get(i).getDistanceRacine());
        }*/
        Noeud suivant = PlusProcheNoeud(open_list, cible);
        if (suivant != null) {
            /*if(suivant.getParent() != noeud.getId())
            {
                   
               for(int i = 0; i< close_list.size();i++)
               {
              if(close_list.get(i).getId() > suivant.getParent())
              {
                 close_list.remove(i);
              }
               }
                   
            }*/
            close_list.add(suivant);
        }
        //System.out.println("close_list 1 : " + close_list);
        noeud = suivant;

        while (noeud != null && (noeud.getPosX() != cible.x || noeud.getPosY() != cible.y)) {
            //System.out.println("Agent : "+getID()+" Noeud suivant : "+noeud.getId()+ " x : "+noeud.getPosX()+ " y : "+noeud.getPosY()+ " parent : "+noeud.getParent()+ " x cible : "+cible.x+" y cible : "+cible.y);
            open_list.remove(noeud);
            for (int i = -1; i < 2; i++) {
                for (int j = -1; j < 2; j++) {
                    int x = noeud.getPosX();
                    int y = noeud.getPosY();
                    if ((x + i < getWorldWidth() && x + i > 0) && (y + j < getWorldHeight() && y + j > 0)
                            && (i != 0 || j != 0) && map[x + i][y + j] != Integer.MAX_VALUE) {
                        Noeud noeu = new Noeud(x + i, y + j, noeud.getId(), cpt);
                        if (!doublons(open_list, noeu)) {
                            int distanceRacine = map[x + i][y + j] + noeud.getDistanceRacine();
                            noeu.setDistanceRacine(distanceRacine);
                            open_list.add(noeu);
                            liste_noeud.add(noeu);
                            cpt++;
                            //   System.out.println("Nouveau noeud "+noeu.getId()+" x : "+noeu.getPosX() + " y : "+noeu.getPosY());
                        }
                    }
                }
            }
            suivant = PlusProcheNoeud(open_list, cible);
            if (suivant != null) {
                /*if(suivant.getParent() != noeud.getId())
                {
                       
                   for(int i = 0; i< close_list.size();i++)
                   {
                 if(close_list.get(i).getId() > suivant.getParent())
                 {
                    close_list.remove(i);
                 }
                   }
                       
                }*/
                close_list.add(suivant);
            }
            noeud = suivant;
        }

        ArrayList<Patch> liste = new ArrayList<Patch>();

        /*   for(int i = 0;i < close_list.size();i++)
           {
        int x = close_list.get(i).getPosX();
        int y = close_list.get(i).getPosY();
        if(map[x][y] >= Configuration.VitesseEstimeeParDefaut)
        {
           return liste;
        }
        else
        {
           liste.add(0,getPatchAt(x - position.x, y - position.y));
        }
           }*/
        Noeud nodesui = close_list.get(close_list.size() - 1);
        while (!(nodesui.getPosX() == getPatch().x && nodesui.getPosY() == getPatch().y)) {
            int x = nodesui.getPosX();
            int y = nodesui.getPosY();
            liste.add(0, getPatchAt(x - getPatch().x, y - getPatch().y));
            nodesui = liste_noeud.get(nodesui.getParent());
        }
        //         System.out.println("Debut ");
        for (int i = 0; i < liste.size(); i++) {
            int x = liste.get(i).x;
            int y = liste.get(i).y;
            if (x > xcor() + Configuration.VisionRadius || x < xcor() - Configuration.VisionRadius
                    || y > ycor() + Configuration.VisionRadius || y < ycor() - Configuration.VisionRadius) {

                if (i == 0) {
                    //System.out.println("test");

                    setHeading(Math.random() * 360.);
                    fd(1);
                }
                //   System.out.println("Fin 1 "+"cible x : "+cible.x+" cible y :"+cible.y);
                return liste;
            }
            //      System.out.println("Pos => x : "+x + " y : "+y);
        }
        //         System.out.println("Pos => x : "+xcor() + " y : "+ycor());
        //   System.out.println("Fin 2 cible x : "+cible.x+" cible y :"+cible.y);
        return liste;
    }

    public boolean doublons(ArrayList<Noeud> liste, Noeud noeud) {
        for (int i = 0; i < liste.size(); i++) {
            if (liste.get(i).getPosX() == noeud.getPosX() && liste.get(i).getPosY() == noeud.getPosY()) {
                return true;
            }
        }
        return false;
    }

    public Noeud PlusProcheNoeud(ArrayList<Noeud> liste, Patch cible) {
        Noeud court = null;
        double dist = 10000000;
        double distanceRacine = 0;
        for (int i = 0; i < liste.size(); i++) {
            int x = liste.get(i).getPosX();
            int y = liste.get(i).getPosY();
            Patch courant = this.getPatchAt(x - this.xcor(), y - this.ycor());
            int max = 0;
            for (int j = 0; j < Configuration.terrains.size(); j++) {
                if (Configuration.terrains.get(j).getPassabilite() > max) {
                    max = Configuration.terrains.get(j).getPassabilite();
                }
            }
            distanceRacine = max * Math.max(Math.abs(cible.x - x), Math.abs(cible.y - y));
            double distance = liste.get(i).getDistanceRacine() + distanceRacine;
            if (distance < dist) {
                dist = distance;
                court = liste.get(i);
            }
        }
        return court;
    }

    /**
     * 
     * @param current le patch visit_______________
     * @param visites le tableau des patchs visit_______________s ou non
     * @return true si il n'y a aucun patch non visit_______________ autour de current
     */
    private boolean AucunPatchNonVisiteAutour(Patch current, int[][] visites) {
        // TODO Auto-generated method stub
        Patch test1 = this.getPatchAt(current.x - this.xcor() + 1, current.y - this.ycor());
        Patch test2 = this.getPatchAt(current.x - this.xcor(), current.y - this.ycor() + 1);
        Patch test3 = this.getPatchAt(current.x - this.xcor() - 1, current.y - this.ycor());
        Patch test4 = this.getPatchAt(current.x - this.xcor(), current.y - this.ycor() - 1);
        boolean test = true;
        if (visites[test1.x][test1.y] == 0 /*&& this.inclus(test1.color, this.civ.getInaccesibles())*/) {
            test = false;
        }
        if (visites[test2.x][test2.y] == 0 /*&& this.inclus(test2.color, this.civ.getInaccesibles())*/) {
            test = false;
        }
        if (visites[test3.x][test3.y] == 0 /*&& this.inclus(test3.color, this.civ.getInaccesibles())*/) {
            test = false;
        }
        if (visites[test4.x][test4.y] == 0 /*&& this.inclus(test4.color, this.civ.getInaccesibles())*/) {
            test = false;
        }
        return test;
    }

    ///////////////////////////////////////////////////////////////////////////
    ////////////////Fin de Astar   
    ///////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////      
    ///////////// End Human Movement      
    /////////////////////////////////////////////////////////      

    /*------------------------------------------------------------------------------*/

    public void fd(double i) {

        Color couleur = this.getPatchColor();
        int TempsAPasser = Configuration.couleurs_terrains.get(couleur).getPassabilite();
        TempsAPasser /= 10;
        if (this.tempsPatch > TempsAPasser) {
            this.tempsPatch -= TempsAPasser;
            Color coul = this.getNextPatch().getColor();
            //On va modifier pour que ______a colle avec les nouveaux terrains
            if (!Configuration.couleurs_terrains.get(couleur).getInfranchissable()) {
                super.fd(1);
                this.getPheromone("passage").incValue(xcor(), ycor(), 1.0f);
                if (this.smell("passage") > Configuration.passagesPourCreerRoute && !this.isMarkPresent("Route")) {
                    Amenagement_Route troncon = new Amenagement_Route(this.getPatch());
                    //this.addAmenagement(troncon);  
                    //this.getPatch().dropMark("Route", troncon);
                }
                if (!Configuration.couleurs_terrains.get(coul).getInfranchissable()) {
                    this.fd(1);
                }

            } else {
                this.randomHeading();
                super.fd(1);
                this.getPheromone("passage").incValue(xcor(), ycor(), 1.0f);
                if (this.smell("passage") > Configuration.passagesPourCreerRoute && !this.isMarkPresent("Route")) {
                    Amenagement_Route troncon = new Amenagement_Route(this.getPatch());
                    //this.addAmenagement(troncon); 
                    //this.getPatch().dropMark("Route", troncon);
                }
            }

        }
        if (this.tempsPatch < TempsAPasser) {
            this.tempsPatch++;
        }
        if (this.tempsPatch == TempsAPasser) {

            //TODO TK3 : voir si le comportement du getNextPatch est correct
            Color coul = this.getNextPatch().getColor();
            //TODO : On va modifier pour que ______a colle avec les nouveaux terrains
            if (!Configuration.couleurs_terrains.get(coul).getInfranchissable()) {
                super.fd(1);
                this.getPheromone("passage").incValue(xcor(), ycor(), 1.0f);
                if (this.smell("passage") > Configuration.passagesPourCreerRoute && !this.isMarkPresent("Route")) {
                    //   Amenagement_Route troncon = new Amenagement_Route(this.getPatch());
                    //this.addAmenagement(troncon);  
                    //this.getPatch().dropMark("Route", troncon);
                }

            } else {
                this.randomHeading();
                this.fd(1);

            }
            this.tempsPatch = 2;
        }

    }

    /**
     * Change la direction de l'agent afin qu'il se positionne en dans la direction de l'agent cible 
     * @param cible
     */

    public void face(Turtle cible) {
        double direction = towards(cible.xcor(), cible.ycor());
        this.setHeading(direction);
    }

    /**
     * Change la direction de l'agent afin qu'il se positionne en dans la direction du patch cible 
     * @param cible
     * 
     */
    public void face(Patch cible) {
        double direction = towards(cible.x, cible.y);
        this.setHeading(direction);
    }

    /**
     * @param tortues
     * @return la turtle la plus eloign_______________________________________ de la tortue appelante
     */
    @SuppressWarnings("null")
    public Turtle MaxOneOf(ArrayList<Turtle> tortues) {
        ArrayList<Turtle> choix = new ArrayList<Turtle>();
        double min = 0;
        for (int i = 0; i < choix.size(); i++) {
            int x = tortues.get(i).xcor();
            int y = tortues.get(i).ycor();
            if (this.distance(x, y) > min) {
                min = this.distance(x, y);
                choix.clear();
                choix.add(tortues.get(i));
            }
            if (this.distance(x, y) == min) {
                choix.add(tortues.get(i));
            }
        }
        return this.oneOf(choix);
    }

    /**
     * @param ArrayList<Turtle>
     * @return une tortue au hasard parmis les tortues en parametre
     */
    public Turtle oneOf(ArrayList<Turtle> tortues) {
        if (tortues == null || tortues.size() == 0)
            return null;
        else
            return tortues.get((int) (Math.random() * (tortues.size())));
    }

    /**
     * @param Turtle[]
     * @return une tortue au hasard parmis les tortues en parametre
     */
    public Turtle oneOf(Turtle[] tortues) {
        if (tortues == null || tortues.length == 0)
            return null;
        else
            return tortues[(int) Math.random() * (tortues.length - 1)];
    }

    /**
     * 
     * @return un agent au hasard qui est sur le meme patch que this
     */
    public Human oneOfHumanHere() {
        List<Turtle> cibles = turtlesHere();
        ArrayList<Turtle> choix = new ArrayList<Turtle>();
        for (int i = 0; i < cibles.size(); i++) {
            if (cibles.get(i) != null && cibles.get(i).getClass().equals(this.getClass()) && cibles.get(i) != this)
                choix.add(cibles.get(i));
        }

        if (!choix.isEmpty())
            return (Human) oneOf(choix);
        else
            return null;
    }

    /**
     * 
     * @param tortues
     * @return la tortue la plus proche de lui
     */
    public Human getNearestTurtleOf(ArrayList<Human> tortues) {
        double min = 100000000;
        int imin = 0;
        for (int i = 0; i < tortues.size(); i++) {
            int xt = tortues.get(i).xcor();
            int yt = tortues.get(i).ycor();
            if (this.distance(xt, yt) < min) {
                min = this.distance(xt, yt);
                imin = i;
            }
        }
        if (tortues.isEmpty()) {
            return null;
        } else {
            return tortues.get(imin);
        }

    }

    /**
     * @param tortues
     * @return la communaute la plus proche de lui
     */
    public Communaute MinOneOfOtherCommunaute(ArrayList<Turtle> tortues) {
        double min = 100000000;
        int imin = 0;
        for (int i = 0; i < tortues.size(); i++) {
            if (tortues.get(i).isPlayingRole("Communaute") && !tortues.get(i).equals(communaute)) {
                int xt = tortues.get(i).xcor();
                int yt = tortues.get(i).ycor();
                if (this.distance(xt, yt) < min) {
                    min = this.distance(xt, yt);
                    imin = i;
                }
            }
        }
        if (tortues.isEmpty()) {
            return null;
        } else {
            return (Communaute) tortues.get(imin);
        }

    }

    /**
     * @param tortues
     * @return la communaute appartenant a une autre civilisation que "civ" la plus proche de l'humain considere
     */
    public Communaute MinOneOfOtherCommunauteOfOtherCiv(ArrayList<Turtle> tortues, Civilisation civ) {
        double min = 100000000;
        int imin = 0;
        for (int i = 0; i < tortues.size(); i++) {
            if (tortues.get(i).isPlayingRole("Communaute") && !tortues.get(i).equals(communaute)
                    && ((Communaute) tortues.get(i)).getCiv() != civ) {
                int xt = tortues.get(i).xcor();
                int yt = tortues.get(i).ycor();
                if (this.distance(xt, yt) < min) {
                    min = this.distance(xt, yt);
                    imin = i;
                }
            }
        }
        if (tortues.isEmpty()) {
            return null;
        } else {
            return (Communaute) tortues.get(imin);
        }
    }

    /**
     * 
     * @param radius
     * @return les tortues a une distance radius de lui
     */
    public ArrayList<Turtle> inRadius(int radius) {
        ArrayList<Turtle> tortues = new ArrayList<Turtle>();
        for (int i = 0; i < radius * 2; i++) {
            for (int j = 0; j < radius * 2; j++) {
                if (this.distance(this.xcor() + i - radius, this.ycor() + j - radius) < radius) {
                    List<Turtle> torts = this.getPatchAt(i - radius, j - radius).getTurtles();
                    for (int k = 0; k < torts.size(); k++) {
                        tortues.add(torts.get(k));
                    }
                }
            }
        }
        return tortues;
    }

    @SuppressWarnings("null")
    public ArrayList<Turtle> TurtlesWithRole(String role) {
        List<Turtle> tortues = World.getInstance().getTurtlesWithRoles(role);
        ArrayList<Turtle> choix = new ArrayList<Turtle>();
        for (int i = 0; i < tortues.size(); i++) {
            choix.add(tortues.get(i));
        }
        return choix;
    }

    @SuppressWarnings({ "null", "unused" })
    public Turtle OneOfTurtlesHereWithRole(String role) {
        List<Turtle> cibles = this.turtlesHere();
        ArrayList<Turtle> choix = new ArrayList<Turtle>();
        for (int i = 0; i < cibles.size(); i++) {
            if (cibles.get(i).isPlayingRole(role)) {
                choix.add(cibles.get(i));
            }
        }

        if (!choix.isEmpty()) {
            return this.oneOf(choix);
        } else {
            return null;
        }

    }

    /**
     * Retourne une tortue pr_______________sente sur le m__________________me patch dont le crit__________________re pass_______________ en param__________________tre correspond
     * @param m : La m_______________thode a utiliser pour effectuer la comparaison
     * @param params : les param__________________tres dont la m_______________thode a besoin
     * @param o : la valeur souhait_______________e pour la compraison
     * @return
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */

    @SuppressWarnings({ "null", "unused" })
    public Turtle OneOfHumanHereWith(Method m, Object[] params, Object o)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        List<Turtle> cibles = this.turtlesHere();
        ArrayList<Turtle> choix = new ArrayList<Turtle>();
        for (int i = 0; i < cibles.size(); i++) {
            if (cibles.get(i).isPlayingRole(DefineConstants.Role_Human)) {
                if (m.invoke((Human) cibles.get(i), params).equals(o)) {
                    choix.add(cibles.get(i));
                }
            }
        }
        if (!choix.isEmpty()) {
            return this.oneOf(choix);
        } else {
            return null;
        }

    }

    /**
     * 
     * @param cible
     * @return vrai si la tortue cible est sur le meme patch que la tortue appelante
     */
    public boolean isHere(Turtle cible) {
        return (this.getPatch() == cible.getPatch());

        /*
        Turtle[] tortuesIci = (Turtle[]) this.getOtherTurtles(0, true).toArray(); //TODO to check
        for(int i = 0;i < tortuesIci.length;i++)
        {
           if(tortuesIci[i].equals(cible))
           {
        return true;
           }
        }
        return false;*/

    }

    /**
        
     * @param patchVariable
     * @param inRadius the highest distance from the agent which should be considered
     * @return the patch which has the highest value for <code>patchVariable</code>
     */
    public Patch getPatchWithMaxOf(String patchVariable, int inRadius) {
        double max = -Double.MAX_VALUE;
        ArrayList<Patch> p = new ArrayList<Patch>();

        /*On cherche le max*/
        for (int i = -inRadius; i <= inRadius; i++) {
            for (int j = -inRadius; j <= inRadius; j++) {
                if (!(i == 0 && j == 0) && this.isInsideEnvironmentBounds(i, j)) {
                    final Patch tmpP = getPatchAt(i, j);
                    //System.out.println(patchVariable);
                    //System.out.println(tmpP.x +" " +tmpP.y);
                    final double tmp = this.smellAt(patchVariable, i, j);
                    if (tmp >= max) {
                        max = tmp;
                    }
                }
            }
        }
        int index = -1;
        if (max != -Double.MAX_VALUE) {
            /*On conserve tous les patch dont la valeur est le max*/
            for (int i = -inRadius; i <= inRadius; i++) {
                for (int j = -inRadius; j <= inRadius; j++) {
                    if (!(i == 0 && j == 0) && this.isInsideEnvironmentBounds(i, j)) {
                        Patch tmpP = getPatchAt(i, j);
                        double tmp = this.smellAt(patchVariable, i, j);
                        if (tmp == max) {
                            p.add(tmpP);
                        }
                    }
                }
            }
            index = (int) (Math.floor(Math.random() * (p.size() - 1)));
        }

        /*   if (this.isInsideEnvironmentBounds(1,1) && p.get(index) == getPatchAt(1,1)) {
              System.out.println("11");
           }
           if (this.isInsideEnvironmentBounds(1,1) && p.get(index) == getPatchAt(1,-1)) {
              System.out.println("1-1");
           }*/
        //System.out.println(index);
        if (index != -1 && index < p.size()) {
            return p.get(index);
        } else {
            return null;
        }

    }

    /**
     * Retourne un amenagement dont le nom est pass_______________ en param__________________tre
     * @param type : nom de l'am_______________nagement
     * @return
     */
    /*
    public Amenagement getOneOfAmenagement(String type)
    {
       ArrayList<Amenagement> selection = new ArrayList<Amenagement>();
       for (int i = 0; i < privateFacilities.size(); i++)
       {
     if (privateFacilities.get(i).getNom().equals(type))
     {
        selection.add(privateFacilities.get(i));
     }
       }
           
       if (selection.size() > 0)   return (selection.get((int) (Math.random()*(selection.size()))));
       return null;
    }*/

    //   /**
    //    * Retourne un amenagement dont le nom est passee en parametre qui se trouve dans un radius de l'Humain
    //    * @param type : nom de l'amenagement int : Radius de recherche.
    //    * @return un amenagement
    //    */
    //   public Amenagement getOneAmenagementInRadius(String type, int radius)
    //   {
    //      if getP
    //      int x = getPatch().x;
    //      int y = getPatch().y;
    //      int patchNumbers = radius * radius;
    //
    //      for(int i = 0; i < patchNumbers; i++){
    //         
    //      }
    //      
    //      
    //      return null;
    //   }

    /***
     * 
     * @param objet
     * @param liste
     * @return true si l'objet est inclus dans la liste
     */

    public boolean inclus(Object objet, ArrayList<?> liste) {
        int i = 0;
        while (i < liste.size() && !liste.get(i).equals(objet)) {
            i++;
        }
        return i < liste.size();
    }

    /**
     * 
     * @param cible
     * @return true si l'agent peut se deplacer sur le Patch cible
     */

    /*public boolean PasObstacle(Patch cible)
    {
       return !inclus(cible.color,this.civ.getInaccesibles()) ;
    }*/

    private double distanceBetween(Patch a, Patch b) {
        return Math.sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y));
    }

    /*
    private ArrayList<Patch> plusProche(ArrayList<Patch> test1, ArrayList<Patch> test2, ArrayList<Patch> test3, ArrayList<Patch> test4) {
       // TODO Auto-generated method stub
       double dis1;
       double dis2;
       double dis3;
       double dis4;
       if(test1 == null)
       {
     dis1 = 1000000000;
       }
       else
       {
     dis1 = this.distance(test1.get(0).x,test1.get(0).y);
     for(int i = 1;i<test1.size();i++)
     {
        dis1 += this.distanceBetween(test1.get(i-1), test1.get(i));
     }
       }
       if(test2 == null)
       {
     dis2 = 1000000000;
       }
       else
       {
     dis2 = this.distance(test2.get(0).x,test2.get(0).y);
     for(int i = 1;i<test2.size();i++)
     {
        dis2 += this.distanceBetween(test2.get(i-1), test2.get(i));
     }
       }
       if(test3 == null)
       {
     dis3 = 1000000000;
       }
       else
       {
     dis3 = this.distance(test3.get(0).x,test3.get(0).y);
     for(int i = 1;i<test3.size();i++)
     {
        dis3 += this.distanceBetween(test3.get(i-1), test3.get(i));
     }
       }
       if(test4 == null)
       {
     dis4 = 1000000000;
       }
       else
       {
     dis4 = this.distance(test4.get(0).x,test4.get(0).y);
     for(int i = 1;i<test4.size();i++)
     {
        dis4 += this.distanceBetween(test4.get(i-1), test4.get(i));
     }
       }
       if(test1 == null && test2 == null && test3 == null && test4 == null)
       {
     return null;
       }
       else
       {
     if(dis1 < dis2)
     {
        if(dis3 < dis4)
        {
           if(dis1 < dis3)
           {
              return test1;
           }
           else
           {
              return test3;
           }
        }
        else
        {
           if(dis1 < dis4)
           {
              return test1;
           }
           else
           {
              return test4;
           }
        }
     }
     else
     {
        if(dis3 < dis4)
        {
           if(dis2 < dis3)
           {
              return test2;
           }
           else
           {
              return test3;
           }
        }
        else
        {
           if(dis2 < dis4)
           {
              return test2;
           }
           else
           {
              return test4;
           }
        }
     }
       }
    }
    */

    /**
     * 
     * @param radius
     * @return les tortues a une distance radius de lui
     */
    public ArrayList<Human> HumaininRadius(int radius) {
        ArrayList<Human> tortues = new ArrayList<Human>();
        for (int i = 0; i < radius * 2; i++) {
            for (int j = 0; j < radius * 2; j++) {
                if (this.distance(this.getX() + i - radius, this.getY() + j - radius) < radius) {
                    List<Turtle> torts = this.getPatchAt(i - radius, j - radius).getTurtles();
                    for (int k = 0; k < torts.size(); k++) {
                        if (torts.get(k).isPlayingRole(DefineConstants.Role_Human)) {
                            tortues.add((Human) torts.get(k));
                        }

                    }
                }
            }
        }
        return tortues;
    }

    public ArrayList<Communaute> CommunauteInRadius(int radius) {
        ArrayList<Communaute> tortues = new ArrayList<Communaute>();
        for (int i = 0; i < radius * 2; i++) {
            for (int j = 0; j < radius * 2; j++) {
                if (this.distance(this.getPatch().x + i - radius, this.getPatch().y + j - radius) < radius) {
                    Turtle[] torts = (Turtle[]) this.getPatchAt(i - radius, j - radius).getTurtles().toArray();
                    for (int k = 0; k < torts.length; k++) {
                        if (torts[k].isPlayingRole("Communaute")) {
                            tortues.add((Communaute) torts[k]);
                        }

                    }
                }
            }
        }
        return tortues;
    }

    public ArrayList<Human> humainsFromCiv(ArrayList<Human> humains, Civilisation civ) {
        ArrayList<Human> humainsTries = new ArrayList<Human>();
        for (int i = 0; i < humains.size(); i++) {
            if (humains.get(i).getCiv().equals(civ)) {
                humainsTries.add(humains.get(i));
            }
        }
        return humainsTries;
    }

    /**
     * @param tortues
     * @return une tortue au hasard parmis les tortues en parametre
     */
    public Human oneOfHumain(ArrayList<Human> tortues) {
        return tortues.get((int) Math.random() * (tortues.size() - 1));
    }

    /**
     * Deplace les biens de l'agent dans une nouvelle communaute.
     * Le transfert est simplifie au maximum, car simuler le detail de cette migration dans la simulation ne nous semble pas pertinent.
     * @param nouvelleCommunaute : la communaute d'accueil
     */
    /*
    public void migrer(Communaute nouvelleCommunaute){
       for (int i = 0; i < privateBuildings.size(); i++){
     privateBuildings.get(i).setCommunaute(nouvelleCommunaute);
     communaute.retirerBatiment(privateBuildings.get(i));
       }
       communaute = nouvelleCommunaute;
        
    }*/

    public Object getMark(String s) {
        return this.getPatch().getMark(s);
    }

    public boolean isMarkPresent(String s) {
        return this.getPatch().isMarkPresent(s);
    }

    public List<Turtle> turtlesHere() {
        return this.getOtherTurtles(0, true);
    }

    public List<Human> humansHere() {
        List<Turtle> turtles = this.getOtherTurtles(0, true);
        LinkedList<Human> humans = new LinkedList<Human>();
        for (Turtle t : turtles) {
            if (t instanceof Human) {
                humans.add((Human) t);
            }
        }
        return humans;
    }

    public List<Human> humansHereWithTag(String tag) {
        List<Turtle> turtles = this.getOtherTurtles(0, true);
        LinkedList<Human> humans = new LinkedList<Human>();
        for (Turtle t : turtles) {
            if (t instanceof Human && ((Human) t).getEsprit().ownTag(tag)) {
                humans.add((Human) t);
            }
        }
        return humans;
    }

    public List<Human> humansHereWithCogniton(TypeCogniton cogni) {
        List<Turtle> turtles = this.getOtherTurtles(0, true);
        LinkedList<Human> humans = new LinkedList<Human>();
        for (Turtle t : turtles) {
            if (t instanceof Human && ((Human) t).getEsprit().ownCogniton(cogni)) {
                humans.add((Human) t);
            }
        }
        return humans;
    }

    //----------------GETTERS/SETTERS-------------------
    /*
    public ArrayList<Batiment> getBatiments() {
       return privateBuildings;
    }
    *//*
        public void setBatiments(ArrayList<Batiment> batiments) {
           this.privateBuildings = batiments;
        }
       */
    public Boolean isWoman() {
        return woman;
    }

    public void setWoman(Boolean woman) {
        this.woman = woman;
    }

    public int getVisionRadius() {
        return visionRadius;
    }

    public Civilisation getCiv() {
        return civ;
    }

    public NInventaire getInventaire() {
        return inventaire;
    }

    public Boolean getIsSelected() {
        return isSelected;
    }

    public void setIsSelected(Boolean isSelected) {
        this.isSelected = isSelected;
    }

    public Communaute getCommunaute() {
        return communaute;
    }

    public Esprit getEsprit() {
        return esprit;
    }

    public Human getPere() {
        return pere;
    }

    public Human getMere() {
        return mere;
    }

    /*
       public ArrayList<Amenagement> getAmenagements() {
          return privateFacilities;
       }
        
       public void setAmenagements(ArrayList<Amenagement> amenagements) {
          this.privateFacilities = amenagements;
       }
    */
    public ArrayList<Human> getEnfants() {
        return enfants;
    }

    public Human getConjoint() {
        return conjoint;
    }

    public boolean estDeLaMemeCivilisation(Human h) {
        //Civkraft v0.1
        return getCiv().equals(h.getCiv());
        /**Original
         * return getCiv().getIndexCiv() == getCiv().getIndexCiv();
         */
    }

    public HashMap<String, Double> getAttr() {
        return attributes;
    }

    public void setAttr(HashMap<String, Double> attributes) {
        this.attributes = attributes;
    }

    public void putAttr(String s, Double d) {
        //System.out.println("maj trigg");

        ArrayList<Object[]> triggers = this.getCiv().getAttributesTrigerringValues().get(s);
        if (triggers != null) {
            for (int i = 0; i < triggers.size(); i++) {
                //System.out.println("TRIGGER : " + ((NCogniton)triggers.get(i)[0]).getNom() + " " + triggers.get(i)[1] + " " + triggers.get(i)[2]);
                Double v;
                if (triggers.get(i)[3].equals(DefineConstants.__MC_NULL_CONSTANT))
                    v = (Double) triggers.get(i)[1];
                else
                    v = getCiv().getCognitiveScheme().getConstantValueByName((String) triggers.get(i)[3]);
                //System.out.println(v +" "+ d + " " + attributes.get(s));

                //new value > old value
                if (v >= attributes.get(s) && v <= d && d > attributes.get(s)) {
                    Integer cmp = (Integer) triggers.get(i)[2];
                    TypeCogniton c = (TypeCogniton) triggers.get(i)[4];
                    //System.out.println("Difference franchie montante: " + c.getNom());

                    switch (cmp) {
                    case 2:
                        if (d > v)
                            esprit.addCogniton(c);
                        break;

                    case 1:
                        if (d >= v && !attributes.get(s).equals(v))
                            esprit.addCogniton(c);
                        break;

                    case 0:
                        if (d == v)
                            esprit.addCogniton(c);
                        else
                            esprit.removeCogniton(c);
                        break;

                    case -1:
                        if (d <= v && !attributes.get(s).equals(v))
                            ;
                        else
                            esprit.removeCogniton(c);
                        break;

                    case -2:
                        if (d < v)
                            ;
                        else
                            esprit.removeCogniton(c);
                        break;

                    default:
                        break;
                    }
                }

                //old value > new value
                else if (v <= attributes.get(s) && v >= d && d < attributes.get(s)) {
                    Integer cmp = (Integer) triggers.get(i)[2];
                    TypeCogniton c = (TypeCogniton) triggers.get(i)[4];
                    //System.out.println("Difference franchie descente: " + c.getNom());

                    switch (cmp) {
                    case 2:
                        if (d > v)
                            ;
                        else
                            esprit.removeCogniton(c);
                        break;

                    case 1:
                        if (d >= v && !attributes.get(s).equals(v))
                            ;
                        else
                            esprit.removeCogniton(c);
                        break;

                    case 0:
                        if (d == v)
                            esprit.addCogniton(c);
                        else
                            esprit.removeCogniton(c);
                        break;

                    case -1:
                        if (d <= v && !attributes.get(s).equals(v))
                            esprit.addCogniton(c);
                        break;

                    case -2:
                        if (d < v)
                            esprit.addCogniton(c);
                        break;

                    default:
                        break;
                    }
                }
            }
        }
        attributes.put(s, d);

    }

    /**
     * Alternate version of getNextPatch which returns this patch instead of null
     */
    public Patch getNextPatch() {
        if (super.getNextPatch() == null)
            return this.getPatch();
        return super.getNextPatch();
    }

    public boolean isInsideEnvironmentBounds(int offX, int offY) {
        World w = World.getInstance();
        if (this.getX() + offX >= 0 && this.getY() + offY >= 0 && this.getX() + offX < w.getWidth()
                && this.getY() + offY < w.getHeight())
            return true;
        else
            return false;

    }

    /**
     * Return the angle towards the specified patch
     */
    public double towards(Patch p) {
        double dx = p.x - xcor();
        double dy = -(p.y - ycor());
        double inRads = Math.atan2(dy, dx);

        if (inRads < 0)
            inRads = Math.abs(inRads);
        else
            inRads = 2 * Math.PI - inRads;

        return Math.toDegrees(inRads);
    }

    /**
     * Return the angle towards the specified patch coordinates
     */
    public double towards(int x, int y) {
        double dx = x - xcor();
        double dy = -(y - ycor());
        double inRads = Math.atan2(dy, dx);

        if (inRads < 0)
            inRads = Math.abs(inRads);
        else
            inRads = 2 * Math.PI - inRads;

        return Math.toDegrees(inRads);
    }

    public ArrayList<Patch> getChemin() {
        return this.chemin;
    }

    public void setCiv(Civilisation civ) {
        this.civ = civ;
    }

    public void setCommunaute(Communaute communaute) {
        this.communaute = communaute;
    }

    public Patch getCible() {
        return cible;
    }

    public void setCible(Patch cible) {
        this.cible = cible;
    }

    public Amenagement createPrivateFacility(TypeAmenagement type, Patch p) {
        Amenagement result = null;

        if (privateFacilities.get(type.getNom()) == null) {
            result = new Amenagement(p, this, type);
            this.launchAgent(result);
            this.privateFacilities.put(type.getNom(), result);
            result.createGroupIfAbsent(this.getCiv().getNom(), DefineConstants.Group_PrivateFacilities);
            result.requestRole(this.getCiv().getNom(), DefineConstants.Group_PrivateFacilities,
                    DefineConstants.Role_Facility);

        }
        return result;
    }

    public Amenagement_Efficacite createPrivateFacilityEfficacite(TypeAmenagement type, Patch p) {
        Amenagement_Efficacite result = null;

        if (privateFacilities.get(type.getNom()) == null) {
            result = new Amenagement_Efficacite(p, this, type);
            this.launchAgent(result);
            this.privateFacilities.put(type.getNom(), result);
            result.createGroupIfAbsent(this.getCiv().getNom(), DefineConstants.Group_PrivateFacilities);
            result.requestRole(this.getCiv().getNom(), DefineConstants.Group_PrivateFacilities,
                    DefineConstants.Role_Facility);

        }
        return result;
    }

    public HashMap<String, Amenagement> getPrivateFacilities() {
        return privateFacilities;
    }

    public void setPrivateFacilities(HashMap<String, Amenagement> buildings) {
        this.privateFacilities = buildings;
    }

    public static void addHumanListener(HumainListener listener) {
        listeners.add(listener);
    }

    public static void removeHumanListener(HumainListener listener) {
        listeners.remove(listener);
    }

    public interface HumainListener {
        public void onHumainActivate(Human humain);

        public void onHumainDie(Human humain);
    }

    ///////////// facilities

    public ArrayList<Amenagement> getFacilitiesOnPatch(Patch p) {
        ArrayList<Amenagement> result = new ArrayList<Amenagement>();
        result.addAll(p.getTurtlesWithRole(DefineConstants.Role_Facility, Amenagement.class));
        return result;
    }

    public ArrayList<Amenagement> getFacilitiesHere() {
        return getFacilitiesOnPatch(this.getPatch());
    }

    public ArrayList<Amenagement> getPrivateFacilitiesHere() {
        ArrayList<Amenagement> result = new ArrayList<Amenagement>();
        for (Amenagement a : this.getPatch().getTurtlesWithRole(DefineConstants.Role_Facility, Amenagement.class)) {
            if (getPrivateFacilities().containsValue(a)) {
                result.add(a);
            }
        }
        return result;
    }

    public ArrayList<Amenagement> getPrivateFacilitiesOfTypeHere(TypeAmenagement type) {
        ArrayList<Amenagement> result = new ArrayList<Amenagement>();
        for (Amenagement a : this.getPatch().getTurtlesWithRole(DefineConstants.Role_Facility, Amenagement.class)) {
            if (a.getType().equals(type) && getPrivateFacilities().containsValue(a)) {
                result.add(a);
            }
        }
        return result;
    }

    public ArrayList<Amenagement> getFacilitiesOfTypeHere(TypeAmenagement type) {
        ArrayList<Amenagement> result = new ArrayList<Amenagement>();
        for (Amenagement a : this.getPatch().getTurtlesWithRole(DefineConstants.Role_Facility, Amenagement.class)) {
            if (a.getType().equals(type)) {
                result.add(a);
            }
        }
        return result;
    }

    public ArrayList<Amenagement> getGroupFacilitiesOfTypeHere(TypeAmenagement type, GroupModel grp) {
        ArrayList<Amenagement> result = new ArrayList<Amenagement>();
        if (esprit.getConcreteGroup(grp) != null) {
            for (Amenagement a : this.getPatch().getTurtlesWithRole(DefineConstants.Role_Facility,
                    Amenagement.class)) {
                if (a.getType().equals(type)
                        && a.getMyGroups(civ.getName()).contains(esprit.getConcreteGroup(grp).getId())) {
                    result.add(a);
                }
            }
        }
        return result;
    }

    public HashMap<String, Amenagement> getBuildings() {
        // TODO Auto-generated method stub
        return privateFacilities;
    }

    public void setCibleInteraction(Human h) {
        this.cibleInteraction = h;
    }

    public Human getCibleInteraction() {
        return cibleInteraction;
    }

    // Modif L.R : 
    public Human oneOfHumanInRadius(int radius) //MODIF L.R
    {
        List<Turtle> cibles = this.getOtherTurtles(radius, true);
        ArrayList<Turtle> choix = new ArrayList<Turtle>();
        for (int i = 0; i < cibles.size(); i++) {
            if (cibles.get(i) != null && cibles.get(i).getClass().equals(this.getClass()) && cibles.get(i) != this)
                choix.add(cibles.get(i));
        }

        if (!choix.isEmpty())
            return (Human) oneOf(choix);
        else
            return null;
    }

    public Human oneOfHumanInRadiusWithAttribute(int radius, String attributeName) //MODIF L.R
    {
        List<Turtle> cibles = this.getOtherTurtles(radius, true);
        ArrayList<Turtle> choix = new ArrayList<Turtle>();
        for (int i = 0; i < cibles.size(); i++) {
            if (cibles.get(i) != null && cibles.get(i).getClass().equals(this.getClass())
                    && cibles.get(i) != this) {
                Double d = ((Human) cibles.get(i)).getAttr().get(attributeName);
                if (d > 0)
                    choix.add(cibles.get(i));
            }
        }
        if (!choix.isEmpty())
            return (Human) oneOf(choix);
        else
            return null;
    }

    public ArrayList<Human> OtherHumansInRadius(int radius) {
        List<Turtle> cibles = this.getOtherTurtles(radius, true);
        ArrayList<Human> humans = new ArrayList<Human>();
        for (int i = 0; i < cibles.size(); i++) {
            if (cibles.get(i) != null && cibles.get(i).getClass().equals(this.getClass()) && cibles.get(i) != this)
                humans.add((Human) cibles.get(i));
        }

        if (!humans.isEmpty())
            return humans;
        else
            return null;
    }

    public Human getInitiateur() {
        return initiateurInteraction;
    }

    public void setInitiateur(Human cible) {
        initiateurInteraction = cible;
    }

    /*public boolean isAlive(){
       return (!isDie);
    }*/

    public int getDegats() {
        return degats;
    }

    public void setDegats(int newDegats) {
        degats = newDegats;
    }

    public void augmenterDegats(int augmentation) {
        degats += augmentation;
    }

    //Envoi de messages : 
    /*protected void recevoirMessage(Message message){
       mailbox.add(message);
    }
        
        
    public void sendMessage(Human destinataire, Message message){
       message.setSender(this);
       destinataire.recevoirMessage(message);
    }
        
    public void broadcastMessageInRadius(Message message, int radius){
       message.setSender(this);
       for(Human h : this.OtherHumansInRadius(radius)){
     h.recevoirMessage(message);
       }
    }
        
    public StringMessage gotStringMessage(String contenuRecherche){
       for(Message message : mailbox){
     if(message instanceof civilisation.message.StringMessage){
        if(((civilisation.message.StringMessage) message).getContenu().equals(contenuRecherche)){
           return (StringMessage) message;
        }
     }
       }
       return null;
    }
        
    public void flushMail(){
       mailbox = new ArrayList<Message>();
    }*/

    public String getDebugString() {
        return debugString;
    }

    public void setDebugString(String debugString) {
        this.debugString = debugString;
    }
}