simul_seq.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
/*
* Ce petit simulateur est fourni comme exemple, SANS GARANTIE: il se
* peut qu'il contiennent des erreurs.
* Si vous en trouvez, de les envoyer à Loris.Marchal@ens-lyon.fr pour
* que je les mette sur la page web.
*
*/
/*
* 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; x<ocean_size; x++)
for(y=0; y<ocean_size; y++)
if (ocean[(y*ocean_size)+x]) {
fish_t fish, fish_at_target;
int direction, x_target, y_target;
fish = ocean[(y*ocean_size)+x];
if (fish->not_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; x<ocean_size+2; x++) fprintf(stdout,"-");
fprintf(stdout,"\n");
for(y=0; y<ocean_size; y++) {
fprintf(stdout,"%d|",y%10);
for(x=0; x<ocean_size; x++) {
if (ocean[y * ocean_size + x] != NULL) {
if (ocean[y * ocean_size + x]->type == 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<ocean_size+2; x++)
fprintf(stdout,"-");
fprintf(stdout,"\n");
fprintf(stdout,"%d requins et %d sardines.\n\n",requins,sardines);
}
int main(int argc, char **argv) {
int step, max_step;
if (argc != 3) {
fprintf(stdout,"Usage: %s <ocean_filename> <nb_of_steps>\n",argv[0]);
exit(1);
}
parse_file(argv[1]);
max_step = atoi(argv[2]);
for(step=0; step<max_step; step++) {
fprintf(stdout,"step %d:\n",step);
simul_one_step();
/* print_ocean(); */
fprintf(stdout,"%d requins et %d sardines.\n\n",nb_of_sharks,nb_of_sardines);
}
return 0;
}
Generated by GNU enscript 1.6.3.