#define _POSIX_C_SOURCE 200112L #include #include #include #include #include #include #include "africa.h" #include "variate.h" #include "hexagon.h" void dumpgenjson(struct afrhex *map, int gen, int year); void hexlistjson(struct afrhex *map); static void setpop(struct afrhex *map, int hexid, int *pop) { struct afrhex *hex; int i; int sum = 0; hex = find_hex(map, hexid); for (i=0; i < 2; i++) { hex->freq[i] = pop[i]; sum += pop[i]; } if (sum % 2) { fprintf(stderr, "allele frequency for hex %d not even\n", hexid); } hex->pop = sum/2; } static void setpopstr(struct afrhex *map, char *spec) { char *resume; char *start; long hex; int freq[2]; int i; errno = 0; hex = strtol(spec, &resume, 10); if (errno) goto error; for (i = 0; i < 2; i++) { if (*resume != ':' && *resume != ',') goto error; start = resume+1; /* skip the colon or comma */ errno = 0; freq[i] = strtol(start, &resume, 10); if (errno) goto error; } setpop(map, hex, freq); return; error: fprintf(stderr, "unable to parse popspec '%s'\n", spec); fprintf(stderr, "format is hex:freq,freq\n"); exit(EXIT_FAILURE); } int main (int ac, char *av[]) { struct afrhex *map; struct afrhex *hex; int gen = 0; int opt; struct timespec ts; /* defaults below */ int year = -140000; unsigned int seed = 0; int run = 1; int eemian = 0; int holocene = 0; int defaultpop = 1; int gens = 1000; double capfactor = 0.25; char tag[16] = ""; map = map_init(maphexes, 100.0, capfactor); clock_gettime(CLOCK_REALTIME, &ts); seed = ((unsigned long)(ts.tv_sec) ^ (unsigned long)ts.tv_nsec) & 0xffffffff; while ((opt = getopt(ac, av, "f:r:s:ehp:y:g:m:t:d:")) != -1) { switch (opt) { case 's': seed = atoi(optarg); break; case 'r': run = atoi(optarg); break; case 'y': year = atoi(optarg); break; case 'g': gens = atoi(optarg); break; case 'm': capfactor = strtod(optarg, 0); climate_init(100.0, capfactor); break; case 't': strcpy(tag, optarg); case 'e': eemian = 1; break; case 'h': holocene = 1; break; case 'p': setpopstr(map, optarg); defaultpop = 0;break; case 'f': if (freopen(optarg, "w", stdout) == NULL) { perror("sim"); exit(EXIT_FAILURE); } break; default: fprintf(stderr, "Usage: %s [-s seed] [-r run] [-y startyear] [-eh] [-p hex:freq,freq[:freq,freq...]\n", av[0]); exit(EXIT_FAILURE); break; } } var_init(seed); if (defaultpop) { hex = find_hex(map, 4788); hex->freq[0] = hex->freq[1] = 2000; hex->pop = hex->freq[0] + hex->freq[1]; } #if 0 r = var_rhyper(1, 5, 5); printf("rhg = %u\n", r); #endif /* dump out the coordinates of the hexes */ #if 0 printf("map init complete (%p)\n", map); double hexvert[14]; int i; printf("{\n"); for (hex = map; hex; hex = hex->next) { HL_vertices(hex->hex, hexvert); printf("\t{ \"hex\": %lld, \"coords\": [", hex->hex); for (i=0; i<5; i++) { printf("%f,%f, ", hexvert[i*2], hexvert[i*2+1]); } printf("%f,%f", hexvert[5*2], hexvert[5*2+1]); printf("] }\n"); } #endif printf("{"); printf(" \"run\": %d, \"seed\": %d, \"gens\": %d", run, seed, gens); printf(",\n\"options\": { \"capfactor\": %g }", capfactor); printf(",\n\"gendata\": [\n"); dumpgenjson(map, 0, year); for (gen = 1; gen <= gens; gen++) { year += 25; nextgen(map, year, holocene + eemian > 0); printf(",\n"); dumpgenjson(map, gen, year); } printf("\n]"); printf(",\n\"hexlist\": "); hexlistjson(map); printf("\n}\n"); return 0; } void dumpgenjson(struct afrhex *map, int gen, int year) { struct afrhex *hex; int count = 0; unsigned int maxpop = 0; printf("{ \"gen\": %d, \"year\": %d, \"pop\": %llu, \"hexes\": [\n", gen, year, total_pop(map) ); for (hex = map; hex; hex = hex->next) { if (hex->pop == 0) continue; if (hex->pop > maxpop) { maxpop = hex->pop; } count++; printf("%s\t{ \"hex\": %lld, \"pop\": %u, \"freq\": [%u, %u], " "\"climate\": \"%s\", \"cap\": %u, \"outpop\": [%u, %u], " "\"inpop\": [%u, %u]" " }", count > 1 ? ",\n" : "", hex->hex, hex->pop, hex->freq[0], hex->freq[1], hex->climate->code, hex->climate->cap, hex->outmigrate[0], hex->outmigrate[1], hex->inmigrate[0], hex->inmigrate[1] ); } printf(" ],\n\t\"maxpop\": %u}", maxpop); } void hexlistjson(struct afrhex *map) { struct afrhex *hex; int count = 0; printf("["); for (hex = map; hex; hex = hex->next) { printf("%s%s%lld", count > 0 ? "," : "", count % 10 == 0 ? "\n" : "", hex->hex ); count++; } printf("]"); }