#include #include #include "gene.h" #ifdef HPUX #include #include void catch_alarm() {}; usleep(usec) unsigned long usec; { struct itimerval val, oval; signal(SIGALRM,catch_alarm); val.it_value.tv_sec = 0; val.it_value.tv_usec = usec; val.it_interval.tv_sec = 0; val.it_interval.tv_usec = 0; setitimer(ITIMER_REAL,&val,&oval); sigpause(0L); } #endif #ifdef SGI usleep(usec) unsigned long usec; { sginap(usec/10000); } #endif unsigned char Wall = 0; unsigned char NoDiverse = 0; unsigned char MessageStdout = 0; unsigned char ViscaOn = 0; unsigned char NoWindow = 0; unsigned char FullScreen = 0; float MutationRate = 0.5; int ICellSize = 20; int InitialPopSize = 80; int LifeSpan = 50; int SeedEnergy = 7; int SeedForRandom = 0; char *Geometry = "800x800"; char *DisplayName = NULL; char *FontName = /* "-b&h-*-bold-r-*-24-*" */ "variable"; char *DataFileName = "P2_dump"; char *LogFileName = NULL; char *ReplayFileName = NULL; int WorldWidth, WorldHeight; double CellSize; unsigned long Step, Generation, PopSize; double drand48(); long lrand48(); struct optb_rec { char *str, *help; unsigned char *flag; } options_b[] = { {"-wall", "Prevent splitting beyond wall", &Wall}, {"-nodiverse", "Prevent splitting of diversed individuals",&NoDiverse}, {"-stdout", "Display messages to standard output device", &MessageStdout}, {"-fullscreen", "Full screen mode", &FullScreen}, {"-visca", "Enable VISCA control", &ViscaOn}, {"-nowin", "Without graphics", &NoWindow}, { NULL, NULL, NULL } }; struct opti_rec { char *str, *help; int *var; } options_i[] = { {"-size", "Size of cell", &ICellSize}, {"-initps", "Initail Population Size", &InitialPopSize}, {"-lspan", "Life Span", &LifeSpan}, {"-seed", "Number of cells per seed", &SeedEnergy}, {"-srand", "Seed for random numbers", &SeedForRandom}, { NULL, NULL, NULL } }; struct optf_rec { char *str, *help; float *var; } options_f[] = { {"-mut", "Mutation rate for each individual", &MutationRate}, { NULL, NULL, NULL } }; struct opts_rec { char *str, *help, **var; } options_s[] = { {"-geom", "\tGeometry of the world", &Geometry}, {"-data", " Data file name", &DataFileName}, {"-log", " Logging file name",&LogFileName}, {"-replay", " Logging file name",&ReplayFileName}, {"-fn", " Font name", &FontName}, {"-disp", " Display name", &DisplayName}, { NULL, NULL, NULL } }; arg_error(cn,option) char *cn, *option; { union { struct optb_rec *b; struct opti_rec *i; struct optf_rec *f; struct opts_rec *s; } p; fprintf(stderr,"%s: illegal option %s.\noptions:\n",cn,option); for (p.i = options_i; p.i->str; p.i++) fprintf(stderr,"%s%s%s. (default %d)\n",p.i->str, ((strlen(p.i->str)<5)?"\t\t":"\t"),p.i->help,*(p.i->var)); for (p.f = options_f; p.f->str; p.f++) fprintf(stderr,"%s%s%s. (default %g)\n",p.f->str, ((strlen(p.f->str)<5)?"\t\t":"\t"),p.f->help,*(p.f->var)); for (p.s = options_s; p.s->str; p.s++) fprintf(stderr,"%s %s. (default %s)\n",p.s->str,p.s->help, ((*(p.s->var))?*(p.s->var):"NULL")); for (p.b = options_b; p.b->str; p.b++) fprintf(stderr,"%s%s%s.\n",p.b->str, ((strlen(p.b->str)<8)?"\t\t":"\t"),p.b->help); exit(1); } int margc; char **margv; main(argc, argv) int argc; char **argv; { int i; union { struct optb_rec *b; struct opti_rec *i; struct optf_rec *f; struct opts_rec *s; } p; margc = argc; margv = argv; for (i = 1; i < argc; i++) { for (p.b = options_b; p.b->str; p.b ++) if (!strcmp(argv[i],p.b->str)) { *(p.b->flag) = 1; goto nextop; } for (p.i = options_i; p.i->str; p.i ++) if (!strncmp(argv[i],p.i->str,strlen(p.i->str))) { *(p.i->var) = atoi(argv[i]+strlen(p.i->str)); goto nextop; } for (p.f = options_f; p.f->str; p.f ++) if (!strncmp(argv[i],p.f->str,strlen(p.f->str))) { *(p.f->var) = atof(argv[i]+strlen(p.f->str)); goto nextop; } if (!p.i->str && i < argc-1) for (p.s = options_s; p.s->str; p.s++) if (!strncmp(argv[i],p.s->str,strlen(p.s->str))) { *(p.s->var) = argv[++i]; goto nextop; } if (!p.s->str && !strcmp(argv[i],"-stdout")) MessageStdout = 1; else arg_error(argv[0],argv[i]); nextop: continue; } CellSize = ICellSize * 0.0001; parse_geom(Geometry); if (SeedForRandom == 0) SeedForRandom = time(0); mem_init(); if (NoWindow) { MessageStdout = 1; ViscaOn = 0; } else gr_init(argc,argv); data_init(); world_return(); if (ViscaOn) video_init(); if (NoWindow) command_loop(); else event_loop(); } static void c_run(com) char *com; { int i, n = atoi(com); if (n < 1) n = 1; for (i = 0; i < n; i ++) exec_step(); } static void c_reset(com) char *com; { world_reset(); } static void c_quit(com) char *com; { world_close(); } static struct com_rec { char *str, *help; void (*proc)(); } command[] = { {"run", " \tExecute cycle", c_run}, {"reset", "\tReset the world", c_reset}, {"quit", "\tQuit this program", c_quit}, {NULL, NULL, 0} }; command_loop() { char com[BUFSIZ]; struct com_rec *coms; while (fgets(com, BUFSIZ, stdin)) { for (coms = command; coms->str; coms ++) if (!strncmp(coms->str, com, strlen(coms->str))) { (*coms->proc)(com+strlen(coms->str)); break; } if (!coms->str) { fprintf(stderr,"\"%s\" is illegal command. Available commands are:\n", com); for (coms = command; coms->str; coms ++) fprintf(stderr," %s%s.\n", coms->str, coms->help); } } } static void world_reset0() { int i, j; individual *p, *alloc_ind(); if (!NoWindow) clear_world(); mem_reset(); for (i = 0; i < InitialPopSize; i ++) { p = alloc_ind(i); for (j = 0; j < GeneLen; j ++) p->gene[j] = lrand48() & 0xffff; if (InitialPopSize > 1) while (!new_cell(drand48(), drand48(), lrand48() & 0xff, 0, p)); else new_cell(0.5, 0.5, lrand48() & 0xff, 0, p); } Generation = Step = 0; } world_reset() { srand48(SeedForRandom = lrand48()); world_reset0(); } world_return() { srand48(SeedForRandom); world_reset0(); } world_close() { if (ViscaOn) video_close(); exit(0); } exec_step() { individual *p; extern individual *Individuals; void cell_step(); if ((++ Step) > LifeSpan) next_generation(); else { for (p = Individuals; p; p = p->next) p->growing = 0; for_all_active_cells(cell_step); } draw_info(); if (ViscaOn) video_rec_frame(1); } mutation(gs,gd) unsigned short *gs, *gd; { int i; bcopy(gs,gd,GeneLen*sizeof(short)); if (MutationRate == 0) return; if (drand48() < MutationRate) { i = lrand48() % (GeneLen * sizeof(Gene)); gd[i/sizeof(Gene)] ^= 1<<(i%sizeof(Gene)); } } static void check_seed1(c) cell *c; { if (c->state==0x0f && !(NoDiverse && c->ind->growing)) c->ind->nseeds ++; else kill_cell(c); } static void check_seed2(c) cell *c; { individual *old, *new, *alloc_ind(); old = c->ind; if (old->size / old->nseeds > SeedEnergy) { c->state = 0; activate_cell(c); new = alloc_ind(old->root_id); mutation(old->gene,new->gene); c->ind = new; draw_cell(c); } else kill_cell(c); } next_generation() { individual *p, *old; extern individual *Individuals, *FreeInd; short_sleep(); old = Individuals; Individuals = NULL; PopSize = 0; for (p = old; p; p = p->next) p->nseeds = 0; for_all_cells(check_seed1); for_all_cells(check_seed2); if (old) { for (p = old; p->next; p = p->next); p->next = FreeInd; FreeInd = old; } Step = 0; Generation ++; short_sleep(); } short_sleep() { if (!NoWindow) { draw_info(); usleep(50000); }}