Alright, you made me dig out a box of floppy disks from the garage.
I think this is it. I tried compiling it and it does compile except for some of the ancient graphics macros and obviously the linker isn't going to find any of the DOS CGA graphics routines. You'll have to update those to make it work. Shouldn't be too hard though.
Have fun!
Code:
#include <graphics.h>
#include <time.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
int dead_bug_color = 1;
int live_bug_color = 2;
int erased_bug_color = 0;
int food_color = 3;
int xmove6þ = {0,2,2,0,-2,-2};
int ymove6þ = {2,1,-1,-2,-1,1};
int bug_count, a, generation, max_bug_count;
long max_food_colonies;
double probrain;
int change_age = 1,
change_shape = 1;
int initial_number_of_bugs =10;
int initial_energy =1000;
int energy_per_turn =1;
long food_colonies =200;
int energy_for_food_pelet =40;
int age_for_reproduction =800;
int energy_to_reproduce =1000;
double probability_of_rain =0.01;
int maximum_energy =1500;
int x_hi, y_hi;
typedef struct bug {
int x_1, y_1;
int x_2, y_2;
int x_3, y_3;
int x_4, y_4;
int x_5, y_5;
int x_6, y_6;
int x_7, y_7;
int x_8, y_8;
int x_9, y_9;
int energy;
int age;
int reproduce_age;
int f, r, hr, rv, hl, l;
double prob_0, prob_1, prob_2, prob_3, prob_4, prob_5;
int direction;
struct bug *next;
struct bug *prev;
} OBJECT;
OBJECT *bug_list=NULL,
*free_list = NULL;
OBJECT *newobject()
{
OBJECT *temp;
if (free_list != NULL)
{
temp = free_list;
free_list = free_list->next;
free_list->prev = NULL;
return (temp);
}
else
return ((OBJECT *) malloc (sizeof(OBJECT)));
}
void freeobject(OBJECT *obj)
{
if (free_list != NULL)
{
obj->next = free_list;
free_list->prev = obj;
obj->prev = NULL;
}
else
{
free_list = obj;
free_list->prev=NULL;
free_list->next=NULL;
}
}
int out_of_memory()
{
closegraph();
clrscr();
printf("Out of memory error\n");
printf("Bug count: %d\n",bug_count);
exit(0);
}
int init_drivers()
{
int g_driver=DETECT, g_mode, g_error;
detectgraph(&g_driver, &g_mode);
g_error = graphresult();
if (g_error <0)
{
printf("Detect graph error: %s.\n",grapherrormsg(g_error));
exit(1);
}
if (g_driver == CGA)
{
g_mode = CGAC1;
g_driver = CGA;
x_hi=319;
y_hi=199;
dead_bug_color = 1;
live_bug_color = 2;
erased_bug_color = 0;
food_color = 3;
registerfarbgidriver(CGA_driver_far);
}
else if (g_driver == MCGA)
{
g_mode = CGAC1;
g_driver = CGA;
x_hi=319;
y_hi=199;
dead_bug_color = 1;
live_bug_color = 2;
erased_bug_color = 0;
food_color = 3;
registerfarbgidriver(CGA_driver_far);
}
else if (g_driver >= EGA && g_driver <=EGAMONO)
{
g_mode = EGAHI;
x_hi=639;
y_hi=349;
registerfarbgidriver(EGAVGA_driver_far);
}
else if (g_driver == IBM8514)
{
g_mode = IBM8514HI;
x_hi=639;
y_hi=479;
registerfarbgidriver(IBM8514_driver_far);
}
else if (g_driver == VGA)
{
g_mode = VGAHI;
x_hi=639;
y_hi=479;
registerfarbgidriver(EGAVGA_driver_far);
}
else if (g_driver == PC3270)
{
g_mode = CGAC1;
g_driver = CGA;
x_hi=319;
y_hi=199;
dead_bug_color = 1;
live_bug_color = 2;
erased_bug_color = 0;
food_color = 3;
registerfarbgidriver(CGA_driver_far);
}
else if (g_driver >= EGA64)
{
g_mode = EGA64HI;
x_hi=639;
y_hi=349;
registerfarbgidriver(EGAVGA_driver_far);
}
else
{
printf("Unsupported graphics driver, please contact the author\n");
exit(1);
}
g_error = graphresult();
if (g_error <0)
{
printf("Registration error: %s.\n",grapherrormsg(g_error));
exit(1);
}
initgraph(&g_driver, &g_mode, "");
g_error = graphresult();
if (g_error <0)
{
printf("Init graph error: %s.\n",grapherrormsg(g_error));
exit(1);
}
}
int draw_bug(OBJECT *bugs, int color)
{
putpixel(bugs->x_1, bugs->y_1, color);
putpixel(bugs->x_2, bugs->y_2, color);
putpixel(bugs->x_3, bugs->y_3, color);
putpixel(bugs->x_4, bugs->y_4, color);
putpixel(bugs->x_5, bugs->y_5, color);
putpixel(bugs->x_6, bugs->y_6, color);
putpixel(bugs->x_7, bugs->y_7, color);
putpixel(bugs->x_8, bugs->y_8, color);
putpixel(bugs->x_9, bugs->y_9, color);
}
int food_here(OBJECT *bugs)
{
int food;
int color;
food = 0;
color = getpixel(bugs->x_1,bugs->y_1);
if (color == food_color)
food++;
color = getpixel(bugs->x_2,bugs->y_2);
if (color == food_color)
food++;
color = getpixel(bugs->x_3,bugs->y_3);
if (color == food_color)
food++;
color = getpixel(bugs->x_4,bugs->y_4);
if (color == food_color)
food++;
color = getpixel(bugs->x_5,bugs->y_5);
if (color == food_color)
food++;
color = getpixel(bugs->x_6,bugs->y_6);
if (color == food_color)
food++;
color = getpixel(bugs->x_7,bugs->y_7);
if (color == food_color)
food++;
color = getpixel(bugs->x_8,bugs->y_8);
if (color == food_color)
food++;
color = getpixel(bugs->x_9,bugs->y_9);
if (color == food_color)
food++;
max_food_colonies -= (long) food;
return (food * energy_for_food_pelet);
}
int initialize_screen()
{
long i;
double exp_0, exp_1, exp_2, exp_3, exp_4, exp_5, exps;
OBJECT *temp_bug, *place_hold;
for (i=0; i<food_colonies; i++)
putpixel(random(x_hi)+1, random(y_hi)+1, food_color);
max_food_colonies = food_colonies*5;
bug_count = initial_number_of_bugs;
max_bug_count = bug_count;
bug_list = newobject();
if (bug_list == NULL)
out_of_memory();
bug_list->prev = NULL;
bug_list->next = NULL;
place_hold = bug_list;
for (i=1; i<bug_count; i++)
{
temp_bug = newobject();
if (temp_bug == NULL)
out_of_memory();
temp_bug->prev = place_hold;
place_hold->next = temp_bug;
place_hold = temp_bug;
}
place_hold->next = NULL;
temp_bug = bug_list;
for (i=0; i<bug_count; i++)
{
temp_bug->x_1 = random(x_hi);
temp_bug->y_1 = random(y_hi);
temp_bug->x_2 = temp_bug->x_1 + 1;
temp_bug->x_3 = temp_bug->x_1 + 2;
temp_bug->x_4 = temp_bug->x_1;
temp_bug->x_5 = temp_bug->x_1 + 1;
temp_bug->x_6 = temp_bug->x_1 + 2;
temp_bug->x_7 = temp_bug->x_1;
temp_bug->x_8 = temp_bug->x_1 + 1;
temp_bug->x_9 = temp_bug->x_1 + 2;
temp_bug->y_2 = temp_bug->y_1;
temp_bug->y_3 = temp_bug->y_1;
temp_bug->y_4 = temp_bug->y_1+1;
temp_bug->y_5 = temp_bug->y_1+1;
temp_bug->y_6 = temp_bug->y_1+1;
temp_bug->y_7 = temp_bug->y_1+2;
temp_bug->y_8 = temp_bug->y_1+2;
temp_bug->y_9 = temp_bug->y_1+2;
temp_bug->energy = initial_energy;
temp_bug->age = 0;
if (change_age == 1)
temp_bug->reproduce_age = age_for_reproduction + random(10)-5;
else
temp_bug->reproduce_age = age_for_reproduction;
temp_bug->l = random(9) - 4;
temp_bug->r = random(9) - 4;
temp_bug->f = random(9) - 4;
temp_bug->hr = random(9) - 4;
temp_bug->rv = random(9) - 4;
temp_bug->hl = random(9) - 4;
exp_0 = pow(2.0,(double)temp_bug->l);
exp_1 = pow(2.0,(double)temp_bug->r);
exp_2 = pow(2.0,(double)temp_bug->f);
exp_3 = pow(2.0,(double)temp_bug->hr);
exp_4 = pow(2.0,(double)temp_bug->rv);
exp_5 = pow(2.0,(double)temp_bug->hl);
exps = exp_0+exp_1+exp_2+exp_3+exp_4+exp_5;
temp_bug->prob_0 = exp_0 / exps;
temp_bug->prob_1 = exp_1 / exps;
temp_bug->prob_2 = exp_2 / exps;
temp_bug->prob_3 = exp_3 / exps;
temp_bug->prob_4 = exp_4 / exps;
temp_bug->prob_5 = exp_5 / exps;
temp_bug->direction = random(6);
draw_bug(temp_bug, live_bug_color);
temp_bug = temp_bug->next;
}
}
int reproduce (OBJECT *parent, int energy)
{
double exp_0, exp_1, exp_2, exp_3, exp_4, exp_5, exps;
OBJECT *temp_bug, *place_hold;
temp_bug = bug_list;
bug_count++;
if (bug_count > max_bug_count)
max_bug_count = bug_count;
place_hold = newobject();
if (place_hold == NULL)
out_of_memory();
place_hold->prev = NULL;
temp_bug->prev = place_hold;
place_hold->next = temp_bug;
bug_list = place_hold;
temp_bug = place_hold;
temp_bug->age = 0;
if (change_age == 1)
temp_bug->reproduce_age = parent->reproduce_age + random(10)-5;
else
temp_bug->reproduce_age = parent->reproduce_age;
temp_bug->energy = energy;
temp_bug->x_1 = parent->x_1;
temp_bug->y_1 = parent->y_1;
if (change_shape == 1)
{
temp_bug->x_2 = parent->x_2 + random (3) - 1;
temp_bug->y_2 = parent->y_2 + random (3) - 1;
temp_bug->x_3 = parent->x_3 + random (3) - 1;
temp_bug->y_3 = parent->y_3 + random (3) - 1;
temp_bug->x_4 = parent->x_4 + random (3) - 1;
temp_bug->y_4 = parent->y_4 + random (3) - 1;
temp_bug->x_5 = parent->x_5 + random (3) - 1;
temp_bug->y_5 = parent->y_5 + random (3) - 1;
temp_bug->x_6 = parent->x_6 + random (3) - 1;
temp_bug->y_6 = parent->y_6 + random (3) - 1;
temp_bug->x_7 = parent->x_7 + random (3) - 1;
temp_bug->y_7 = parent->y_7 + random (3) - 1;
temp_bug->x_8 = parent->x_8 + random (3) - 1;
temp_bug->y_8 = parent->y_8 + random (3) - 1;
temp_bug->x_9 = parent->x_9 + random (3) - 1;
temp_bug->y_9 = parent->y_9 + random (3) - 1;
}
else
{
temp_bug->x_2 = parent->x_2;
temp_bug->y_2 = parent->y_2;
temp_bug->x_3 = parent->x_3;
temp_bug->y_3 = parent->y_3;
temp_bug->x_4 = parent->x_4;
temp_bug->y_4 = parent->y_4;
temp_bug->x_5 = parent->x_5;
temp_bug->y_5 = parent->y_5;
temp_bug->x_6 = parent->x_6;
temp_bug->y_6 = parent->y_6;
temp_bug->x_7 = parent->x_7;
temp_bug->y_7 = parent->y_7;
temp_bug->x_8 = parent->x_8;
temp_bug->y_8 = parent->y_8;
temp_bug->x_9 = parent->x_9;
temp_bug->y_9 = parent->y_9;
}
temp_bug->l = random(2) - 1 + parent->l;
temp_bug->r = random(2) - 1 + parent->r;
temp_bug->f = random(2) - 1 + parent->f;
temp_bug->hr = random(2) - 1 + parent->hr;
temp_bug->rv = random(2) - 1 + parent->rv;
temp_bug->hl = random(2) - 1 + parent->hl;
exp_0 = pow(2.0,(double)temp_bug->l);
exp_1 = pow(2.0,(double)temp_bug->r);
exp_2 = pow(2.0,(double)temp_bug->f);
exp_3 = pow(2.0,(double)temp_bug->hr);
exp_4 = pow(2.0,(double)temp_bug->rv);
exp_5 = pow(2.0,(double)temp_bug->hl);
exps = exp_0+exp_1+exp_2+exp_3+exp_4+exp_5;
temp_bug->prob_0 = exp_0 / exps;
temp_bug->prob_1 = exp_1 / exps;
temp_bug->prob_2 = exp_2 / exps;
temp_bug->prob_3 = exp_3 / exps;
temp_bug->prob_4 = exp_4 / exps;
temp_bug->prob_5 = exp_5 / exps;
temp_bug->direction = random(6);
draw_bug(temp_bug, live_bug_color);
}
int move_bugs()
{
int temp_dir, turn, half_energy;
int x_move1, y_move1, x_move2, y_move2, x_move3, y_move3, x_move4,
y_move4, x_move5, y_move5, x_move6, y_move6, x_move7, y_move7,
x_move8, y_move8, x_move9, y_move9;
double new_move, p0, p1, p2, p3, p4, p5;
OBJECT *temp_bug, *prev_bug, *next_bug;
temp_bug = bug_list;
while (temp_bug != NULL)
{
new_move = (double) rand() / 32767.0;
p0 = temp_bug->prob_0;
p1 = p0 + temp_bug->prob_1;
p2 = p1 + temp_bug->prob_2;
p3 = p2 + temp_bug->prob_3;
p4 = p3 + temp_bug->prob_4;
p5 = p4 + temp_bug->prob_5;
if (new_move > 0.0 && new_move <= p0)
turn=0;
else if (new_move > p0 && new_move <= p1)
turn=1;
else if (new_move > p1 && new_move <= p2)
turn=2;
else if (new_move > p2 && new_move <= p3)
turn=3;
else if (new_move > p3 && new_move <= p4)
turn=4;
else if (new_move > p4 && new_move <= p5)
turn=5;
temp_dir = (temp_bug->direction + turn) % 6;
x_move1 = temp_bug->x_1 + xmovetemp_dirþ;
y_move1 = temp_bug->y_1 + ymovetemp_dirþ;
x_move2 = temp_bug->x_2 + xmovetemp_dirþ;
y_move2 = temp_bug->y_2 + ymovetemp_dirþ;
x_move3 = temp_bug->x_3 + xmovetemp_dirþ;
y_move3 = temp_bug->y_3 + ymovetemp_dirþ;
x_move4 = temp_bug->x_4 + xmovetemp_dirþ;
y_move4 = temp_bug->y_4 + ymovetemp_dirþ;
x_move5 = temp_bug->x_5 + xmovetemp_dirþ;
y_move5 = temp_bug->y_5 + ymovetemp_dirþ;
x_move6 = temp_bug->x_6 + xmovetemp_dirþ;
y_move6 = temp_bug->y_6 + ymovetemp_dirþ;
x_move7 = temp_bug->x_7 + xmovetemp_dirþ;
y_move7 = temp_bug->y_7 + ymovetemp_dirþ;
x_move8 = temp_bug->x_8 + xmovetemp_dirþ;
y_move8 = temp_bug->y_8 + ymovetemp_dirþ;
x_move9 = temp_bug->x_9 + xmovetemp_dirþ;
y_move9 = temp_bug->y_9 + ymovetemp_dirþ;
temp_bug->age += 1;
temp_bug->energy -= energy_per_turn;
if
(!(x_move1>x_hi || x_move1< 0 || y_move1< 0 || y_move1> y_hi) &&
!(x_move2>x_hi || x_move2< 0 || y_move2< 0 || y_move2> y_hi) &&
!(x_move3>x_hi || x_move3< 0 || y_move3< 0 || y_move3> y_hi) &&
!(x_move4>x_hi || x_move4< 0 || y_move4< 0 || y_move4> y_hi) &&
!(x_move5>x_hi || x_move5< 0 || y_move5< 0 || y_move5> y_hi) &&
!(x_move6>x_hi || x_move6< 0 || y_move6< 0 || y_move6> y_hi) &&
!(x_move7>x_hi || x_move7< 0 || y_move7< 0 || y_move7> y_hi) &&
!(x_move8>x_hi || x_move8< 0 || y_move8< 0 || y_move8> y_hi) &&
!(x_move9>x_hi || x_move9< 0 || y_move9< 0 || y_move9> y_hi))
{
draw_bug(temp_bug, erased_bug_color);
temp_bug->direction = temp_dir;
temp_bug->x_1 = x_move1;
temp_bug->y_1 = y_move1;
temp_bug->x_2 = x_move2;
temp_bug->y_2 = y_move2;
temp_bug->x_3 = x_move3;
temp_bug->y_3 = y_move3;
temp_bug->x_4 = x_move4;
temp_bug->y_4 = y_move4;
temp_bug->x_5 = x_move5;
temp_bug->y_5 = y_move5;
temp_bug->x_6 = x_move6;
temp_bug->y_6 = y_move6;
temp_bug->x_7 = x_move7;
temp_bug->y_7 = y_move7;
temp_bug->x_8 = x_move8;
temp_bug->y_8 = y_move8;
temp_bug->x_9 = x_move9;
temp_bug->y_9 = y_move9;
temp_bug->energy += food_here(temp_bug);
if (temp_bug->energy >= maximum_energy)
temp_bug->energy = maximum_energy;
draw_bug(temp_bug, live_bug_color);
}
if (temp_bug->energy <= 0)
{
prev_bug = temp_bug->prev;
next_bug = temp_bug->next;
draw_bug(temp_bug, dead_bug_color);
freeobject(temp_bug);
bug_count--;
if (bug_count == 0)
temp_bug = NULL;
else
{
if (prev_bug != NULL)
prev_bug->next = next_bug;
else
bug_list = next_bug;
if (next_bug != NULL)
next_bug->prev = prev_bug;
temp_bug = next_bug;
}
}
else if (temp_bug->age > temp_bug->reproduce_age &&
temp_bug->energy > energy_to_reproduce)
{
half_energy = temp_bug->energy/2;
draw_bug(temp_bug, erased_bug_color);
reproduce(temp_bug, half_energy);
reproduce(temp_bug, half_energy);
prev_bug = temp_bug->prev;
next_bug = temp_bug->next;
freeobject(temp_bug);
bug_count--;
if (prev_bug != NULL)
prev_bug->next = next_bug;
else
bug_list = next_bug;
if (next_bug != NULL)
next_bug->prev = prev_bug;
temp_bug = next_bug;
}
else
temp_bug = temp_bug->next;
if (kbhit()!=0)
temp_bug=NULL;
}
}
int rain()
{
long i;
long new_colonies;
new_colonies = (long) (((double) rand() / 32767) * food_colonies);
for (i=0; i<new_colonies; i++)
putpixel(random(x_hi)+1, random(y_hi)+1, food_color);
max_food_colonies += new_colonies;
}
evolve()
{
OBJECT *temp_bug;
init_drivers(); /* x_hi x y_hi */
randomize();
initialize_screen();
while (kbhit()==0 && bug_count != 0)
{
move_bugs();
probrain = (double) rand() / 32767.0;
if (probrain < probability_of_rain)
rain();
generation += 1;
}
if (bug_count != 0)
getch();
closegraph();
clrscr();
printf("Max bugs was %d\n",max_bug_count);
temp_bug = bug_list;
a=0;
while (temp_bug != NULL && kbhit() ==0 && bug_count != 0)
{
printf("Age of bug %d reached %d ",a++,temp_bug->age);
if (change_age == 1)
printf("reproduction age reached %d\n",
temp_bug->reproduce_age);
else
printf("\n");
temp_bug = temp_bug->next;
}
if (temp_bug != NULL)
getch();
printf("Number of time units %d\n",generation);
temp_bug = bug_list;
while (temp_bug != NULL)
{
bug_list = temp_bug->next;
free(temp_bug);
temp_bug = bug_list;
}
temp_bug = free_list;
while (temp_bug != NULL)
{
free_list = temp_bug->next;
free(temp_bug);
temp_bug = free_list;
}
}
main(int argc, char *argvþ)
{
int i;
char *ptr;
int running=1;
if ((argc > 1) && (strcmp(argv1þ,"?")==0))
{
printf("\nEVOLVE - an evolution demonstration\n");
printf(" By: Robert Simonoff (S427359 at GBGVM3)\n\n");
printf("Command syntax is: \n");
printf("EVOLVE options\n\n");
printf("Where options can be any of the following, but must\n");
printf("be in the order shown: \n");
printf(" ? ");
printf("Displays this help screen\n");
printf(" /CS=Y ");
printf("Allows shape mutation\n");
printf(" /CA=Y ");
printf("Allows age mutation\n");
printf(" /IB=# ");
printf("Sets initial number of bugs\n");
printf(" /IE=# ");
printf("Sets the initial energy\n");
printf(" /IF=# ");
printf("Sets the number of initial food colonies\n");
printf(" /EM=# ");
printf("Energy required for a move\n");
printf(" /EG=# ");
printf("Energy gained for 1 food colony\n");
printf(" /AR=# ");
printf("Minimum age for reproduction\n");
printf(" /ER=# ");
printf("Energy required for reproduction\n");
printf(" /PR=.######### ");
printf("Probability of rain in a time unit\n");
printf(" /ME=# ");
printf("Maximum amount of energy stored in bug\n");
running = 0;
}
else
{
if (argc > 1)
for (i=1; i<argc; i++)
{
ptr = strtok(argviþ,"=");
if (strcmp(strupr(ptr),"/CS")==0)
{
if (strupr(strtok(NULL,"\n "))0þ == 'N')
change_shape = 0;
}
else if (strcmp(strupr(ptr),"/CA")==0)
{
if (strupr(strtok(NULL,"\n "))0þ == 'N')
change_age = 0;
}
else if (strcmp(strupr(ptr),"/IB")==0)
{
initial_number_of_bugs = atoi(strtok(NULL,"\n "));
}
else if (strcmp(strupr(ptr),"/EM")==0)
{
energy_per_turn = atoi(strtok(NULL,"\n "));
}
else if (strcmp(strupr(ptr),"/IE")==0)
{
initial_energy =atoi(strtok(NULL,"\n "));
}
else if (strcmp(strupr(ptr),"/IF")==0)
{
food_colonies =atol(strtok(NULL,"\n "));
}
else if (strcmp(strupr(ptr),"/EG")==0)
{
energy_for_food_pelet = atoi(strtok(NULL, "\n "));
}
else if (strcmp(strupr(ptr),"/AR")==0)
{
age_for_reproduction = atoi(strtok(NULL, "\n "));
}
else if (strcmp(strupr(ptr),"/ER")==0)
{
energy_to_reproduce = atoi(strtok(NULL, "\n "));
}
else if (strcmp(strupr(ptr),"/PR")==0)
{
probability_of_rain = atof(strtok(NULL, "\n "));
}
else if (strcmp(strupr(ptr),"/ME")==0)
{
maximum_energy = atoi(strtok(NULL, "\n "));
}
}
}
if (running == 1)
evolve();
}