/* ******************************** */ /* WOLF.C */ /* A Wolf Population Simulation */ /* rps Microsoft C version */ /* (c) Copyright 1987,'95 R P Sarna */ /* Maine Maritime Academy */ /* Castine, Maine 04420 */ /* All Rights Reserved */ /* May be copied for non-commercial */ /* use. */ /* Routines may also be used for */ /* non-commercial uses. */ /* Please tell me if you find it */ /* useful! */ /* ******************************** */ /* *************************************************************** */ /* Note this kind of simulation actually creates "individuals". */ /* you can actually track the life of each individual, if you wish */ /* */ /* The routines were originally used to force optimum scheduling */ /* for logging operations analysis. A looooong time ago! */ /* */ /* Somebody should put better wolf data in it. */ /* */ /* Note that you can modify it to either accept a starting number */ /* from the user, or get one depending on the system clock. */ /* */ /* To contact me: */ /* sarna@saturn.caps.maine.edu */ /* *************************************************************** */ #include #include #ifdef MSC #include #endif #include char id[] = "$Header: c:/programs/rcs/wolf.c 1.5 95/06/27 08:42:31 Red Exp $"; char copyrite[] = "Copyright (c) 1995 R. P. Sarna All Rights Reserved."; char copyleft[] = "Permission granted for non-profit copying and Distribution."; /* event definitions: */ #define STATS 0 #define BIRTH 1 #define DEATH 2 #define ENDSM 10 /* define sex number: */ #define MALE 1 #define FEMALE 0 struct link { /* structure definition for link in queue */ int time; char priority; char event; int wolfnum; int sex; struct link *lastptr; struct link *nextptr; }; struct link *beginlink; struct link *endlink; struct vect { /* vector type (for each event) */ int vtime; char vprior; char vevent; int vwolfnum; int vsex; }; struct vect *vector; /* function declarations */ void init(void); /* initialize simulation */ void add2q(void); /* add event to queue */ void mallerr(void); /* exit if memory allocation error */ void birth(void); /* birth of wolf event, set up future births */ void death(void); /* death of wolf event */ void stats(void); /* event to print out statistics */ void endsim(void); /* event to end simulation */ void getone(void); /* get next event from queue */ void typeout(void); /* print information at beginning */ void *malloc(size_t size); /* standard C memory allocation */ void free(void *memblock); /* standard C freeing of allocated memory */ int rand(void); /* standard C random number function */ void srand(unsigned int seed); /* standard C seed random number */ int timenow; /* present simulated time */ int population; /* present population */ int lastwolf; /* wolf serial numbers */ int males; /* present number of males */ int females; /* present number of females */ int sfactor; /* starvation factor if population too high */ /* to put copyright into object code */ char copyrt1[]= "(c) Copyright 1987,1995 R P Sarna"; char copyrt2[]= "39 Cushnoc Drive"; char copyrt3[]= "Augusta, ME 04330"; char copyrt4[]= "All Rights Reserved"; char copyrt5[]= "May be copied for non-commercial use"; char copyrt6[]= "if copied intact"; long clock(); void main(void) { init(); while (1) { getone(); timenow = vector->vtime; if (vector->vevent == STATS) { stats(); continue; } if (vector->vevent == BIRTH) { birth(); continue; } if (vector->vevent == DEATH) { death(); continue; } if (vector->vevent == ENDSM) endsim(); } } void init(void) { int garbchar; unsigned seed; char throwaway[80]; timenow = 0; population = 2; lastwolf = 2; males = 1; females = 1; if ((beginlink = (struct link *)malloc(sizeof(*beginlink))) == NULL) mallerr() ; if ((endlink = (struct link *)malloc(sizeof(*beginlink))) == NULL) mallerr() ; if ((vector = (struct vect *)malloc(sizeof(*vector))) == NULL) mallerr() ; endlink->nextptr = NULL; endlink->lastptr = beginlink; beginlink->nextptr = endlink; beginlink->lastptr = NULL; beginlink->time = -32768; beginlink->priority = 0; endlink->time = 32767; endlink->priority = 255; /* Put in first birth: */ vector->vtime = 1; vector->vprior = 10; vector->vevent = BIRTH; vector->vwolfnum = 0; /* numbered at birth */ vector->vsex = FEMALE; add2q(); /* Put in death of wolf #1: */ vector->vtime = 5; vector->vprior = 5; vector->vevent = DEATH; vector->vwolfnum = 1; /* numbered at birth */ vector->vsex = MALE; add2q(); /* Put in death of wolf #2: */ vector->vtime = 5; vector->vprior = 5; vector->vevent = DEATH; vector->vwolfnum = 2; /* numbered at birth */ vector->vsex = FEMALE; add2q(); /* Put in End-Of-Simulation event: */ vector->vtime = 25; vector->vprior = 0; vector->vevent = ENDSM; vector->vwolfnum = 0; vector->vsex = 0; add2q(); /* Put in first printout of statistics: */ vector->vtime = 10; vector->vprior = 100; vector->vevent = STATS; vector->vwolfnum = 0; vector->vsex = 0; add2q(); /* Tell about this simulation: */ typeout(); /* Set up random number generator and begin: */ seed = (unsigned)(clock()) & 0x0000FFFF; fprintf(stderr, "\nPress to begin:"); gets(throwaway); seed = (unsigned)(clock() & 0x0000FFFF); srand(seed); } void mallerr(void) { /* Exception Handler For Memory Allocation: */ fprintf(stderr, "\nERROR: Memory allocation failure\n"); exit(1); } void add2q(void) /* Version with priorities */ { struct link *biglink; struct link *nextlink; struct link *newlink; if ((newlink = (struct link *)malloc(sizeof(*beginlink))) == NULL) mallerr() ; biglink = endlink; nextlink = (*biglink).lastptr; while (1) { /* T != */ if ((vector->vtime < biglink->time) && (vector->vtime > nextlink->time)) { biglink->lastptr = newlink; newlink->nextptr = biglink; newlink->lastptr = nextlink; nextlink->nextptr = newlink; newlink->time = vector->vtime; newlink->priority = vector->vprior; newlink->event = vector->vevent; newlink->wolfnum = vector->vwolfnum; newlink->sex = vector->vsex; break; } /* = T */ if ((vector->vtime == nextlink->time) && /* < P */ (vector->vprior >= nextlink->priority)) { biglink->lastptr = newlink; newlink->nextptr = biglink; newlink->lastptr = nextlink; nextlink->nextptr = newlink; newlink->time = vector->vtime; newlink->priority = vector->vprior; newlink->event = vector->vevent; newlink->wolfnum = vector->vwolfnum; newlink->sex = vector->vsex; break; } /* = T = */ if ((vector->vtime == biglink->time) && /* <= P <= */ (vector->vtime == nextlink->time) && (vector->vprior >= nextlink->priority) && (vector->vprior <= biglink->priority)) { biglink->lastptr = newlink; newlink->nextptr = biglink; newlink->lastptr = nextlink; nextlink->nextptr = newlink; newlink->time = vector->vtime; newlink->priority = vector->vprior; newlink->event = vector->vevent; newlink->wolfnum = vector->vwolfnum; newlink->sex = vector->vsex; break; } /* T = */ if ((vector->vtime == biglink->time) && /* P <= */ (vector->vtime != nextlink->time) && (vector->vprior <= biglink->priority)) { biglink->lastptr = newlink; newlink->nextptr = biglink; newlink->lastptr = nextlink; nextlink->nextptr = newlink; newlink->time = vector->vtime; newlink->priority = vector->vprior; newlink->event = vector->vevent; newlink->wolfnum = vector->vwolfnum; newlink->sex = vector->vsex; break; } else { biglink = nextlink; nextlink = biglink->lastptr; } } } void getone(void) { /* Get next event and put it into vector: */ struct link *smalllink; struct link *nextlink; struct link *dellink; smalllink = beginlink; nextlink = smalllink->nextptr; if (nextlink->time == 32767) { fprintf(stderr,"\nERROR: Attempt to get event from empty queue\n"); exit(1); } dellink = nextlink; nextlink = dellink->nextptr; smalllink->nextptr = nextlink; nextlink->lastptr = smalllink; vector->vtime = dellink->time; vector->vprior = dellink->priority; vector->vevent = dellink->event; vector->vwolfnum = dellink->wolfnum; vector->vsex = dellink->sex; free(dellink); return; } void birth(void) { int breedage; int lifespan; int i,j; int sex; sex = vector->vsex; /* Are there any adults left? */ if (population < 1) return; /* Are there any males left? */ if (males < 1) { printf("\nSorry, no males left, so no births, though scheduled."); return; } /* Update population: */ population++; lastwolf++; printf("\nCongratulations on the birth of new "); if (sex == MALE) { printf("male "); males++; } if (sex == FEMALE) { printf("female "); females++; } printf("puppy #%d", lastwolf); /* Determine breeding age: */ breedage = (rand() % 2); /* 0 or 1 */ breedage = breedage + 1; /* 1 - 2 years, total */ /* Determine lifespan: */ lifespan = (rand() % 9); /* 0 - 8 */ /* Create death event for parent: */ vector->vtime = timenow + lifespan; /* 0 - 5 years */ vector->vprior = 5; vector->vevent = DEATH; vector->vwolfnum = lastwolf; vector->vsex = sex; add2q(); if (lifespan == 0) return; /* If male, that's it: */ if (sex == MALE) return; /* As pack grows, so does starvation factor: */ if (population >= 20) sfactor = 4; /* high population */ if (population < 20) sfactor = 2; /* pack too big */ if (population < 15) sfactor = 0; /* pack size ok */ /* If still alive and female, births may occur, create them: */ for (j = breedage; j <= lifespan; j++) { /* 0 - 6 offspring */ for (i = 0; i < ((rand() % 7) - sfactor); i++) { vector->vtime = timenow + breedage + j; vector->vprior = 10; vector->vevent = BIRTH; vector->vwolfnum = 0; /* numbered at birth */ vector->vsex = (rand() % 2); /* 0 or 1 */ add2q(); } } } void death(void) { /* Change population: */ population--; printf("\nSincere sympathy on the death of "); if (vector->vsex == MALE) { printf("male "); males--; } if (vector->vsex == FEMALE) { printf("female "); females--; } printf("wolf #%d", vector->vwolfnum); } void stats(void) { /* Print out statistics: */ printf("\n==================="); printf("\nSTATISTICS:"); printf("\n-------------------"); printf("\n Year: %d", timenow); printf("\n Population: %d", population); printf("\n males: %d", males); printf("\n females: %d", females); printf("\n# of wolves: %d", lastwolf); printf("\n==================="); /* Put in next printout of statistics: */ vector->vtime = timenow + 10; vector->vprior = 100; vector->vevent = STATS; vector->vwolfnum = 0; vector->vsex = 0; add2q(); } void endsim(void) { /* End simulation: */ printf("\n==================="); printf("\n==================="); printf("\nEND OF SIMULATION: "); printf("\n==================="); stats(); printf("\n===================\n"); exit(0); } void typeout(void) { fprintf(stderr, "\n WOLF POPULATION SIMULATION"); fprintf(stderr, "\n\nThis is a simulation of a wolf population. It is"); fprintf(stderr, "\nstochastic; that is, individual wolves are born or die"); fprintf(stderr, "\ndepending on the result of a random number generator."); fprintf(stderr, "\nThe random (actually pseudo-random) number generator"); fprintf(stderr, "\nuses a 'seed' at the start; this comes from the computer's"); fprintf(stderr, "\nclock. Therefore, each time you run the program, you"); fprintf(stderr, "\ncan get different answers. This is as it should be:"); fprintf(stderr, "\nsometimes a population prospers, sometimes it dies out."); fprintf(stderr, "\nIn general, life is rough: it is very hard, both in this"); fprintf(stderr, "\nsimulation and in the real world, to get a stable"); fprintf(stderr, "\npopulation going!"); fprintf(stderr, "\n\nThis simulation is in its very early stages. Currently,"); fprintf(stderr, "\nit assumes that the wolves live from zero to eight years. "); fprintf(stderr, "\nFrom one or two years until the end of their lives, they"); fprintf(stderr, "\nmay have from zero to six pups per year. As the pack "); fprintf(stderr, "\nsize grows, litter size will become smaller."); fprintf(stderr, "\n\nEventually, the simulation dreamed of will have wolves and"); fprintf(stderr, "\nprey, all interacting in the same fashion. Until then,"); fprintf(stderr, "\ntry this! (Redirect output to file to trace lives.)\n"); }