Advertisement
uzimane_

zoom try

Nov 3rd, 2020 (edited)
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.26 KB | None | 0 0
  1. #define OLC_PGE_APPLICATION
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <string>
  5. #include <vector>
  6. #include <time.h>
  7. #include "olcPixelGameEngine.h"
  8.  
  9. using namespace std;
  10.  
  11. class Food {
  12. public:
  13.     int x, y;
  14.     bool isCorpse = false;
  15. };
  16.  
  17. class Unit {
  18. public:
  19.     int x, y;
  20.     int id;
  21.     int hunger;
  22.     pair<int, int> destination;
  23.     int foodDestinationID;
  24.     char sex;
  25.     int multiplyCoolDown = 0;
  26.  
  27.     bool checkCoordByXIsFree(int whereToGo, int width, int **mat) {
  28.         if (x + whereToGo < width
  29.             and
  30.             x + whereToGo >= 0
  31.             and
  32.             mat[x + whereToGo][y] != 1
  33.             and
  34.             mat[x + whereToGo][y] != 2) {
  35.             return true;
  36.         }
  37.         else
  38.             return false;
  39.     }
  40.  
  41.     bool checkCoordByYIsFree(int whereToGo, int height, int **mat) {
  42.         if (y + whereToGo < height
  43.             and
  44.             y + whereToGo >= 0
  45.             and
  46.             mat[x][y + whereToGo] != 1
  47.             and
  48.             mat[x][y + whereToGo] != 2) {
  49.             return true;
  50.         }
  51.         else
  52.             return false;
  53.     }
  54.  
  55.     bool validCoord(int x, int y, int width, int height, int **mat) {
  56.         if (x >= 0 and x < width and y >= 0 and y < height and mat[x][y] == 0)
  57.             return true;
  58.         else
  59.             return false;
  60.     }
  61.  
  62.     vector<Food> becomeCorpse(vector<Food> food) {
  63.         Food corpse;
  64.         corpse.x = this->x;
  65.         corpse.y = this->y;
  66.         corpse.isCorpse = true;
  67.         food.push_back(corpse);
  68.         return food;
  69.     }
  70.  
  71.     void moveTowards(int width, int height, int **mat) {
  72.  
  73.         int xOrY[2] = { 0, 1 };
  74.         int direction;
  75.         bool flagX = false, flagY = false;
  76.         int retryCount = 0;
  77.  
  78.         while (retryCount < 4) {
  79.  
  80.             int x_or_y = xOrY[rand() % 2];
  81.  
  82.             if (x - destination.first == 0)
  83.                 x_or_y = 1;
  84.             if (y - destination.second == 0)
  85.                 x_or_y = 0;
  86.  
  87.             if (x_or_y == 0)
  88.                 if (x - destination.first < 0)
  89.                     direction = 1;
  90.                 else
  91.                     direction = -1;
  92.  
  93.             if (x_or_y == 1)
  94.                 if (y - destination.second < 0)
  95.                     direction = 1;
  96.                 else
  97.                     direction = -1;
  98.  
  99.             if (x_or_y == 0 and checkCoordByXIsFree(direction, width, mat) == true) {
  100.                 x += direction;
  101.                 flagX = true;
  102.             }
  103.  
  104.             if (x_or_y == 1 and checkCoordByYIsFree(direction, height, mat) == true) {
  105.                 y += direction;
  106.                 flagY = true;
  107.             }
  108.  
  109.             if (flagX == 0 and flagY == 0) {
  110.                 retryCount++;
  111.                 continue;
  112.             }
  113.  
  114.             if (hunger > 0) {
  115.                 hunger--;
  116.                 return;
  117.             }
  118.             else {
  119.                 return;
  120.             }
  121.         }
  122.     }
  123.  
  124.     vector<Unit> multiply(vector<Unit> Units, int width, int height, int **mat) {
  125.         int retryCount = 0;
  126.         char sex[2] = { 'f', 'm' };
  127.  
  128.         Unit unit;
  129.         unit.hunger = 100;
  130.         unit.multiplyCoolDown = 0;
  131.         unit.x = x;
  132.         unit.y = y;
  133.         unit.sex = sex[rand() % 2];
  134.         //unit.newBorn = true;
  135.         Units.push_back(unit);
  136.         //mat[unit.x][unit.y] = 1;
  137.         return Units;
  138.     }
  139.  
  140.     vector<Unit> findPair(vector<Unit> Units, int id, int width, int height, int** mat) {
  141.         int minDist = INT_MAX;
  142.         int destID = -1;
  143.         for (int i = 0; i < Units.size(); i++) {  
  144.             int curDist = abs(x - Units[i].x) + abs(y - Units[i].y);
  145.             if (Units[i].sex != Units[id].sex and Units[i].hunger > 85 and curDist < minDist) { //////// heavy variant to check all existing units, appropriate
  146.                 minDist = curDist;                                                                       //only for small map size
  147.                 destID = i;
  148.             }
  149.         }
  150.  
  151.         //for (int i = Units[id].x - 20; i < Units[id].x + 20; i++) {
  152.         //  for (int j = Units[id].y - 20; i < Units[id].y + 20; j++) {
  153.         //      if (mat[i][j] == 1) {
  154.         //          int curDist = abs(Units[id].x - Units[i].x) + abs(y - Units[i].y);
  155.  
  156.         //      }
  157.         //  }
  158.         //}
  159.  
  160.         if (destID != -1) {
  161.             Units[id].destination.first = Units[destID].x;
  162.             Units[id].destination.second = Units[destID].y;
  163.         }
  164.        
  165.         return Units;
  166.     }
  167.  
  168.     vector<Unit> seekPair(vector<Unit> Units, int id, int width, int height, int** mat) {
  169.  
  170.         int dist;
  171.         int unitIdle = 1;
  172.  
  173.         Units = findPair(Units, id, width, height, mat);
  174.    
  175.         if (Units[id].destination.first == 0 and Units[id].destination.second == 0) {
  176.             Units[id].walk(width, height, mat);
  177.             return Units;
  178.         }
  179.  
  180.         if (abs(Units[id].x - Units[id].destination.first) + abs(Units[id].y - Units[id].destination.second) > 1 ) {
  181.             Units[id].moveTowards(width, height, mat);
  182.             unitIdle = 0;
  183.         }
  184.  
  185.         for (int i = 0;i < Units.size();i++) {
  186.             dist = abs(Units[id].x - Units[i].x) + abs(Units[id].y - Units[i].y);
  187.             if (dist == 1 and Units[id].multiplyCoolDown >= 100 and Units[i].multiplyCoolDown >= 100 and Units[id].sex != Units[i].sex) {
  188.                 Units = multiply(Units, width, height, mat);
  189.                 Units[id].multiplyCoolDown = 0;
  190.                 Units[i].multiplyCoolDown = 0;
  191.                 unitIdle = 0;
  192.             }
  193.         }
  194.  
  195.         if (unitIdle == 1) {
  196.             Units[id].walk(width, height, mat);
  197.             return Units;
  198.         }
  199.  
  200.         return Units;
  201.     }
  202.  
  203.     pair<vector<Food>, vector<Food>> eat(vector<Food> food, vector<Food> eatenFood) {
  204.         pair<vector<Food>, vector<Food>> foods;
  205.  
  206.         eatenFood.push_back(food[foodDestinationID]);
  207.         food.erase(food.begin() + foodDestinationID);
  208.         foods.first = food;
  209.         foods.second = eatenFood;
  210.         hunger = 100;
  211.         return foods;
  212.     }
  213.  
  214.     void findNearestFood(vector<Food> food) {
  215.         int minDist = INT_MAX;
  216.         if (food.size() == 0) {
  217.             return;
  218.         }
  219.         for (int i = 0; i < food.size(); i++) {
  220.             int curDist = abs(x - food[i].x) + abs(y - food[i].y);
  221.             if (curDist < minDist) {
  222.                 minDist = curDist;
  223.                 destination.first = food[i].x;
  224.                 destination.second = food[i].y;
  225.                 foodDestinationID = i;
  226.             }
  227.         }
  228.     }
  229.  
  230.     pair<vector<Food>, vector<Food>> seekFood(vector<Food> food, vector<Food> eatenFood, int width, int height, int** mat) {
  231.         findNearestFood(food);
  232.         pair<vector<Food>, vector<Food>> foods;
  233.         foods.first = food;
  234.         foods.second = eatenFood;
  235.  
  236.         int foodIdle = 1;
  237.  
  238.         if (abs(x - destination.first) + abs(y - destination.second) > 1) {
  239.             moveTowards(width, height, mat);
  240.             foodIdle = 0;
  241.             return foods;
  242.         }
  243.         else if (abs(x - destination.first) + abs(y - destination.second) == 1) {
  244.             foodIdle = 0;
  245.             return eat(food, eatenFood);
  246.         }
  247.  
  248.         if (foodIdle == 1) {
  249.             return foods;
  250.         }
  251.        
  252.     }
  253.  
  254.     //............................
  255.  
  256.     void walk(int width, int height, int **mat) {
  257.  
  258.         int upOrDown[2] = { -1, 1 };
  259.         int leftOrRight[2] = { 0, 1 };
  260.         bool flagX = 0, flagY = 0;
  261.         int retryCount = 0;
  262.  
  263.         while (retryCount < 4) {
  264.  
  265.             int moveUpOrDown = upOrDown[rand() % 2];
  266.             int moveLeftOrRight = leftOrRight[rand() % 2];;
  267.  
  268.             if (moveLeftOrRight == 0 and validCoord(x + moveUpOrDown, y, width, height, mat) == true) {
  269.                 x += moveUpOrDown;
  270.                 flagX = 1;
  271.             }
  272.  
  273.             if (moveLeftOrRight == 1 and validCoord(x, y + moveUpOrDown, width, height, mat) == true) {
  274.                 y += moveUpOrDown;
  275.                 flagY = 1;
  276.             }
  277.  
  278.             if (flagX == 0 and flagY == 0) {
  279.                 retryCount++;
  280.                 continue;
  281.             }
  282.  
  283.             if (hunger > 0) {
  284.                 hunger--;
  285.                 return;
  286.             }
  287.         }
  288.     }
  289.  
  290. };
  291.  
  292. class Karta {
  293. public:
  294.  
  295.     int height, width;
  296.     int** mat;
  297.     vector<Unit> Units;
  298.     vector<Unit> unitsPrevPos;
  299.     vector<Unit> newUnits;
  300.     vector<Food> food;
  301.     vector<Food> eatenFood;
  302.     pair<vector<Food>, vector<Food>> foods;
  303.  
  304.     bool validCoord(int x, int y) {
  305.         if (x >= 0 and x < width and y >= 0 and y < height and mat[x][y] == 0)
  306.             return true;
  307.         else
  308.             return false;
  309.     }
  310.  
  311.     void createMap(int w, int h, int unitsAmount) {
  312.         mat = new int* [w];
  313.         for (int i = 0; i < w; i++) {
  314.             mat[i] = new int[h];
  315.         }
  316.         for (int i = 0; i < w; i++) {
  317.             for (int j = 0; j < h; j++) {
  318.                 mat[i][j] = 0;
  319.             }
  320.         }
  321.         height = h;
  322.         width = w;
  323.         spawnUnits(unitsAmount);
  324.     }
  325.  
  326.     void spawnUnits(int amount) {
  327.         for (int i = 0; i < amount; i++) {
  328.             Unit unit;
  329.             unit.x = rand() % width;
  330.             unit.y = rand() % height;
  331.             char Sex[2] = { 'm', 'f' };
  332.             char sex = Sex[rand() % 2];
  333.             unit.sex = sex;
  334.             unit.hunger = 100;
  335.             if (mat[unit.x][unit.y] == 0) {
  336.                 Units.push_back(unit);
  337.                 mat[unit.x][unit.y] = 1;
  338.             }
  339.             else {
  340.                 i--;
  341.                 continue;
  342.             }
  343.         }
  344.         spawnFirstFood();
  345.     }
  346.  
  347.     void spawnFirstFood() {
  348.         for (int i = 0; i < Units.size() / 2; i++) {
  349.             Food eda;
  350.             eda.x = rand() % width;
  351.             eda.y = rand() % height;
  352.             if (mat[eda.x][eda.y] == 0) {
  353.                 food.push_back(eda);
  354.                 mat[eda.x][eda.y] = 2;
  355.             }
  356.             else {
  357.                 i--;
  358.                 continue;
  359.             }
  360.         }
  361.     }
  362.  
  363.     void spawnFood(int ctr) {
  364.         int retryCount = 0;
  365.         while (retryCount < 4) {
  366.             Food eda;
  367.             Food newEda;
  368.             eda = food[ctr % food.size()];
  369.             int x_or_y[2] = { 0, 1 };
  370.             int up_or_down[2] = { -1, 1 };
  371.  
  372.             int xOrY = x_or_y[rand() % 2];
  373.             int upOrDown = up_or_down[rand() % 2];
  374.  
  375.             if (xOrY == 0) {
  376.                 if (upOrDown == -1) {
  377.                     newEda.x = eda.x - 1;
  378.                     newEda.y = eda.y;
  379.                 }
  380.                 if (upOrDown == 1) {
  381.                     newEda.x = eda.x + 1;
  382.                     newEda.y = eda.y;
  383.                 }
  384.             }
  385.             if (xOrY == 1) {
  386.                 if (upOrDown == -1) {
  387.                     newEda.x = eda.x;
  388.                     newEda.y = eda.y - 1;
  389.                 }
  390.                 if (upOrDown == 1) {
  391.                     newEda.x = eda.x;
  392.                     newEda.y = eda.y + 1;
  393.                 }
  394.             }
  395.  
  396.             if (validCoord(newEda.x, newEda.y) == true) {
  397.                 food.push_back(newEda);
  398.                 mat[newEda.x][newEda.y] = 2;
  399.                 break;
  400.             }
  401.             else {
  402.                 retryCount++;
  403.                 continue;
  404.             }
  405.         }
  406.     }
  407.  
  408.     int goLive(int ctr) {
  409.         unitsPrevPos = Units;
  410.         eatenFood.clear();
  411.         if (ctr % 2 == 0) {
  412.             spawnFood(ctr / 2);
  413.         }
  414.         for (int j = 0; j < Units.size(); j++) {
  415.             Units[j].multiplyCoolDown++;
  416.             if (Units[j].hunger > 50 and Units[j].multiplyCoolDown >= 100) {
  417.                 Units = Units[j].seekPair(Units, j, width, height, mat);
  418.                 if (unitsPrevPos.size() < Units.size()) {
  419.                     mat[Units.back().x][Units.back().y] = 1;
  420.                 }
  421.                 continue;
  422.             }
  423.             if (Units[j].hunger > 25) {
  424.                 Units[j].walk(width, height, mat);
  425.                 continue;
  426.             }
  427.             if (Units[j].hunger <= 25 and Units[j].hunger > 0) {
  428.                 foods = Units[j].seekFood(food, eatenFood, width, height, mat);
  429.                 food = foods.first;
  430.                 eatenFood = foods.second;
  431.                 continue;
  432.             }
  433.             if (Units[j].hunger == 0) {
  434.                 food = Units[j].becomeCorpse(food);
  435.                 mat[Units[j].x][Units[j].y] = 2;
  436.                 Units.erase(Units.begin() + j);
  437.             }
  438.         }
  439.        
  440.         for (int i = 0; i < unitsPrevPos.size(); i++) {
  441.             mat[unitsPrevPos[i].x][unitsPrevPos[i].y] = 0;
  442.         }
  443.         for (int i = 0; i < Units.size(); i++) {
  444.             mat[Units[i].x][Units[i].y] = 1;
  445.         }
  446.         for (int i = 0; i < eatenFood.size(); i++) {
  447.             mat[eatenFood[i].x][eatenFood[i].y] = 0;
  448.         }
  449.         return ++ctr;
  450.     }
  451. };
  452.  
  453.  
  454.  
  455.  
  456.  
  457. class LifeSimulation : public olc::PixelGameEngine {
  458. public:
  459.  
  460.     LifeSimulation() {
  461.         sAppName = "LifeSimulation";
  462.     }
  463.  
  464.     Karta map;
  465.     int ctr = 0;
  466.  
  467.     int rem = 0;
  468.  
  469.     float fOffsetX = 0.0f;
  470.     float fOffsetY = 0.0f;
  471.     float fScaleX = 1.0f;
  472.     float fScaleY = 1.0f;
  473.  
  474.     float fStartPanX = 0.0f;
  475.     float fStartPanY = 0.0f;
  476.  
  477.     float fSelectedCellX = 0.0f;
  478.     float fSelectedCellY = 0.0f;
  479.  
  480.     bool OnUserCreate() override {
  481.  
  482.         int unitsAmount = 20;
  483.         map.createMap(ScreenWidth(), ScreenHeight(), unitsAmount);
  484.  
  485.         for (int x = 0; x < ScreenWidth(); x++) {
  486.             for (int y = 0; y < ScreenHeight(); y++) {
  487.                 Draw(x, y, olc::Pixel(0, 255, 0));
  488.             }
  489.         }
  490.  
  491.         fOffsetX = -ScreenWidth() / 2;
  492.         fOffsetY = -ScreenHeight() / 2;
  493.  
  494.         return true;
  495.     }
  496.  
  497.     void WorldToScreen(float fWorldX, float fWorldY, int& nScreenX, int& nScreenY)
  498.     {
  499.         nScreenX = (int)((fWorldX - fOffsetX) * fScaleX);
  500.         nScreenY = (int)((fWorldY - fOffsetY) * fScaleY);
  501.     }
  502.  
  503.     void ScreenToWorld(int nScreenX, int nScreenY, float& fWorldX, float& fWorldY)
  504.     {
  505.         fWorldX = ((float)nScreenX / fScaleX) + fOffsetX;
  506.         fWorldY = ((float)nScreenY / fScaleY) + fOffsetY;
  507.     }
  508.  
  509.     bool OnUserUpdate(float fElapsedTime) override {
  510.  
  511.  
  512.         float fMouseX = (float)GetMouseX();
  513.         float fMouseY = (float)GetMouseY();
  514.  
  515.         // For panning, we need to capture the screen location when the user starts
  516.         // to pan...
  517.         if (GetMouse(2).bPressed)
  518.         {
  519.             fStartPanX = fMouseX;
  520.             fStartPanY = fMouseY;
  521.         }
  522.  
  523.         // ...as the mouse moves, the screen location changes. Convert this screen
  524.         // coordinate change into world coordinates to implement the pan. Simples.
  525.         if (GetMouse(2).bHeld)
  526.         {
  527.             fOffsetX -= (fMouseX - fStartPanX) / fScaleX;
  528.             fOffsetY -= (fMouseY - fStartPanY) / fScaleY;
  529.  
  530.             // Start "new" pan for next epoch
  531.             fStartPanX = fMouseX;
  532.             fStartPanY = fMouseY;
  533.         }
  534.  
  535.         // For zoom, we need to extract the location of the cursor before and after the
  536.         // scale is changed. Here we get the cursor and translate into world space...
  537.         float fMouseWorldX_BeforeZoom, fMouseWorldY_BeforeZoom;
  538.         ScreenToWorld(fMouseX, fMouseY, fMouseWorldX_BeforeZoom, fMouseWorldY_BeforeZoom);
  539.  
  540.  
  541.         // ...change the scale as required...
  542.         if (GetKey(olc::Key::UP).bHeld)
  543.         {
  544.             fScaleX *= 1.001f;
  545.             fScaleY *= 1.001f;
  546.         }
  547.  
  548.         if (GetKey(olc::Key::DOWN).bHeld)
  549.         {
  550.             fScaleX *= 0.999f;
  551.             fScaleY *= 0.999f;
  552.         }
  553.  
  554.         // ...now get the location of the cursor in world space again - It will have changed
  555.         // because the scale has changed, but we can offset our world now to fix the zoom
  556.         // location in screen space, because we know how much it changed laterally between
  557.         // the two spatial scales. Neat huh? ;-)
  558.         float fMouseWorldX_AfterZoom, fMouseWorldY_AfterZoom;
  559.         ScreenToWorld(fMouseX, fMouseY, fMouseWorldX_AfterZoom, fMouseWorldY_AfterZoom);
  560.         fOffsetX += (fMouseWorldX_BeforeZoom - fMouseWorldX_AfterZoom);
  561.         fOffsetY += (fMouseWorldY_BeforeZoom - fMouseWorldY_AfterZoom);
  562.  
  563.         // Clear Screen
  564.         FillRect(0, 0, ScreenWidth(), ScreenHeight(), olc::Pixel(0, 255, 0));
  565.  
  566.  
  567.         // Clip
  568.         float fWorldLeft, fWorldTop, fWorldRight, fWorldBottom;
  569.         ScreenToWorld(0, 0, fWorldLeft, fWorldTop);
  570.         ScreenToWorld(ScreenWidth(), ScreenHeight(), fWorldRight, fWorldBottom);
  571.  
  572.  
  573.         for (int i = 0; i < map.Units.size(); i++) {
  574.             if (map.Units[i].sex == 'm')
  575.                 Draw(map.Units[i].x, map.Units[i].y, olc::Pixel(0, 0, 255));
  576.             if (map.Units[i].sex == 'f')
  577.                 Draw(map.Units[i].x, map.Units[i].y, olc::Pixel(255, 203, 219));
  578.         }
  579.         for (int i = 0; i < map.unitsPrevPos.size(); i++) {
  580.             Draw(map.unitsPrevPos[i].x, map.unitsPrevPos[i].y, olc::Pixel(0, 255, 0));
  581.         }
  582.         for (int i = 0; i < map.food.size(); i++) {
  583.             if (map.food[i].isCorpse == true)
  584.                 Draw(map.food[i].x, map.food[i].y, olc::Pixel(0, 0, 0));
  585.             else
  586.                 Draw(map.food[i].x, map.food[i].y, olc::Pixel(255, 0, 0));
  587.         }
  588.         for (int i = 0; i < map.eatenFood.size(); i++) {
  589.             Draw(map.eatenFood[i].x, map.eatenFood[i].y, olc::Pixel(0, 255, 0));
  590.         }
  591.  
  592.         int curHunger = 0;
  593.        
  594.         if (GetMouse(1).bPressed) {
  595.             int curHungerX = GetMouseX();
  596.             int curHungerY = GetMouseY();
  597.             for (int i = 0; i < map.Units.size(); i++) {
  598.                 if (map.Units[i].x == curHungerX and map.Units[i].y == curHungerY or
  599.                     map.Units[i].x == curHungerX + 1 and map.Units[i].y == curHungerY + 1 or
  600.                     map.Units[i].x == curHungerX - 1 and map.Units[i].y == curHungerY -1 or
  601.                     map.Units[i].x == curHungerX + 1 and map.Units[i].y == curHungerY or
  602.                     map.Units[i].x == curHungerX and map.Units[i].y == curHungerY + 1 or
  603.                     map.Units[i].x == curHungerX - 1 and map.Units[i].y == curHungerY or
  604.                     map.Units[i].x == curHungerX and map.Units[i].y == curHungerY - 1) {
  605.                     curHunger = map.Units[i].hunger;
  606.                     rem = i;
  607.                     break;
  608.                 }
  609.             }
  610.         }
  611.         else {
  612.             curHunger = map.Units[rem].hunger;
  613.         }
  614.         DrawStringDecal({ 0, 0 }, "Hunger: " + to_string(curHunger), olc::WHITE, { 0.5, 0.5 });
  615.         DrawStringDecal({ 0, 5 }, "id: " + to_string(rem), olc::WHITE, { 0.5, 0.5 });
  616.        
  617.         ctr = map.goLive(ctr);
  618.  
  619.         Sleep(500);
  620.         return true;
  621.     }
  622. };
  623.  
  624. int main()
  625. {
  626.  
  627.     int screenWidth = 100;
  628.     int screenHeight = 100;
  629.     int pixelSize = 8;
  630.  
  631.     LifeSimulation lifeSimulation;
  632.     if (lifeSimulation.Construct(screenWidth, screenHeight, pixelSize, pixelSize)) {
  633.         lifeSimulation.Start();
  634.     }
  635.  
  636. }
  637.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement