Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Simulateur d'écosystème
Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Simulateur d'écosystème

Posté le 07/05/2014 21:54

J'expose ici un projet sur lequel je m'arrache les cheveux planche depuis plusieurs semaines déjà : un add-in capable de simuler un écosystème, sous forme des sprites simples pour avoir une vue globale. 8)
Le panel d'éléments est très succinct, il y aura des petites plantes, des arbres, des herbivores et des carnivores. Il seront capables d'interagir entre eux en se courant après, en se bouffant et en se reproduisant.

La particularité de ce simulateur résidera dans l'introduction de l'évolution. Par exemple, si une population importante d'herbivores devient trop résistante, alors vous pourrez peut-être observer que certains carnivores arrivent à manger en adoptant un comportement charognard (et ce de façon indirecte, c'est-à-dire que le programme sera prévu pour que des mutations apparaissent, mais le fait que ces mutations se répandent si elles sont favorables ne sera dû qu'aux lois de la sélection naturelle).
Bon, j'espère que je ne vous ai pas déjà paumé, de toute façon les explications précédentes sont plus de l'ordre du détail technique (heureusement parce que sinon je n'aurai pas beaucoup de téléchargements ).

Bien sûr, pour que cet add-in reste ludique, l'utilisateur pourra agir à sa guise sur l'écosystème (je ne sais pas encore comment). Au final, ce ne sera pas vraiment un jeu mais plutôt une espèce de "bac à sable".


Pour l'anecdote, l'idée m'est venue en lisant un article de Science & vie sur la définition de la vie, qui abordait des éléments (chimiques, informatiques, physiques...) troublants, car très semblables à des formes de vie. Et ce qui a attiré mon attention est un programme (dont le nom m'échappe) d'un chercheur (dont le nom m'échappe aussi ) qui affichait des formes très simples, mais capables d'évoluer et de se parasiter entre elles.
Bref, ça m'avait plutôt fasciné, notamment le fait que le programme aboutit à des résultats non prévus car découlant du développement de l'I.A., et ça m'a donnait envie de faire pareil.
L'idée a germé et a aboutit à ce projet d’écosystème



Voilà, j'aurai préféré vous exposer ce projet plus tard car j'aurais bien aimé que vous ayez une démo digne de ce nom, mais il se trouve que je planche sur les I.A. et que j'ai actuellement un problème tenace que je ne parvient pas à résoudre moi-même
cf premier post



1, 2, 3 Suivante
Lephenixnoir En ligne Administrateur Points: 24259 Défis: 170 Message

Citer : Posté le 07/05/2014 21:55 | #


Magnifique !

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Citer : Posté le 07/05/2014 21:56 | # | Fichier joint


Le problème auquel je suis confronté est le suivant : chaque être est géré avec une structure, et cette structure contient un pointeur qui pointe sur la cible de l'animal (sa proie par exemple). Or il se trouve que ce pointeur prend souvent des valeurs anarchiques, aboutissant alors à des erreurs.
Malheureusement, je n'ai pas été capable de localiser la source de l'erreur, qui est donc cachée dans mon code. Je vous mets donc ce dernier ici (ainsi qu'en pièce jointe parce qu'il est long ), et je suis sincèrement désolé de ne pas pouvoir vous donner seulement un morceau qui rendraient le problème plus simple à résoudre

Le .c :
#include <stdio.h>
#include <stdlib.h>
#include "fxlib.h"
#include "string.h"
#include "MonochromeLib.h"
#include "usefull.h"
#include "Ecsystem.h"

#define CARTE(x,y) carte[(y-1)*largeur+x-1]
#define REPRODUCTION 400
#define FAIM(masse) 40*masse
#define VIE(masse) 2500+500*masse
#define RESISTANCE(masse) masse+1.0

int AddIn_main(int isAppli, unsigned short OptionNum)
{
    srand(time_getTicks());
    
    ML_clear_vram();
    ML_clear_screen();
    
    simulation();
}

