Advertisement
Guest User

Daily Programmer Halloween Intermediate Challenge

a guest
Oct 31st, 2014
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.04 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. #define _DIR(i)  ((i) >= 0 && (i) <= 2 ? \
  6.                     (i) - 21 : \
  7.                     (i) == 3 || (i) == 4 ? \
  8.                     ((i) - 3) * 2 - 1 : \
  9.                     (i) >= 5 && (i) <= 7 ? \
  10.                     (i) + 14 : \
  11.                     -1000000)
  12. #define DIR(x) (i + _DIR(x))
  13. #define D deck[d]
  14. #define DIM 20
  15. #define SQDIM 400
  16.  
  17. int x, y, z, xinit, yinit, zinit;
  18. int stumble, flee, seek;
  19. int singlekill, doublekill, killtotal;
  20. int zombvictim, zombhunter, zombtotal;
  21. int ticks = 1000;
  22.  
  23. void shuffle(int *a, int sz)
  24. {
  25.     int i, j, r, temp;;
  26.     for (i = 0; i < sz; ++i) {
  27.         j = i + rand() % (sz - i);
  28.         temp = a[i];
  29.         a[i] = a[j];
  30.         a[j] = temp;
  31.     }
  32. }
  33.  
  34. void sim(char *field, int *deck, int t)
  35. {
  36.     stumble = flee = seek = 0;
  37.     singlekill = doublekill = killtotal = 0;
  38.     zombvictim = zombhunter = zombtotal = 0;
  39.  
  40.     int i, tick, d, dird, moveconv, movedir, actions;
  41.     int adjacents[4] = {1, 3, 4, 6};
  42.     for (tick = 0; tick < t; ++tick)
  43.         for (i = 0; i < SQDIM; ++i) {
  44.             shuffle(deck, 8);
  45.             actions = 2;
  46.             switch(field[i]) {
  47.                 case 'Z':
  48.                     for (d = 1; d < 8 && actions > 0; d += 2) {
  49.                         dird = DIR(D);
  50.                         if (dird < 0 || dird >= SQDIM)
  51.                             continue;
  52.                         switch( field[dird] ) {
  53.                             case 'V':
  54.                                 field[dird] = 'Z';
  55.                                 zombvictim++;
  56.                                 y--;
  57.                                 x++;
  58.                                 zombtotal++;
  59.                                 actions -= 2;
  60.                                 break;
  61.                             case 'H':
  62.                                 field[dird] = 'Z';
  63.                                 zombhunter++;
  64.                                 z--;
  65.                                 x++;
  66.                                 zombtotal++;
  67.                                 actions -= 2;
  68.                                 break;
  69.                             default:
  70.                                 break;
  71.                         }
  72.                     }
  73.                     if (!actions)
  74.                         break;
  75.                     moveconv = rand() % 4;
  76.                     movedir = DIR(adjacents[moveconv]);
  77.                     while (movedir < 0 || movedir >= SQDIM) {
  78.                         moveconv = (moveconv + 1) % 4;
  79.                         movedir = DIR(adjacents[moveconv]);
  80.                     }
  81.                     if(!field[movedir]) {
  82.                         stumble++;
  83.                         field[movedir] = 'Z';
  84.                         field[i] = 0;
  85.                     }
  86.                     break;
  87.                 case 'V':
  88.                     for (d = 0; d < 8 && actions > 0; ++d) {
  89.                         dird = DIR(D);
  90.                         if (dird < 0 || dird >= SQDIM)
  91.                             continue;
  92.                         if (field[dird] == 'Z') {
  93.                             moveconv = rand() % 8;
  94.                             movedir = DIR(moveconv);
  95.                             while (movedir < 0 ||
  96.                                     movedir >= SQDIM) {
  97.                                 moveconv = (moveconv + 1) % 8;
  98.                                 movedir = DIR(moveconv);
  99.                             }
  100.                             if (!field[movedir]) {
  101.                                 flee++;
  102.                                 field[movedir] = 'V';
  103.                                 field[i] = 0;
  104.                             }
  105.                             actions -= 2;
  106.                         }
  107.                     }
  108.                     break;
  109.                 case 'H':
  110.                     for (d = 0; d < 8 && actions > 0; ++d) {
  111.                         dird = DIR(D);
  112.                         if (dird < 0 || dird >= SQDIM)
  113.                             continue;
  114.                         if (field[dird] == 'Z') {
  115.                             if (actions == 1) {
  116.                                 singlekill--;
  117.                                 doublekill++;
  118.                             } else { singlekill++; }
  119.                             field[dird] = 0;
  120.                             x--;
  121.                             killtotal++;
  122.                             actions--;
  123.                         }
  124.                     }
  125.                     if (actions < 2)
  126.                         break;
  127.                     moveconv = rand() % 8;
  128.                     movedir = DIR(moveconv);
  129.                     while (movedir < 0 ||
  130.                             movedir >= SQDIM) {
  131.                         moveconv = (moveconv + 1) % 8;
  132.                         movedir = DIR(moveconv);
  133.                     }
  134.                     if(!field[movedir]) {
  135.                         seek++;
  136.                         field[movedir] = 'H';
  137.                         field[i] = 0;
  138.                     }
  139.                     break;
  140.                 default:
  141.                     break;
  142.             }
  143.         }
  144. }
  145.  
  146. int main(int argc, char **argv)
  147. {
  148.     // x: zombies, y: victims, z: hunters
  149.     int i, j;
  150.     if (argc < 4) {
  151.         printf("too few args. format: [zombies] [victims] [hunters] [[ticks]]\n");
  152.         return 1;
  153.     }
  154.  
  155.     x = xinit = atoi(argv[1]);
  156.     y = yinit = atoi(argv[2]);
  157.     z = zinit = atoi(argv[3]);
  158.     if (argc > 4)
  159.         ticks = atoi(argv[4]);
  160.  
  161.     if (x < 0 || y < 0 || z < 0 || x + y + z > SQDIM) {
  162.         printf("all args must be >0, "
  163.                 "sum must be less than 401\n");
  164.         return 2;
  165.     }
  166.  
  167.     int *deck = malloc(SQDIM * sizeof(int));
  168.     char *field = calloc(SQDIM, 1);
  169.     if (!deck || !field) {
  170.         fprintf(stderr, "Mem allocation error\n");
  171.         return 2;
  172.     }
  173.  
  174.     for (i = 0; i < SQDIM; ++i)
  175.         deck[i] = i;
  176.  
  177.     srand(time(0));
  178.     shuffle(deck, SQDIM);
  179.  
  180.     for (i = 0; i < x; ++i)
  181.         field[deck[i]] = 'Z';
  182.     for (i = x; i - x < y; ++i)
  183.         field[deck[i]] = 'V';
  184.     for (i = x + y; i - x - y < z; ++i)
  185.         field[deck[i]] = 'H';
  186.  
  187.     for (i = 0; i < 8; ++i)
  188.         deck[i] = i;
  189.  
  190.     printf("Initial field state:\n");
  191.     for (i = 0; i < DIM; ++i) {
  192.         for (j = 0; j < DIM; ++j)
  193.             printf("%c",
  194.                     field[i*DIM + j] ? field[i*DIM + j] : '-');
  195.         putchar('\n');
  196.     }
  197.     putchar ('\n');
  198.  
  199.     for (i = 0; i < 100 + rand(); ++i)
  200.         j = rand();
  201.  
  202.     sim(field, deck, ticks);
  203.  
  204.     printf("Final field state:\n");
  205.     for (i = 0; i < DIM; ++i) {
  206.         for (j = 0; j < DIM; ++j)
  207.             printf("%c",
  208.                     field[i*DIM + j] ? field[i*DIM + j] : '-');
  209.         putchar('\n');
  210.     }
  211.  
  212.     printf("\nSimulation results:\n\n");
  213.     printf("Inittal population:\n"
  214.             "  Zombies: %d\n"
  215.             "  Victims: %d\n"
  216.             "  Hunters: %d\n\n",
  217.             xinit, yinit, zinit
  218.           );
  219.  
  220.     printf("Final population after %d ticks:\n"
  221.             "  Zombies: %d\n"
  222.             "  Victims: %d\n"
  223.             "  Hunters: %d\n\n",
  224.             ticks, x, y, z
  225.           );
  226.  
  227.     printf("Zombie stumbles: %d\n"
  228.             "Victim flees: %d\n"
  229.             "Hunter seeks: %d\n\n",
  230.             stumble, flee, seek
  231.           );
  232.  
  233.     printf("Total zombified: %d\n"
  234.             "Victims zombified: %d\n"
  235.             "Hunters zombified: %d\n"
  236.             "Total kills: %d\n"
  237.             "Single zombie kills: %d\n"
  238.             "Double zombie kills: %d\n\n",
  239.             zombtotal, zombvictim, zombhunter,
  240.             killtotal, singlekill, doublekill
  241.           );
  242.  
  243.     if (!(y+z))
  244.         printf("The zombies have won!\n");
  245.     else if (!x)
  246.         printf("The living have won!\n");
  247.     else if ((abs(zombtotal - killtotal) <= 5))
  248.         printf("The zombies and the living have tied!\n");
  249.     else if (zombtotal > killtotal > 5)
  250.         printf("The zombies have won!\n");
  251.     else
  252.         printf("The living have won!\n");
  253.     return 0;
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement