#include #include #include #include #include /* * Ce petit simulateur de Loris Marchal est fourni comme exemple, SANS GARANTIE: il se * peut qu'il contiennent des erreurs. * */ /* * les paramètres de la simulation * * (ce sont des valeurs choisies au hasard: * adaptez-les tant que vous voulez !) * */ /* age de reprodution des requins */ #define BREEDING_AGE_SHARK 50 /* age de reprodution des sardines */ #define BREEDING_AGE_SARDINE 15 /* probabilité de reprodution des requins */ #define PROBA_SHARK 0.1 /* probabilité de reprodution des sardines */ #define PROBA_SARDINE 0.3 /* période de famine des requins */ #define T_FAMINE 20 /* * Variables globales */ #define SARDINE 1 #define SHARK 2 int ocean_size; struct fish_struct_t { char type; char age; char age_before_starvation; char not_to_treat; }; typedef struct fish_struct_t *fish_t; fish_t *ocean; int nb_of_sharks = 0; int nb_of_sardines = 0; /* * parse_file(filename) * * Lit le fichier de description de l'océan * et initialise les données. * */ void parse_file(char *filename) { FILE *input_file; int x,y,age; char type[20]; int line=1; input_file = fopen(filename,"r"); if (!input_file) { fprintf(stdout,"Unable to open file %s\n",filename); abort(); } if (fscanf(input_file, "%d\n", &ocean_size) != 1) { fprintf(stdout,"Unable to read ocean_size in %s\n",filename); abort(); } ocean = (fish_t*) calloc(ocean_size * ocean_size,sizeof(fish_t)); while (fscanf(input_file, "%d %d %s %d\n", &x, &y, type, &age)==4) { fish_t fish; fish = (fish_t) malloc(sizeof(struct fish_struct_t)); if (strcmp(type,"shark")==0) { fish->type = SHARK; nb_of_sharks++; } else if (strcmp(type,"sardine")==0) { fish->type = SARDINE; nb_of_sardines++; } else { fprintf(stdout,"Unknown type of fish \"%s\"\n",type); abort(); } fish->age = age; fish->age_before_starvation = T_FAMINE; line++; ocean[(y*ocean_size)+x] = fish; } if (!feof(input_file)) { fprintf(stdout,"Problem while parsing line %d of file %s\n",line,filename); abort(); } } /* * simul_one_step() * * Effectue une étape de simulation * */ void simul_one_step(void) { int x,y; for(x=0; xnot_to_treat) { fish->not_to_treat = 0; continue; } fish->age++; switch (fish->type) { case SHARK: fish->age_before_starvation--; if (fish->age > BREEDING_AGE_SHARK) { fish->age--; /* to avoid overflow: no need to consider shark older than this age */ } if (fish->age_before_starvation == 0) { free(fish); ocean[(y*ocean_size)+x]=NULL; nb_of_sharks--; } else { direction = (int) (4.0*rand()/(RAND_MAX+1.0)); x_target = x; y_target =y; switch (direction) { case 0: x_target++; break; case 1: y_target++; break; case 2: x_target--; break; case 3: y_target--; break; } if (x_target < 0) x_target+=ocean_size; if (y_target < 0) y_target+=ocean_size; if (x_target == ocean_size) x_target = 0; if (y_target == ocean_size) y_target = 0; fish_at_target = ocean[y_target * ocean_size + x_target]; if ((fish_at_target != NULL) && (fish_at_target->type == SARDINE)) { free(fish_at_target); nb_of_sardines--; ocean[y_target * ocean_size + x_target] = NULL; fish_at_target = NULL; fish->age_before_starvation = T_FAMINE; } if (fish_at_target == NULL) { /* moving */ if ((direction == 0) || (direction == 1)) { /* if the fish moves right or down, take care not to treat it a second time in this step */ fish->not_to_treat = 1; } ocean[y_target * ocean_size + x_target] = fish; ocean[y * ocean_size + x] = 0; /* breeding ? */ if (fish->age >= BREEDING_AGE_SHARK) { if (((1.0*rand())/(RAND_MAX+1.0)) < PROBA_SHARK) { /* a new shark ! */ fish_t new_shark = (fish_t) malloc(sizeof(struct fish_struct_t)); new_shark->type = SHARK; new_shark->age = 0; new_shark->age_before_starvation = T_FAMINE; ocean[y * ocean_size + x] = new_shark; nb_of_sharks++; } } } } break; case SARDINE: if (fish->age > BREEDING_AGE_SARDINE) { fish->age--; /* to avoid overflow: no need to consider sardine older than this age */ } direction = (int) (4.0*rand()/(RAND_MAX+1.0)); x_target = x; y_target =y; switch (direction) { case 0: x_target++; break; case 1: y_target++; break; case 2: x_target--; break; case 3: y_target--; break; } if (x_target<0) x_target+=ocean_size; if (y_target<0) y_target+=ocean_size; if (x_target == ocean_size) x_target = 0; if (y_target == ocean_size) y_target = 0; fish_at_target = ocean[y_target * ocean_size + x_target]; if (fish_at_target == NULL) { /* moving */ if ((direction == 0) || (direction == 1)) { /* if the fish moves right or down, take care not to treat it a second time in this step */ fish->not_to_treat = 1; } ocean[y_target * ocean_size + x_target] = fish; ocean[y * ocean_size + x] = 0; /* breeding ? */ if (fish->age >= BREEDING_AGE_SARDINE) { if (((1.0*rand())/(RAND_MAX+1.0)) < PROBA_SARDINE) { /* a new sardine ! */ fish_t new_sardine = (fish_t) malloc(sizeof(struct fish_struct_t)); new_sardine->type = SARDINE; new_sardine->age = 0; new_sardine->age_before_starvation = T_FAMINE; ocean[y * ocean_size + x] = new_sardine; nb_of_sardines++; } } } break; } } } /* * print_ocean() * * Permet l'affichage de la grille, si celle-ci est de petite taille. * */ void print_ocean(void) { int x,y; int requins = 0; int sardines = 0; fprintf(stdout," "); for(x=0; xtype == SHARK) { fprintf(stdout,"\033[31mR\033[00m"); requins++; } else { fprintf(stdout,"S"); sardines++; } } else fprintf(stdout," "); } fprintf(stdout,"|\n"); } fprintf(stdout," "); for(x=0; x \n",argv[0]); exit(1); } parse_file(argv[1]); max_step = atoi(argv[2]); for(step=0; step