void simulation()
{
    short hauteur=5,largeur=10,vie;
    short curseur_x=1,curseur_y=1;
    Element *carte,*element,*element_apres;
    short i,j;
    Liste *liste;
    char vitesse,resistance;
    short faim;
    int fps=10;
    
    /*PrintV(1,1,sizeof(Element));
    ML_display_vram();
    while(1);*/
    
    
    liste=initialisation();
    carte=generation_map(hauteur,largeur,liste);

[red]    //C'est ici que ça foire !
    do
    {
        element=liste->premier;
        while(element!=NULL)
        {
            //Gestion des Etres d'ici...
            vitesse=element->masse;
            resistance=RESISTANCE(element->masse);
            faim=FAIM(element->masse);
            element->vie--;
            
            element_apres=element->suivant;
            if(element->type > ARBRE)
            {
                if(element->etat != MORT)
                {
                    if(element->cible!=NULL)if(element->cible->etat==INEXISTANT)ciblage(element,NULL);
                    objectif(element);
                    if(element->cible==NULL)recherche(element,carte,hauteur,largeur);

                    if(element->compteur>=vitesse)
                    {
                        if(element->cible!=NULL)
                        {
                            if(abs(element->cible->x - element->x)+abs(element->cible->y - element->cible->y)>1)deplacement(element,hauteur,largeur,carte);
                            else action(element,faim,liste,carte,hauteur,largeur);
                        }else deplacement(element,hauteur,largeur,carte);
                        element->compteur=0;
                    }else element->compteur++;
                    
                    vie=1500+500*element->masse;
                    if(element->vie==3*(vie/4))element->etat=MOYEN;
                    if(element->vie==vie/4)element->etat=VIEUX;
                    if(!element->vie)
                    {
                        element->etat=MORT;
                        clear(element->x,element->y);
                        affichage(*element);
                    }
                }
                else if(!(element->vie%100))element->viande--;        
                
                if(!element->viande)
                {
                    clear(element->x,element->y);
                    CARTE(element->x,element->y).type=0;
                    element->etat=INEXISTANT;
                }

            }
            else reproduction_vegetal(liste,element,hauteur,largeur,carte);
            
            if(element->etat==INEXISTANT && !element->nombre_predateurs)suppression(liste,element);
            
            element=element_apres;
            
            //...à là
            
            if(IsKeyDown(KEY_CTRL_EXE))
            {
                for(i=1;i<=largeur;i++)for(j=1;j<=hauteur;j++)PrintV(7*i-6,8*j-7,CARTE(i,j).type);
                ML_display_vram();
                while(1);
            }
            
            if(IsKeyDown(KEY_CTRL_SHIFT))
            {
                while(IsKeyDown(KEY_CTRL_SHIFT));
                while(IsKeyUp(KEY_CTRL_SHIFT));
                while(IsKeyDown(KEY_CTRL_SHIFT));
            }
        }
        ML_display_vram();
        //setFps(fps);
    }while(1);
    
    
    while(1);[/red]
    free(carte);
    while(liste->premier!=NULL)suppression(liste,liste->premier);
}

Element *generation_map(short hauteur, short largeur,Liste *liste)
{
    Element *carte=NULL;
    short i,j;
    carte=malloc(hauteur*largeur*sizeof(Element));
    if(carte==NULL)erreur();

    for(i=1;i<=largeur;i++)for(j=1;j<=hauteur;j++)CARTE(i,j).type=0;
    
    creation_etre(liste->premier,largeur,hauteur,alea(1,3),carte,1,0,0);
    for(i=1;i<(largeur*hauteur)/10;i++)insertion(liste,largeur,hauteur,carte,1,0,0,alea(1,3));

    for(i=1;i<=largeur;i++)for(j=1;j<=hauteur;j++)affichage(CARTE(i,j));

    ML_display_vram();
    
    return carte;
}

int alea(int min,int max)
{
    return (rand()%(max-min+1))+min;
}

void creation_etre(Element *etre,short largeur,short hauteur,Type type,Element *carte,char hasard,short x,short y)
{
    char sante[]={2.0,3.0,4.0,5.0,6.0};
    
    if(hasard)
    {    do
        {    
            etre->x=alea(1,largeur);
            etre->y=alea(1,hauteur);
        }while(CARTE(etre->x,etre->y).type);
    }
    else
    {
        etre->x=x;
        etre->y=y;
    }
    etre->direction=alea(0,1);
    etre->deplacement=alea(0,1);
    
    etre->type=type;
    etre->objectif=0;
    etre->objectif_etat=0;
    etre->action=RIEN;
    etre->nombre_predateurs=0;
    etre->cible=NULL;
    
    if(etre->type > ARBRE)
    {
        etre->etat=JEUNE;
        etre->masse=3;
    }
    else
    {
        etre->etat=INDEFINI;
        etre->masse=5;
    }
    
    etre->sante=sante[etre->masse-1];
    etre->compteur=0;
    etre->viande=etre->masse+1;

    etre->reproduction=REPRODUCTION;
    etre->vie=VIE(etre->masse);
    etre->faim=FAIM(etre->masse);
    
    CARTE(etre->x,etre->y)=*etre;
}

void affichage(Element etre)
{
    char *bmp,i;
    char sprites_animaux[2][2][4][8]={
                                        {
                                            {{0,0,0,0,24,152,112,80},{0,0,0,0,140,124,120,72},{0,0,0,0,140,124,120,72},{0,0,0,0,72,120,124,140}},        //herbivore tourné vers la gauche
                                            {{0,0,0,0,192,200,112,80},{0,0,0,0,196,248,120,72},{0,0,0,0,196,248,120,72},{0,0,0,0,72,120,248,196}}        //herbivore tourné vers la droite
                                        },{
                                            {{0,0,0,0,152,120,144,72},{0,0,0,128,108,252,144,72},{0,0,0,128,108,252,144,72},{0,0,0,0,72,144,252,108}},    //carnivore tourné vers la gauche
                                            {{0,0,0,0,200,240,72,144},{0,0,0,4,216,252,36,72},{0,0,0,4,216,252,36,72},{0,0,0,0,72,36,252,216}}            //carnivore tourné vers la droite
                                        }
                                  };
    char sprites_vegetaux[2][8]={{0,0,0,0,0,40,16,16},{0,24,60,126,60,24,24,60}};
                        
    if(etre.type > ARBRE)
    {
        bmp=sprites_animaux[etre.type-3][etre.direction][etre.etat-1];
    }
    else if(etre.type)bmp=sprites_vegetaux[etre.type-1];
    
    if(etre.type)ML_bmp_or(bmp,7*etre.x-6,8*etre.y-7,7,8);
}

void clear(short x,short y)
{
    char bmp[8]={1,1,1,1,1,1,1,1};
    ML_bmp_8_and(bmp,7*x-6,8*y-7);
}

void deplacement(Element *etre,short hauteur,short largeur,Element *carte)
{
    short x=etre->x,y=etre->y;
    char i,move_x=0,move_y=0;
    
    if(etre->cible!=NULL)
    {    
        if(x > etre->cible->x)move_x=-1;
        else move_x=1;
        if(y > etre->cible->y)move_y=-1;
        else move_y=1;
    
        if(etre->action==FUITE)
        {
            move_x*=-1;
            move_y*=-1;
        }
        if(etre->deplacement)
        {
            if(!CARTE(x,y+move_y).type && y+move_y>=1 && y+move_y<=hauteur)y+=move_y;
            else if(!CARTE(x+move_x,y).type && x+move_x>=1 && x+move_x<=largeur)x+=move_x;
        }
        else
        {
            if(!CARTE(x+move_x,y).type && x+move_x>=1 && x+move_x<=largeur)x+=move_x;
            else if(!CARTE(x,y+move_y).type && y+move_y>=1 && y+move_y<=hauteur)y+=move_y;
        }
    }
    else if(!move(etre->x,etre->y,&x,&y,1,carte,hauteur,largeur))return;
    
    if(etre->x!=x || etre->y!=y || etre->cible==NULL)
    {
        if(etre->x==x-1)etre->direction=1;
        if(etre->x==x+1)etre->direction=0;
        
        CARTE(etre->x,etre->y).type=0;
        clear(etre->x,etre->y);
        etre->x=x;
        etre->y=y;
        CARTE(x,y)=*etre;
        affichage(*etre);
    }
}

void reproduction_vegetal(Liste *liste,Element *etre,short hauteur, short largeur,Element *carte)
{
    short x,y;
    
        if(!move(etre->x,etre->y,&x,&y,1+(etre->type==2),carte,hauteur,largeur) && !etre->reproduction)
        {
            insertion(liste,largeur,hauteur,carte,0,x,y,etre->type);
            affichage(*etre);
        }
}

void recherche(Element *etre,Element *carte,short hauteur,short largeur)
{
    char i,j,distance=0,Champ_de_vision=5;
    short x=etre->x,y=etre->y;
    int truc;
    Element element;
    
    for(i=-Champ_de_vision*(!etre->direction);i<=Champ_de_vision*etre->direction;i++)
    {
        for(j=-Champ_de_vision;j<=Champ_de_vision;j++)
        {
            if(j+y>=1 && j+y<=hauteur && i+x>=1 && i+x<=largeur && (j || i) && i+j<=Champ_de_vision)
            {
                element=CARTE(x+i,y+j);
                if(element.type>0 && element.type<5 && (((element.type==etre->objectif && (element.etat==etre->objectif_etat || etre->objectif_etat==INDEFINI)) && i+j<distance) || (element.type==CARNIVORE && element.cible==etre && etre->type==HERBIVORE)))
                {
                    ciblage(etre,&element);
                    etre->test=&element;
                    distance=i+j;
                    if(element.type==CARNIVORE && element.cible==etre && etre->type==HERBIVORE)
                    {
                        etre->action=FUITE;
                        return;
                    }
                }
            }
        }
    }
}

void objectif(Element *etre)
{
    if(etre->reproduction && etre->etat==MOYEN)etre->reproduction--;
    if(etre->etat!=JEUNE)etre->faim--;
    
    if(etre->cible!=NULL)
    {
        if(etre->cible->cible!=etre && etre->action==FUITE)
        {
            etre->action=RIEN;
            ciblage(etre,NULL);
        }
        else return;
    }
    
    if(!etre->reproduction)
    {
        etre->objectif=etre->type;
        etre->objectif_etat=MOYEN;
        etre->action=ACCOUPLEMENT;
    }
    
    if(etre->faim<=0)
    {
        if(etre->type==CARNIVORE)
        {
            etre->objectif=HERBIVORE;
            etre->objectif_etat=INDEFINI;
        }
        else
        {
            etre->objectif=PETITE_PLANTE;
            etre->objectif_etat=INDEFINI;
        }
        etre->action=MANGER;
    }
}

void action(Element *etre,short faim,Liste *liste,Element *carte,short hauteur,short largeur)
{
    int i;
    
    if(etre->action==MANGER)
    {
        if(etre->cible->type > ARBRE  && etre->cible->etat != MORT)etre->cible->sante--;
        else
        {
            if(etre->cible->type > ARBRE)
            {
                if(!etre->cible->viande--)
                {
                    clear(etre->cible->x,etre->cible->y);
                    CARTE(etre->cible->x,etre->cible->y).type=0;
                    etre->cible->etat=INEXISTANT;
                    ciblage(etre,NULL);
                }
                etre->faim+=10;
            }
            else
            {
                clear(etre->cible->x,etre->cible->y);
                CARTE(etre->cible->x,etre->cible->y).type=0;
                etre->cible->etat=INEXISTANT;
                ciblage(etre,NULL);
                etre->faim+=5;
            }
            
            if(etre->faim >= faim)
            {
                etre->faim=faim;
                etre->objectif=0;
            }
        }
    
    }
}

char move(short x1,short y1,short *x2,short *y2,char distance,Element *carte,short hauteur, short largeur)
{
    char direction,i,d[]={0,0,0,0};
    do
    {
        i=0;
        *x2=x1;
        *y2=y1;
        direction=alea(1,4);
        
        *x2+=distance*(direction==2);
        *x2-=distance*(direction==4);
        *y2+=distance*(direction==3);
        *y2-=distance*(direction==1);
        
        if(CARTE(*x2,*y2).type || *x2<1 || *x2>largeur || *y2<1 || *y2>hauteur)
        {
            d[direction-1]=1;
            i=1;
        }
        
        if(d[0] && d[1] && d[2] && d[3])return 0;
    }while(i);
    return 1;
}

void erreur()
{
    ML_clear_screen();
    ML_clear_vram();
    PrintXY(1,1,"Erreur, faites un reboot de la calto",0);
    ML_display_vram();
    while(1);
}

int abs(int nombre)
{
    if(nombre<0)return -nombre;
    else return nombre;
}

void ciblage(Element *etre,Element *cible)
{
    if(etre->cible != NULL)etre->cible->nombre_predateurs--;
    etre->cible=cible;
    if(etre->cible != NULL)etre->cible->nombre_predateurs++;
}

//Gestion de la liste chaînée :

Liste *initialisation()
{
    Liste *liste=NULL;
    Element *element=NULL;
    liste=malloc(sizeof(*liste));
    element=malloc(sizeof(*element));
    
    if (liste==NULL || element==NULL)erreur();
    
    element->suivant=NULL;
    element->precedent=NULL;
    liste->premier=element;
    liste->dernier=element;
    liste->taille=1;
    
    return liste;
}

void insertion(Liste *liste,short largeur,short hauteur,Element *carte,char hasard,short x,short y,Type type)
{
    Element *nouveau=NULL;
    nouveau=malloc(sizeof(*nouveau));
    if (liste == NULL || nouveau == NULL)erreur();
    
    creation_etre(nouveau,largeur,hauteur,type,carte,hasard,x,y);
    
    liste->dernier->suivant=nouveau;
    nouveau->precedent=liste->dernier;
    liste->dernier=nouveau;
    nouveau->suivant=NULL;
    liste->taille++;
}

void suppression(Liste *liste,Element *element)
{
    if (liste==NULL)erreur();
    
    if(liste->premier!=element)element->precedent->suivant=element->suivant;
    else liste->premier=element->suivant;
    
    if(liste->dernier!=element)element->suivant->precedent=element->precedent;
    else liste->dernier=element->precedent;
    
    liste->taille--;
    free(element);
}






#pragma section _BR_Size
unsigned long BR_Size;
#pragma section


#pragma section _TOP

int InitializeSystem(int isAppli, unsigned short OptionNum)
{
    return INIT_ADDIN_APPLICATION(isAppli, OptionNum);
}

#pragma section



Mes énumérations et la structure en question :
typedef struct Element Element;
typedef struct Liste Liste;


enum Type
{
    PETITE_PLANTE=1,ARBRE=2,HERBIVORE=3,CARNIVORE=4
};

enum Etat
{
    INDEFINI=0,JEUNE=1,MOYEN=2,VIEUX=3,MORT=4,INEXISTANT=5
};

enum Action
{
    RIEN=0,REGROUPEMENT=1,ACCOUPLEMENT=2,MANGER=3,FUITE=4
};

typedef enum Type Type;
typedef enum Etat Etat;
typedef enum Action Action;


struct Liste
{
    short taille;
    Element *premier;
    Element *dernier;
};


struct Element
{
    enum Type type;
    short vie;
    short reproduction;

    //Animaux uniquement :
    short x;
    short y;
    char direction;
    char deplacement;
    
    signed short faim;
    enum Etat etat;
    
    char masse;
    char sante;
    char compteur;
    char viande;
    
    char nombre_predateurs;
    enum Action action;
    char objectif;
    enum Etat objectif_etat;
    Element *cible;
    Element *test;
    
    Element *suivant;
    Element *precedent;
};

Remiweb Hors ligne Membre de CreativeCalc Points: 1040 Défis: 32 Message

Citer : Posté le 07/05/2014 21:58 | #


Génial, c'est exactement le genre de projet que je rêvais de faire !
Enfin moi je pensais plus à des petites formes de vie avec lesquelles on peut un minimum interagir pour influencer leurs développement. Le but étant qu'a chaque partie on arrive à quelque chose de presque unique.

J'ai hâte de voir ça en tout cas
Tweaks : ||||| ||||
Lephenixnoir En ligne Administrateur Points: 24259 Défis: 170 Message

Citer : Posté le 07/05/2014 21:59 | #


On peut avoir les définitions de tes structures ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm Hors ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 07/05/2014 22:01 | #


Bonne chance pour le projet !
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Citer : Posté le 07/05/2014 22:03 | #


Merci à vous
@Lephenixnoir : la voici (dans le message au-dessus)

Édit : demandez-moi si vous voulez des précisions
Eltoredo Hors ligne Modérateur Points: 4301 Défis: 35 Message

Citer : Posté le 07/05/2014 22:09 | #


Signature !
La procrastination est une vertu. (voir ma description pour comprendre mon raisonnement)
Lephenixnoir En ligne Administrateur Points: 24259 Défis: 170 Message

Citer : Posté le 07/05/2014 22:21 | #


Je n'ai rien vu d'évident dans le code (mais il faudra regarder la gestion des pointeurs en détail).
N'es-tu tout de même pas arrivé à déterminer quelle fonction ou quelle partie de la gestion pouvait générer ces erreurs ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm Hors ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 07/05/2014 22:33 | #


Je sais pas si c'est moi qui ai mal lu, mais je n'ai pas l'impression que tu initialise avec NULL tes pointeurs lors de la création d'un nouvel élément...
Il faudrait déjà commencer par là, même si c'est pas de là que viens le bug
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Citer : Posté le 07/05/2014 23:08 | #


@Lephenixnoir : ce qui est sûr c'est que ça se passe pendant la boucle de gestion de l'écosystème (je vais la colorer en rouge, ce sera plus clair), mais je n'en sait pas plus.
J'ai d'abord cru que c'était un problème de la fonction "recherche" dont le rôle est de trouver une cible, mais je suis de plus en plus convaincu que c'est une autre fonction qui est concernée.

@Dark Storm : tous les pointeurs (sauf test) sont initialisés. C'est juste que "précédent" et "suivant" interviennent dans la gestion de la liste chaînée, donc je ne les initialise pas dans la fonction "creation_etre" mais plutôt dans la fonction "insertion".
Darkysun Hors ligne Membre Points: 1747 Défis: 52 Message

Citer : Posté le 07/05/2014 23:09 | #


c'est normall un cf premier post sans lien ?
sinon quoi signature elto ?
Si je ne réponds pas à un post depuis trop longtemps : envoyez-moi un message pour me le rappeler !




Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Citer : Posté le 07/05/2014 23:13 | #


Oui c'est normal : dans le post principal je parlerai de l'avancée du projet, donc je ne veux pas l'encombrer avec quelque chose d'aussi secondaire et éphémère qu'une demande d'aide
Eltoredo Hors ligne Modérateur Points: 4301 Défis: 35 Message

