summaryrefslogtreecommitdiffstats
path: root/zpu/roadshow/roadshow/games/sumeria.c
blob: 7171adf986164143a700a890f4799701955b64a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
/*    Govern ancient Sumeria.    Heavily modified by Mike Arnautov 1975.
 *    Converted from Basic to PR1ME Fortran (mode 32R) MLA 1979.
 *    Rev.19.1, GGR version 14 Oct 83. MLA
 *    Converted to ANSI C December 2001. MLA
 */

#include <stdio.h>
#include <time.h>
#include <math.h>

int year_term;
int year_abs;
int percent_starved;
int dead_total;
int starved;
int population;

char reply [160];

void try_again (int reason)
{
   if (reason == 1)
      puts ("For the extreme folly of soft - heartedness and");
   if (reason)
   {
      printf ("%considering ", reason == 3 ? 'C' : 'c');
      puts ("the mess you would leave the city in,");
      puts ("you are hereby commanded to remain in office for");
      puts ("another ten years. May your fate be a lesson and");
      puts ("a warning for generations to come.");
   }
   else
   {
      puts ("Hamurabe, you are either a politico-economic genius");
      puts ("or just a lucky bastard. There being but one way to");
      puts ("settle the question, you are hereby requested to stay");
      puts ("in office for another ten years.");
   }
   year_term = 0;
   year_abs--;
   percent_starved = starved * 100.0 / population;
   dead_total = starved;
}

float rnd (void)
{
   return ((rand () % 1000) / 1000.0);
}

int iabs (int value)
{
   return ((value >= 0) ? value : -value);
}

void terminate (int abort)
{
   if (abort == 2)
   {
      puts ("For this extreme mismanagement you have been");
      puts ("deposed, flayed alive and publicly beheaded.");
      puts ("\nMay Ashtaroth preserve your Ka.\n");
   }
   else if (abort == 1)
   {
      puts ("\nHamurabe:  I find myself unable to fulfil your wish.");
      puts ("You will have to find yourself another kingdom.");
   }
   if (abort != 2)
      puts ("\nMay Baal be with you.\n");
   exit (0);
}
   
void think_again (char *what, int quantity)
{
   if (*what == 'l' || *what == 'g')
      printf ("Hamurabe, think again. ");
   if (*what == 'l')
      printf ("You own %d acres of land.", quantity);
   else if (*what == 'g')
      printf ("You have only %d bushels of grain.", quantity);
   else
      printf ("But you only have %d people to tend the fields.", population);
   puts (" Now then,");
}
int query (char *prompt)
{
   while (1)
   {
      int sign;
      int value;
      char * cptr;
      
      printf (prompt);
      fgets (reply, sizeof (reply) - 1, stdin);
      value = 0;
      sign = 1;
      cptr = reply;
      while (*cptr == ' ' || *cptr == '\t') cptr++;
      if (*cptr == '-')
      {
         cptr++;
         sign = -1;
      }
      if (*cptr == 'q' || *cptr == 'Q')
         terminate (1);
      while (*cptr && *cptr != '\n')
      {
         if (*cptr >= '0' && *cptr <= '9')
            value = 10 * value + *cptr - '0';
         else if (*cptr == '.')
            break;
         else if (*cptr != '.')
         {
            sign = 0;
            break;
         }
         cptr++;
      }
      if (sign)
         return (sign * value);
      puts ("Hamurabe, your command has not been understood!");
   }   
}

int main ()
{
   int acreage;
   int immigration;
   int second_term;
   int dead_total;
   int stores;
   int harvest;
   int rat_food;
   int yield;
   int rounded_price;
   int sell;
   int buy;
   int plant;
   int food;
   int transaction;
   int rats;
   int plague_deaths;
   int survived;
   int dead_rats;
   int tmp_int;

   float price;
   float breadline;
   float provisions;
   float plague;
   float acres_per_head;
   float acres_per_init;
   float stores_per_head;
   float rats_ate;
   float rat_log;
   float percent_starved;
   float tmp_float;
   
   printf ("[Sumeria (Primos) rev.19.1, GGR (MLA) version 14 Oct 83]\n");
   puts ("[Conversion to ANSI C: MLA, Feb 2002]\n");
   while (1)
   {
      printf ("Do you know how to play? ");
      fgets (reply, sizeof(reply) - 1, stdin);
      if (*reply == '\n') break;
      *reply += (*reply < 'a') ? 'a' - 'A' : 0;
      if (*reply == 'y') break;
      if (*reply != 'n' && *reply != 'q') continue;
      puts ("\nToo bad!\n");
      break;
   }
  
   srand (time (NULL));
   *(reply + sizeof (reply) - 1) = '\0';
   
   puts ("Try your hand at governing ancient Sumeria");
   puts ("for a ten year term of office.");

   second_term = 0;
   dead_total = 0;
   percent_starved = 0;
   year_term = 0;
   year_abs = 0;
   acres_per_init = 10;
   population = 100;
   stores = 2800;
   harvest = 3000;
   rat_food = 200;
   yield = 3;
   acreage = 1000;
   immigration = 5;
   transaction = 0;
   price = 18 + 6 * rnd ();
   breadline = 19 + 4 * rnd ();
   provisions = breadline;
   rats = 1000;
   rat_log = 3;
   plague = rnd () / 2;
   starved = 0;

year_term = year_abs = 9;
   while (1)
   {
      
      while (1)
      {
         year_term++;
         year_abs++;
         putchar ('\n');
         acres_per_head = ((float) acreage) / population;
         stores_per_head = ((float) stores) /population;
         puts ("Hamurabe: I beg to report to you,");
         printf ("In year %d, ", year_abs);
         if (starved > 0)
            printf ("%ld", starved);
         else
            printf ("no");
         printf (" %s starved, %ld came to the city.\n", 
            starved <= 1 ? "person" : "people", immigration);
         if (plague >= 0.85)
            printf ("A horrible plague struck! %d people died.\n", 
               plague_deaths);
         printf ("Population is now %ld.\n", population);
         printf ("The city owns %ld acres.\n", acreage);
         printf ("You harvested %ld bushels per acre.\n", yield);
         printf ("Rats ate %ld bushels.\n", rat_food);
         printf ("You now have %ld bushels in store.\n\n", stores);

         if (year_term == 11) 
            break;
         rounded_price = price + 0.5;
         printf ("Land is trading at %ld bushels per acre.\n\n", rounded_price);

         while (1)
         {
            buy = query ("How many acres do you wish to buy? ");
            if (rounded_price * buy <= stores)
               break;
            think_again ("grain", stores);
         }
         if (buy > 0)
         {
            acreage += + buy;
            stores -= rounded_price * buy;
            transaction = buy;
         }
         else
         {
            while (1)
            {
               sell = query ("How many acres do you wish to sell? ");
               if (sell <= acreage)
                  break;
               think_again ("land", acreage);
            }
            acreage -= sell;
            stores += rounded_price * sell;
            transaction = -sell;
         }
      
         putchar ('\n');
         while (1)
         {
            food = query ("How many bushels do you wish to feed your people? ");
            if (food <= stores)
               break;
            think_again ("grain", stores);
         }
         stores -= food;
         putchar ('\n');
         while (1)
         {
            plant = query ("How many acres do you wish to plant with seed? ");
            if (plant <= acreage && plant <= 2 * stores && 
                plant <= 10 * population)
               break;
            if (plant > acreage)
               think_again ("land", acreage);
            else if (plant > 2 * stores)
               think_again ("grain", stores);
            else
               think_again ("people", population);
         }
   
         stores -= plant / 2;
         yield = 4 * rnd() + 1.65;
         harvest = plant * yield;
         rat_food = 0;
         rats_ate = stores * (rat_log - 2.2) / 3.6;
         dead_rats = rats - 4 * rats_ate;
         rats = 3 * rats;
         if (dead_rats > 0) rats = rats - dead_rats;
   
         if (plague >= 0.3) 
         {
            if (plague >= 0.85)
            {
               if (plague > 1) plague = 1;
               rats = 500 + 5000 * (plague - 0.7);
            }
            else
               rats *= 1.225 - 0.75 * plague;
         }
   
         if (rats < 500)
            rats = 500;
         rat_food = rats / 4;
         if (rats_ate < rat_food)
            rat_food = rats_ate;
         rat_food *= 7;
         if (rat_food <= 20) 
            rat_food = 20 + 30 * rnd();
         stores += harvest - rat_food;
         rat_log = log10 (1.0 * rats);
         if (stores + stores <= harvest)
         {
            rat_food = harvest * (1 + rnd()) / 4.0;
            stores = harvest - rat_food;
         }
   
         tmp_int = 100 + iabs (100 - population);
         immigration = tmp_int * ((acres_per_head + 
            stores_per_head - 36) / 250.0 + 
               (provisions - breadline + 2.5) / 40) + .5;
         if (immigration <= 0) 
            immigration = 5 * rnd() + 1;
         survived = food / breadline;
         provisions = (1.0 * food) / population;
         plague = (2 * rnd() + rat_log - 3) / 3.0;
         if (population < survived) 
            survived = population;
         else
         {
            starved = population - survived;
            if (starved >= 0.45 * population)
            {
               printf ("\nYou starved %d people in one year!\n", starved);
               terminate (2);
            }
            percent_starved = ((year_term - 1) * percent_starved + 
               100.0 * starved / population) / year_term;
            population = survived;
            dead_total += starved;
         }
         population += immigration;
         price = (price + 15 + (stores_per_head - acres_per_head) / 3) / 2 + 
            transaction / 50 + 3 * rnd() - 2;
         if (price <1.0) price = 1.0;
         if (plague >= 0.85)
         {
            plague_deaths = population * (0.429 * plague - 0.164);
            population -= plague_deaths;
         }
      }
   
      printf ("In your ten year term of office %d people starved.\n",
         dead_total);
      printf ("You started with %0.2f acres per person and ended\n",
         acres_per_init);
      acres_per_head = (1.0 * acreage) / population;
      acres_per_init = acres_per_head;
      printf ("with %0.2f acres per person.\n\n", acres_per_head);
   
      tmp_float = 10 * acres_per_head / 3;
      if (percent_starved > 25)
         terminate (2);
      if (percent_starved <= 7)
      {
         try_again (1);
         continue;
      }
      if (tmp_float < 7) 
         terminate (2);
      if (tmp_float > 10)
      {
         puts ("Your heavy handed performance smacks of Nabuchodonoser");
         puts ("and Asurbanipal II. The surviving populace hates your");
         puts ("guts and your eventual assasination is just a matter of");
         puts ("time.");
         terminate (0);
      }
      puts ("Consequently you have been deposed and disgraced");
      puts ("and only avoided a public punishment because");
      puts ("of mitigating circumstances. While it may be");
      puts ("admitted in private that you had a rotten deal");
      tmp_int = 3 * rnd();
      if (tmp_int == 0)
         puts ("try explaining that to a mob looking for scape-goats.");
      if (tmp_int == 1)
         puts ("history is not interested in such petty excuses.");
      if (tmp_int == 2)
      {
         puts ("you should have considered such occupational hazards");
         puts ("before applying for the job.");
      }
      terminate (0);
      
      if (acres_per_head < 7)
      {
         try_again (1);
         continue;
      }
      if (acres_per_head < 9)
      {
         puts ("Your performance has been satisfactory and, in the");
         puts ("perspective of history, actually quite good.");
         if (rnd() >= 0.5) 
         {
            puts ("You may not be exactly popular, but given a good");
            puts ("body-guard there is nothing to be really worried about.");
         }
         else
         {
            puts ("While not exactly loved, you are at least respected.");
            puts ("What more can a realistic ruler ask for?");
         }
      }
      else if (second_term == 0)

      if (second_term == 0)
      {
         if (stores <= 10 * population)
         {
            try_again (3);
            continue;
         }
         second_term = 1;
         try_again (0);
         continue;
      }
      else
      {
         puts ("Hamurabe, your name will be remembered through the");
         puts ("ages to come with admiration and respect.\n");
         puts ("(So you did get away with it you lucky sod!)");
      }
      if (stores > 10 * population)
         terminate (0);
      puts ("\n                            HOWEVER\n\n");
      second_term = 0;
      try_again (2);
      continue;
   }
}
OpenPOWER on IntegriCloud