#include #include #include #include #include #include #define COLONYNW 10 #define COLONYNH 10 #define SLNUM 300000 #define INDIVIDUAL '.' #define ELEVEL cnumberw*cnumberh/5 #define ENERGY '#' #define START cnumberw*cnumberh/2 typedef struct { int alive; int generations; int death_age; int energy_needed; int energy; int repro; int move; } cell; void print_colony(cell **colony, int wnumber, int hnumber, char individual) { int i, w; for(i = 0; i < hnumber; i++) { for(w = 0; w < wnumber; w++) printf("%c ", colony[i][w].alive==1 ? individual : (colony[i][w].alive==2 ? ENERGY: ' ')); printf("\n"); } } int reproduce(cell **colony, cell parent1, cell parent2, int h, int w, int th, int tw, char *filename) { int free_c[8][2], i, x, n = 0, z; for(i = -1; i < 2; i++) { for(x = -1, n = 0; x < 2; x++) { if((h+i) < 0 || (h+i) >= th || (w+x) < 0 || (w+x) >= tw) continue; else if(colony[h+i][w+x].alive != 1) { free_c[n][0] = h+i; free_c[n][1] = w+x; n++; } } } if (!n) return; if(n == 1) z = 0; else z = rand()%n; if(parent2.alive) { int ev = rand()%5; colony[free_c[z][0]][free_c[z][1]].energy_needed = (rand()%2?parent1.energy_needed:parent2.energy_needed) + (ev < 2?1:(ev==3?-1:0)); ev = rand()%5; colony[free_c[z][0]][free_c[z][1]].death_age = (rand()%2?parent1.death_age:parent2.death_age) + (ev < 2?-1:(ev==3?1:0)); ev = rand()%5; colony[free_c[z][0]][free_c[z][1]].repro = (rand()%2?parent1.repro:parent2.repro) + (ev < 2?1:(ev==3?-1:0)); colony[free_c[z][0]][free_c[z][1]].energy = 10; ev = rand()%5; colony[free_c[z][0]][free_c[z][1]].move = (rand()%2?parent1.move:parent2.move) + (ev < 2?1:(ev==3?-1:0)); if(colony[free_c[z][0]][free_c[z][1]].alive == 2) colony[free_c[z][0]][free_c[z][1]].energy+=2; if(colony[free_c[z][0]][free_c[z][1]].energy_needed < 0) colony[free_c[z][0]][free_c[z][1]].energy_needed = 0; if(colony[free_c[z][0]][free_c[z][1]].death_age < 0) colony[free_c[z][0]][free_c[z][1]].death_age = 0; if(colony[free_c[z][0]][free_c[z][1]].repro <= 0) colony[free_c[z][0]][free_c[z][1]].repro = 1; if( colony[free_c[z][0]][free_c[z][1]].move <= 0) colony[free_c[z][0]][free_c[z][1]].move = 1; FILE *file = fopen(filename, "a"); fprintf(file, "Coordinates: (%d, %d)\n Life Span: %d\n Energy Requirement: %d\n Reproduction Chance: 1/%d\n Movement Chance: 1/%d\n\n", free_c[z][0], free_c[z][1], colony[free_c[z][0]][free_c[z][1]].death_age, colony[free_c[z][0]][free_c[z][1]].energy_needed, colony[free_c[z][0]][free_c[z][1]].repro, colony[free_c[z][0]][free_c[z][1]].move); fclose(file); return((colony[free_c[z][0]][free_c[z][1]].alive=1)); } else { int ev = rand()%5; colony[free_c[z][0]][free_c[z][1]].energy_needed = parent1.energy_needed + (ev < 2?1:(ev==3?-1:0)); ev = rand()%5; colony[free_c[z][0]][free_c[z][1]].death_age = parent1.death_age + (ev < 2?-1:(ev==3?1:0)); ev = rand()%5; colony[free_c[z][0]][free_c[z][1]].repro = parent1.energy_needed + (ev < 2?1:(ev==3?-1:0)); colony[free_c[z][0]][free_c[z][1]].energy = 10; ev = rand()%5; colony[free_c[z][0]][free_c[z][1]].move = parent1.move + (ev < 2?1:(ev==3?-1:0)); if(colony[free_c[z][0]][free_c[z][1]].alive == 2) colony[free_c[z][0]][free_c[z][1]].energy+=2; if(colony[free_c[z][0]][free_c[z][1]].energy_needed < 0) colony[free_c[z][0]][free_c[z][1]].energy_needed = 0; if(colony[free_c[z][0]][free_c[z][1]].death_age < 0) colony[free_c[z][0]][free_c[z][1]].death_age = 0; if(colony[free_c[z][0]][free_c[z][1]].repro <= 0) colony[free_c[z][0]][free_c[z][1]].repro = 1; if( colony[free_c[z][0]][free_c[z][1]].move <= 0) colony[free_c[z][0]][free_c[z][1]].move = 1; FILE *file = fopen(filename, "a"); fprintf(file, "Coordinates: (%d, %d)\n Life Span: %d\n Energy Requirement: %d\n Reproduction Chance: 1/%d\n Movement Chance: 1/%d\n\n", free_c[z][0], free_c[z][1], colony[free_c[z][0]][free_c[z][1]].death_age, colony[free_c[z][0]][free_c[z][1]].energy_needed, colony[free_c[z][0]][free_c[z][1]].repro, colony[free_c[z][0]][free_c[z][1]].move); fclose(file); return((colony[free_c[z][0]][free_c[z][1]].alive=1)); } } int update_colony(cell **colony, int wnumber, int hnumber, int *hnum, char *filename) { int h, w, tnumber = 0; cell lol = {0, 0, 0, 0, 0, 0}; if(tnumber < wnumber * hnumber) { for(h = 0; h < hnumber; h++) { for(w = 0; w < wnumber && tnumber < wnumber * hnumber; w++) { if(colony[h][w].alive == 1 && colony[h][w].generations && !(rand()%colony[h][w].repro)) { reproduce(colony, colony[h][w],(cell) lol, h, w, hnumber, wnumber, filename); colony[h][w].energy--; } if(colony[h][w].alive == 1 && colony[h][w].generations && !(rand()%colony[h][w].move)) { int free_c[8][2], i, x, n = 0, z; for(i = -1; i < 2; i++) { for(x = -1, n = 0; x < 2; x++) { if((h+i) < 0 || (h+i) >= hnumber || (w+x) < 0 || (w+x) >= wnumber) continue; else { free_c[n][0] = h+i; free_c[n][1] = w+x; n++; } } } if (!n) continue; if(n == 1) z = 0; else z = rand()%n; colony[h][w].energy--; if(colony[free_c[z][0]][free_c[z][1]].alive == 1) reproduce(colony, colony[h][w], colony[free_c[z][0]][free_c[z][1]], h, w, hnumber, wnumber, filename); else { if(colony[free_c[z][0]][free_c[z][1]].alive == 2) colony[h][w].energy+=2; memcpy(&colony[free_c[z][0]][free_c[z][1]], &colony[h][w], sizeof(cell)); memset(&colony[h][w], '\0', sizeof(cell)); } } } } } for(h = 0; h < hnumber; h++) { for(w = 0; w < wnumber; w++){ if((colony[h][w].generations >= colony[h][w].death_age && colony[h][w].alive == 1) || (colony[h][w].generations >= 2 && colony[h][w].alive==2)){ colony[h][w].alive = (colony[h][w].alive == 1)?2:0; colony[h][w].generations = 0; continue; } if(colony[h][w].energy < colony[h][w].energy_needed && colony[h][w].alive == 1) { colony[h][w].alive = 2; colony[h][w].generations = 0; continue; } if(colony[h][w].alive) colony[h][w].generations++; } } for(h = 0; h < hnumber; h++) { for(w = 0; w < wnumber; w++) if(colony[h][w].alive == 1) tnumber++; } if(tnumber > *hnum) *hnum = tnumber; return tnumber; } int main(int argc, char **argv) { int cnumberw = COLONYNW; int cnumberh = COLONYNH; int slnum = SLNUM; char individual = INDIVIDUAL; int c; while((c = getopt(argc, argv, "h:w:c:s:"))!= -1) { switch(c) { case 'h': cnumberh = atoi(optarg); break; case 'w': cnumberw = atoi(optarg); break; case 'c': individual = optarg[0]; break; case 's': slnum = atoi(optarg); } } cell **carray = malloc(cnumberh * sizeof(cell)); int i, cnum, hnum; for(i = 0; i < cnumberw; i++) carray[i] = malloc(cnumberw * sizeof(cell)); struct timeval rtime; gettimeofday(&rtime, 0); srand((unsigned int) rtime.tv_usec); for(i = 0; i < START; i++) { int rw = rand()%cnumberw; int rh = rand()%cnumberh; carray[rh][rw].alive = 1; carray[rh][rw].death_age = 5; carray[rh][rw].energy_needed = 5; carray[rh][rw].energy = 10; carray[rh][rw].repro = 2; carray[rh][rw].move = 4; hnum = i; } for(i = 0; i < ELEVEL; i++) { int x, y; do { y = (rand()%cnumberh); x = (rand()%cnumberw); } while(y < 0 || y == cnumberh || x == cnumberw || x < 0); carray[y][x].alive = 2; } char filename[24]; sprintf(filename, "dump-%d", time(0)); for(i = 0; ; i++) { usleep(slnum); system("clear"); printf("Colony %d by %d; Generation %d; %d Alive; Highest: %d\n", cnumberw, cnumberh, i, cnum, hnum); print_colony(carray, cnumberw, cnumberh, individual); cnum = update_colony(carray, cnumberw, cnumberh, &hnum, filename); if(!cnum) { printf("Entire colony is dead :-(\n"); exit(0); } } }