Citer : Posté le 07/05/2014 23:14 | #


Signature = Je le met dans ma signature xD
La procrastination est une vertu. (voir ma description pour comprendre mon raisonnement)
Az Hors ligne Membre de CreativeCalc Points: 548 Défis: 10 Message

Citer : Posté le 08/05/2014 00:02 | #


Une sorte de LIFE sur calto? J'en ai déjà mais il ne marchais pas . J'adore l'idée! J'ai hâte d'essayer

Ajouté le 08/05/2014 à 03:15 :
Bah signature aussi alors
Je fais du Biohacking, des jeux vidéo et j'écris... Un lien pour les controler tous et dans les ténèbres les lier https://linktr.ee/axelfougues
Lephenixnoir En ligne Administrateur Points: 24259 Défis: 170 Message

Citer : Posté le 08/05/2014 06:44 | #


Je peux savoir à quoi sert le while(1); vide, à la dernière ligne rouge ?

Un peu plus haut, tu définis que si !element->viande, element disparaît. Or l'appel à la fonction suppression est soumis à deux à conditions:
if(element->etat==INEXISTANT && !element->nombre_predateurs)suppression(liste,element);

Ce qui veut dire que s'il reste des prédateurs, l'élément ne disparaît pas, donc ces prédateurs pointent sur un élément vide. Ceci ne sera corrigé qu'au tour suivant, donc on a des résidus d'êtres inexistants d'un tour sur l'autre.

Mais surtout, le ciblage(element,NULL) ne s'effectue que si element->vie!=MORT. Or si un animal "meurt" alors qu'il lui reste des prédateurs, on ne passe pas par la fonction supprimer(), donc on a juste un appel à clear() et l'affection de INEXISTANT à son élément vie.

Donc encore une fois, une "fuite" de mémoire jusqu'au tour suivant.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Totoyo Hors ligne Membre d'honneur Points: 16093 Défis: 102 Message
Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Citer : Posté le 08/05/2014 10:40 | #


Merci Totoyo

En fait l'ajout de l'état INEXISTANT a justement été fait dans le but d'éviter que d'éventuels prédateurs pointent sur un élément vide. Lorsqu'un animal est mort et entièrement décomposé, il ne sert à rien mais si je le supprime, c'est justement ça qui va faire en sorte que les prédateurs pointeront sur une structure inexistante.
Par conséquent, une condition en début de boucle initialise le pointeur cible de chaque être à NULL si element->cible->état==INEXISTANT . Ainsi, l'être mort et décomposé n'est supprimé que lorsque tous ses prédateurs ont abandonné leur cible

D'ailleurs je ne sais pas où tu as vu un "if(element->vie != MORT)ciblage(element,NULL);", etant donné que la composante vie est un short et non une énumération

Quant au while(1), c'est juste quelque chose que j'avais placé au tout début, pour me rassurer...histoire de d'abord tester l'arrêt de la simulation avant la déletion de l'ecosystème (enfin bon, c'était juste par rigueur et dans le but de ne pas brûler les étapes, mais en réalité il ne sert à rien ).
Lephenixnoir En ligne Administrateur Points: 24259 Défis: 170 Message

Citer : Posté le 08/05/2014 10:47 | #


Oui, c'est element->etat != MORT.
Ce que je veux dire, c'est que les prédateurs n'abandonnent leurs proies que s'ils ne sont pas morts au tour suivant. Et si ils meurent au même tour ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Citer : Posté le 08/05/2014 11:04 | #


C'est pas faux, en fait il suffit d'initialiser systématiquement le pointeur à NULL en cas de mort
Lephenixnoir En ligne Administrateur Points: 24259 Défis: 170 Message

Citer : Posté le 08/05/2014 11:07 | #


Et surtout, je ne vois pas pourquoi tu ne réorganises pas ta boucle de traitement pour que l'element mort soit détruit avant le tour suivant.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
1, 2, 3 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 50 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd