]> pd.if.org Git - afpopgen/blob - sim/sim.c
initial commit
[afpopgen] / sim / sim.c
1 #define _POSIX_C_SOURCE 200112L
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <time.h>
6 #include <errno.h>
7 #include <unistd.h>
8
9 #include "africa.h"
10 #include "variate.h"
11 #include "hexagon.h"
12 void dumpgenjson(struct afrhex *map, int gen, int year);
13 void hexlistjson(struct afrhex *map);
14
15 static void setpop(struct afrhex *map, int hexid, int *pop) {
16         struct afrhex *hex;
17         int i;
18
19         hex = find_hex(map, hexid);
20         for (i=0; i < 2; i++) {
21                 hex->freq[i] = pop[i];
22         }
23 }
24
25 static void setpopstr(struct afrhex *map, char *spec) {
26         char *resume;
27         char *start;
28         long hex;
29         int freq[2];
30         int i;
31
32         errno = 0;
33         hex = strtol(spec, &resume, 10);
34         if (errno) goto error; 
35
36         for (i = 0; i < 2; i++) {
37                 if (*resume != ':' && *resume != ',') goto error;
38                 start = resume+1; /* skip the colon or comma */
39                 errno = 0;
40                 freq[i] = strtol(start, &resume, 10);
41                 if (errno) goto error;
42         }
43         setpop(map, hex, freq);
44         return;
45
46 error:
47         fprintf(stderr, "unable to parse popspec '%s'\n", spec);
48         fprintf(stderr, "format is hex:freq,freq\n");
49         exit(EXIT_FAILURE);
50 }
51
52 int main (int ac, char *av[]) {
53         struct afrhex *map;
54         struct afrhex *hex;
55         int gen = 0;
56         int opt;
57         struct timespec ts;
58         /* defaults below */
59         int year = -140000;
60         unsigned int seed = 0;
61         int run = 1;
62         int eemian = 0;
63         int holocene = 0;
64         int defaultpop = 1;
65         int gens = 1000;
66         double capfactor = 0.25;
67         char tag[16] = "";
68
69         map = map_init(maphexes, 100.0, capfactor);
70
71         clock_gettime(CLOCK_REALTIME, &ts);
72         seed = ((unsigned long)(ts.tv_sec) ^ (unsigned long)ts.tv_nsec) & 0xffffffff;
73
74         while ((opt = getopt(ac, av, "r:s:ehp:y:g:m:t:d:")) != -1) {
75                 switch (opt) {
76                         case 's': seed = atoi(optarg); break;
77                         case 'r': run = atoi(optarg); break;
78                         case 'y': year = atoi(optarg); break;
79                         case 'g': gens = atoi(optarg); break;
80                         case 'm': capfactor = strtod(optarg, 0); climate_init(100.0, capfactor); break;
81                         case 't': strcpy(tag, optarg);
82                         case 'e': eemian = 1; break;
83                         case 'h': holocene = 1; break;
84                         case 'p': setpopstr(map, optarg); defaultpop = 0;break;
85                         default:
86                                   fprintf(stderr, "Usage: %s [-s seed] [-r run] [-y startyear] [-eh] [-p hex:freq,freq[:freq,freq...]\n",
87                                                   av[0]);
88                                   exit(EXIT_FAILURE);
89                                   break;
90                 }
91         }
92
93         var_init(seed);
94         
95         if (defaultpop) {
96                 hex = find_hex(map, 4788);
97                 hex->freq[0] = hex->freq[1] = 2000;
98                 hex->pop = hex->freq[0] + hex->freq[1];
99         }
100
101 #if 0
102         r = var_rhyper(1, 5, 5);
103         printf("rhg = %u\n", r);
104 #endif
105
106         /* dump out the coordinates of the hexes */
107 #if 0
108         printf("map init complete (%p)\n", map);
109         double hexvert[14];
110         int i;
111         printf("{\n");
112         for (hex = map; hex; hex = hex->next) {
113                 HL_vertices(hex->hex, hexvert);
114                 printf("\t{ \"hex\": %lld, \"coords\": [", hex->hex);
115                 for (i=0; i<5; i++) {
116                         printf("%f,%f, ", hexvert[i*2], hexvert[i*2+1]);
117                 }
118                 printf("%f,%f", hexvert[5*2], hexvert[5*2+1]);
119                 printf("] }\n");
120         }
121 #endif
122
123
124         printf("{");
125         printf(" \"run\": %d, \"seed\": %d, \"gens\": %d", run, seed, gens);
126         printf(",\n\"gendata\": [\n");
127
128         dumpgenjson(map, 0, year);
129
130         for (gen = 1; gen <= gens; gen++) {
131                 year += 25;
132                 nextgen(map, year, holocene + eemian > 0);
133                 printf(",\n");
134                 dumpgenjson(map, gen, year);
135         }
136         printf("\n]");
137
138         printf(",\n\"hexlist\": ");
139         hexlistjson(map);
140
141         printf("\n}\n");
142
143         return 0;
144 }
145
146 void dumpgenjson(struct afrhex *map, int gen, int year) {
147         struct afrhex *hex;
148         int count = 0;
149         unsigned int maxpop = 0;
150
151         printf("{ \"gen\": %d, \"year\": %d, \"pop\": %llu, \"hexes\": [\n",
152                         gen, year, total_pop(map)
153               );
154         for (hex = map; hex; hex = hex->next) {
155                 if (hex->pop == 0) continue;
156                 if (hex->pop > maxpop) {
157                         maxpop = hex->pop;
158                 }
159                 count++;
160                 printf("%s\t{ \"hex\": %lld, \"pop\": %u, \"freq\": [%u, %u], "
161                                 "\"climate\": \"%s\", \"cap\": %u, \"outpop\": [%u, %u], "
162                                 "\"inpop\": [%u, %u]"
163                                 " }",
164                                 count > 1 ? ",\n" : "",
165                                 hex->hex, hex->pop, hex->freq[0], hex->freq[1],
166                                 hex->climate->code, hex->climate->cap, 
167                                 hex->outmigrate[0], hex->outmigrate[1],
168                                 hex->inmigrate[0], hex->inmigrate[1]
169                       );
170         }
171         printf(" ],\n\t\"maxpop\": %u}", maxpop);
172 }
173
174 void hexlistjson(struct afrhex *map) {
175         struct afrhex *hex;
176         int count = 0;
177
178         printf("[");
179         for (hex = map; hex; hex = hex->next) {
180                 printf("%s%s%lld",
181                                 count > 0 ? "," : "",
182                                 count % 10 == 0 ? "\n" : "",
183                                 hex->hex
184                       );
185                 count++;
186         }
187         printf("]");
188 }
189
190