Advertisement
Guest User

Untitled

a guest
Dec 10th, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.80 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <vector>
  5. #include <time.h>
  6. #include <unistd.h>
  7. #include <algorithm>
  8. #include <math.h>
  9. #include <string>
  10.  
  11. using namespace std;
  12.  
  13. #define FIELD_WIDTH 50
  14. #define FIELD_HEIGHT 50
  15.  
  16. #define COMMON_VOLE_NEIGHBOURS_X 1
  17. #define COMMON_VOLE_NEIGHBOURS_Y 1
  18.  
  19. // USER ARGUMENTS
  20. int arg_deepPlowingWeek = 0;
  21. int arg_commonVolesToSpawn = 0;
  22. int arg_planting = 0;
  23. int arg_acid = 0;
  24.  
  25. int weeks_count = 0;
  26. int common_voles_count = 0;
  27. bool overcrowded = false;
  28.  
  29. /**
  30.  * Single common vole structure
  31.  */
  32. struct CommonVole {
  33.     bool isMale;
  34.     unsigned int age;
  35.     unsigned int remainingWeeksOfPregnancy;
  36.     unsigned int foodSupply;
  37. };
  38.  
  39. /**
  40.  * Represents one single food unit in field
  41.  */
  42. struct FoodUnit {
  43.     bool available;
  44.     int timeToRenew;
  45. };
  46.  
  47. /**
  48.  * Structure for next move propability
  49.  */
  50. struct MovePropability {
  51.     int x;
  52.     int y;
  53.     float propability;
  54. };
  55.  
  56. /**
  57.  * Field
  58.  */
  59. vector<CommonVole> fieldOfCommonVoles[FIELD_HEIGHT][FIELD_WIDTH];
  60. FoodUnit food[FIELD_HEIGHT][FIELD_WIDTH];
  61.  
  62. /**
  63.  * Calculate amount of predators
  64.  * @return
  65.  */
  66. int getPredatorsAmount() {
  67.     return (pow(common_voles_count, 2) / 15000);
  68. }
  69.  
  70. /**
  71.  * Print field of common voles
  72.  * @param field
  73.  */
  74. void printField(){
  75.     printf("\n\n\n\n\nWeek number: %d\nCommon voles amount: %d\nPredators: %d\n", weeks_count, common_voles_count, getPredatorsAmount());
  76.     for(int y = 0; y < FIELD_HEIGHT; y++){
  77.         for(int x = 0; x < FIELD_WIDTH; x++){
  78.             // Setting the right background color
  79.             if(food[y][x].available){
  80.                 cout << "\033[37;43m";
  81.             } else {
  82.                 cout << "\033[0m";
  83.             }
  84.  
  85.             if(fieldOfCommonVoles[y][x].size() > 0){
  86.                 cout << fieldOfCommonVoles[y][x].size() << " ";
  87.             } else {
  88.                 printf("- ");
  89.             }
  90.  
  91.             cout << "\033[0m";
  92.         }
  93.         printf("\n");
  94.     }
  95. }
  96.  
  97. /**
  98.  * Clears field from food
  99.  */
  100. void clearFood(){
  101.     for(int i = 0; i < FIELD_HEIGHT; i++){
  102.         fill_n(food[i], FIELD_WIDTH, (FoodUnit){.available = false, .timeToRenew = 0});
  103.     }
  104. }
  105.  
  106. /**
  107.  * Makes food
  108.  */
  109. void spawnFood(){
  110.     for(int i = 0; i < FIELD_HEIGHT; i++){
  111.         fill_n(food[i], FIELD_WIDTH, (FoodUnit){.available = true, .timeToRenew = 0});
  112.     }
  113. }
  114.  
  115. /**
  116.  * Checks whether food should be renewed
  117.  * if so, renew it!
  118.  */
  119. void foodCheck(){
  120.     if(weeks_count >= 12 && weeks_count <= 35){
  121.         for(int y = 0; y < FIELD_HEIGHT; y++){
  122.             for(int x = 0; x < FIELD_WIDTH; x++){
  123.                 if(!food[y][x].available){
  124.                     food[y][x].timeToRenew--;
  125.                     if(food[y][x].timeToRenew == 0){
  126.                         food[y][x].available = true;
  127.                     }
  128.                 }
  129.             }
  130.         }
  131.     }
  132. }
  133.  
  134. /**
  135.  * Manage common vole starvation
  136.  */
  137. void commonVoleStarvation(){
  138.     for(int y = 0; y < FIELD_HEIGHT; y++){
  139.         for(int x = 0; x < FIELD_WIDTH; x++){
  140.             if(fieldOfCommonVoles[y][x].size() > 0){
  141.                 for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
  142.                     fieldOfCommonVoles[y][x].at(i).foodSupply--;
  143.                     if(fieldOfCommonVoles[y][x].at(i).foodSupply == 0){
  144.                         fieldOfCommonVoles[y][x].erase(fieldOfCommonVoles[y][x].begin() + i);
  145.                         common_voles_count--;
  146.                         continue;
  147.                     }
  148.                 }
  149.             }
  150.         }
  151.     }
  152. }
  153.  
  154. /**
  155.  * Deep plowing apears!
  156.  */
  157. void deepPlowing(){
  158.     bool shouldRemove = true;
  159.  
  160.     for(int y = 0; y < FIELD_HEIGHT; y++){
  161.         for(int x = 0; x < FIELD_WIDTH; x++){
  162.             if(fieldOfCommonVoles[y][x].size() > 0){
  163.                 for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
  164.                     if(shouldRemove){
  165.                         fieldOfCommonVoles[y][x].erase(fieldOfCommonVoles[y][x].begin() + i);
  166.                         shouldRemove = false;
  167.                         common_voles_count--;
  168.                     } else {
  169.                         shouldRemove = true;
  170.                     }
  171.                 }
  172.             }
  173.         }
  174.     }
  175.  
  176.     clearFood();
  177. }
  178.  
  179. /**
  180.  * Acid application
  181.  */
  182. void acidApplication(){
  183.     int amountOfCommonVolesToKill = common_voles_count * (50 + rand() % 45) / 100;
  184.  
  185.     for(int y = 0; y < FIELD_HEIGHT; y++){
  186.         for(int x = 0; x < FIELD_WIDTH; x++){
  187.             if(fieldOfCommonVoles[y][x].size() > 0){
  188.                 for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
  189.                     if(amountOfCommonVolesToKill > 0){
  190.                         fieldOfCommonVoles[y][x].erase(fieldOfCommonVoles[y][x].begin() + i);
  191.                         amountOfCommonVolesToKill--;
  192.                         common_voles_count--;
  193.                     }
  194.                 }
  195.             }
  196.         }
  197.     }
  198.  
  199.     clearFood();
  200. }
  201.  
  202. /**
  203.  * Get most possible move
  204.  */
  205. MovePropability chooseMoveDependingOnPropability(vector<MovePropability> moveRecords){
  206.     random_shuffle(moveRecords.begin(), moveRecords.end());
  207.     MovePropability move = moveRecords[0];
  208.     for(int i = 0; i < moveRecords.size(); i++){
  209.         if(moveRecords[i].propability > move.propability) move = moveRecords[i];
  210.     }
  211.     return move;
  212. }
  213.  
  214. /**
  215.  * Check whether any female
  216.  * should have children.. If so, DO IT!
  217.  */
  218. void commonVoleReproductionCheck(){
  219.     for(int y = 0; y < FIELD_HEIGHT; y++){
  220.         for(int x = 0; x < FIELD_WIDTH; x++){
  221.             if(fieldOfCommonVoles[y][x].size() > 0){
  222.                 for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
  223.                     // Increment their age
  224.                     fieldOfCommonVoles[y][x].at(i).age++;
  225.  
  226.                     // THE REPRODUCTION!!!!
  227.                     if(fieldOfCommonVoles[y][x].at(i).remainingWeeksOfPregnancy == 1){
  228.                         fieldOfCommonVoles[y][x].at(i).remainingWeeksOfPregnancy--;
  229.  
  230.                         int numberOfChilds = 3 + rand() % 8;
  231.                         for(int childs = 0; childs < numberOfChilds; childs++){
  232.                             int dx = -1 + rand() % 3;
  233.                             int dy = -1 + rand() % 3;
  234.  
  235.                             if((y + dy) >= 0 && (y + dy < FIELD_HEIGHT) && (x + dx) >= 0 && (x + dx) < FIELD_WIDTH){
  236.                                 fieldOfCommonVoles[y + dy][x + dx].push_back((CommonVole){
  237.                                     .isMale = ((rand() % 100) > 60) ? false : true,
  238.                                     .age = 0,
  239.                                     .remainingWeeksOfPregnancy = 0,
  240.                                     .foodSupply = 2
  241.                                 });
  242.                                 common_voles_count++;
  243.                             } else {
  244.                                 childs--;
  245.                             }
  246.                         }
  247.                     } else if(fieldOfCommonVoles[y][x].at(i).remainingWeeksOfPregnancy > 0){
  248.                         fieldOfCommonVoles[y][x].at(i).remainingWeeksOfPregnancy--;
  249.                     }
  250.                 }
  251.             }
  252.         }
  253.     }
  254. }
  255.  
  256. /**
  257.  * Apply evil predators
  258.  */
  259. void applyPredators(){
  260.     int predators_count = getPredatorsAmount();
  261.     for(int i = 0; i < predators_count; i++){
  262.  
  263.         int chance = rand() % 100;
  264.         int propabilityForHunt = (int)((sin((weeks_count / 10.0) - (M_PI)) + 1.0) / 2 * 100);
  265.  
  266.         if(overcrowded == true) propabilityForHunt *= 4;
  267.  
  268.         if(chance < propabilityForHunt){
  269.             int amountOfCommonVolesToKill = rand() % (35 * ((overcrowded == true) ? 5 : 1));
  270.  
  271.             for(int j = 0; j < amountOfCommonVolesToKill; j++){
  272.                 int randX = rand() % (FIELD_WIDTH - 1);
  273.                 int randY = rand() % (FIELD_HEIGHT - 1);
  274.  
  275.                 if(fieldOfCommonVoles[randY][randX].size() > 0){
  276.                     amountOfCommonVolesToKill -= fieldOfCommonVoles[randY][randX].size();
  277.                     common_voles_count -= fieldOfCommonVoles[randY][randX].size();
  278.                     fieldOfCommonVoles[randY][randX].clear();
  279.                 }
  280.             }
  281.         }
  282.     }
  283. }
  284.  
  285. int main(int argc, char *argv[]) {
  286.  
  287.     try{
  288.         int opt;
  289.         while ((opt = getopt(argc, argv, "c:d:p:a:")) != -1){ // Iterate through all command line arguments
  290.             switch(opt){
  291.                 case 'd':
  292.                     arg_deepPlowingWeek = stoi(optarg);
  293.                     break;
  294.  
  295.                 case 'p':
  296.                     arg_planting = stoi(optarg);
  297.                     break;
  298.  
  299.                 case 'c':
  300.                     arg_commonVolesToSpawn = stoi(optarg);
  301.                     break;
  302.  
  303.                 case 'a':
  304.                     arg_acid = stoi(optarg);
  305.                     break;
  306.  
  307.                 default:
  308.                     abort();
  309.             }
  310.         }
  311.     } catch (exception e){
  312.         fprintf(stderr, "Error while parsing arguments\n");
  313.         exit(10);
  314.     }
  315.  
  316.     if(arg_commonVolesToSpawn == 0){
  317.         fprintf(stderr, "-c parameter is mandatory\n");
  318.         exit(10);
  319.     }
  320.  
  321.  
  322.     srand(time(NULL)); // Seed random number generator
  323.  
  324.     int commonVolesToSpawn = arg_commonVolesToSpawn; // Common voles to start with
  325.  
  326.     for(int i = 0; i < commonVolesToSpawn; i++){ // Spawn common voles into field
  327.         int random_x = rand() % FIELD_WIDTH;
  328.         int random_y = rand() % FIELD_HEIGHT;
  329.  
  330.         fieldOfCommonVoles[random_y][random_x].push_back((CommonVole){
  331.             .isMale = ((rand() % 100) > 60) ? false : true,
  332.             .age = 0,
  333.             .remainingWeeksOfPregnancy = 0,
  334.             .foodSupply = 14
  335.         });
  336.  
  337.         common_voles_count++;
  338.     }
  339.  
  340.     // Initialize food array
  341.     clearFood();
  342.  
  343.     // Main loop
  344.     while(true){
  345.         // Creating food if it is the right time
  346.         if(weeks_count == ((arg_planting == 0) ? 12 : arg_planting)) spawnFood();
  347.         foodCheck();
  348.  
  349.         // If we are harvesting
  350.         if(weeks_count == ((arg_deepPlowingWeek == 0) ? 35 : arg_deepPlowingWeek)) deepPlowing();
  351.  
  352.         // If it is acid application week
  353.         if(arg_acid != 0 && arg_acid == weeks_count) acidApplication();
  354.  
  355.         // Common vole reproduction check
  356.         commonVoleReproductionCheck();
  357.  
  358.         if(common_voles_count >= 1000) overcrowded = true;
  359.  
  360.         // Check if any common vole starved to death
  361.         commonVoleStarvation();
  362.  
  363.         // Apply predators
  364.         applyPredators();
  365.  
  366.         // Moving common voles
  367.         for(int y = 0; y < FIELD_HEIGHT; y++){
  368.             for(int x = 0; x < FIELD_WIDTH; x++){
  369.                 if(fieldOfCommonVoles[y][x].size() > 0){
  370.                     for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
  371.                         // Make some children
  372.                         for(int dy = y - COMMON_VOLE_NEIGHBOURS_Y; dy <= y + COMMON_VOLE_NEIGHBOURS_Y; dy++){
  373.                             for(int dx = x - COMMON_VOLE_NEIGHBOURS_X; dx <= x + COMMON_VOLE_NEIGHBOURS_X; dx++){
  374.  
  375.                                 if( // If we are within field boundaries
  376.                                     ((dx >= 0) && (dx < FIELD_WIDTH)) &&
  377.                                     ((dy >= 0) && (dy < FIELD_HEIGHT)) &&
  378.                                     fieldOfCommonVoles[dy][dx].size() > 0)
  379.                                 {
  380.                                     for(int parentCandidate = 0; parentCandidate < fieldOfCommonVoles[dy][dx].size(); parentCandidate++){
  381.  
  382.                                         if(
  383.                                             fieldOfCommonVoles[y][x].at(i).isMale &&
  384.                                             fieldOfCommonVoles[y][x].at(i).age >= 3 &&
  385.                                             !fieldOfCommonVoles[dy][dx].at(parentCandidate).isMale &&
  386.                                             fieldOfCommonVoles[dy][dx].at(parentCandidate).remainingWeeksOfPregnancy == 0 &&
  387.                                             fieldOfCommonVoles[dy][dx].at(parentCandidate).age >= 3 &&
  388.                                             weeks_count >= 12 &&
  389.                                             weeks_count <= 35
  390.                                         ){
  391.                                             // We have found girl to have children with
  392.                                             fieldOfCommonVoles[dy][dx].at(parentCandidate).remainingWeeksOfPregnancy = 3;
  393.                                         }
  394.                                     }
  395.                                 }
  396.                             }
  397.                         }
  398.  
  399.                         // Calculate move propabilities for each neighbour
  400.                         vector<MovePropability> possibleMoves;
  401.  
  402.                         for(int dy = y - COMMON_VOLE_NEIGHBOURS_Y; dy <= y + COMMON_VOLE_NEIGHBOURS_Y; dy++){
  403.                             for(int dx = x - COMMON_VOLE_NEIGHBOURS_X; dx <= x + COMMON_VOLE_NEIGHBOURS_X; dx++){
  404.                                 if(dx == 0 && dy == 0) continue;
  405.  
  406.                                 int nextX = dx, nextY = dy;
  407.  
  408.                                 if(nextX < 0) nextX = FIELD_WIDTH - abs(nextX);
  409.                                 if(nextX > FIELD_WIDTH - 1) nextX = nextX - FIELD_WIDTH;
  410.                                 if(nextY < 0) nextY = FIELD_HEIGHT - abs(nextY);
  411.                                 if(nextY > FIELD_HEIGHT - 1) nextY = nextY - FIELD_HEIGHT;
  412.  
  413.  
  414.                                 possibleMoves.push_back((MovePropability){
  415.                                     .x = nextX,
  416.                                     .y = nextY,
  417.                                     .propability = (float)(food[nextY][nextX].available / ((COMMON_VOLE_NEIGHBOURS_X * 2) * (COMMON_VOLE_NEIGHBOURS_Y * 2) - 1.0))
  418.                                 });
  419.                             }
  420.                         }
  421.  
  422.                         // Choose THE move
  423.                         MovePropability choosedMove = chooseMoveDependingOnPropability(possibleMoves);
  424.                         if(choosedMove.propability > 0){
  425.                             fieldOfCommonVoles[y][x].at(i).foodSupply = fieldOfCommonVoles[y][x].at(i).foodSupply + 3;
  426.                             fieldOfCommonVoles[choosedMove.y][choosedMove.x].push_back(fieldOfCommonVoles[y][x].at(i));
  427.                             food[choosedMove.y][choosedMove.x] = (FoodUnit){
  428.                                 .available = false,
  429.                                 .timeToRenew = 3
  430.                             };
  431.                             fieldOfCommonVoles[y][x].erase(fieldOfCommonVoles[y][x].begin() + i);
  432.                         }
  433.                     }
  434.                 }
  435.             }
  436.         }
  437.  
  438.         printField();
  439.         weeks_count++;
  440.         if(weeks_count >= 50) overcrowded = false;
  441.         weeks_count = weeks_count % 52;
  442.         usleep(500000);
  443.     }
  444. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement