Advertisement
Guest User

Untitled

a guest
May 21st, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.94 KB | None | 0 0
  1. #include <iostream>
  2. #include <ncurses.h>
  3. #include <thread>
  4. #include <unistd.h>
  5. #include <vector>
  6. #include <random>
  7. #include <mutex>
  8. #include <condition_variable>
  9.  
  10. #define BALL 'o'
  11. #define SCREEN_REFRESH 100000
  12.  
  13. class Ball;
  14. struct point;
  15. void init();
  16. void removeOldBalls();
  17. void moveBall(Ball* ball, point direction);
  18. void print();
  19. void quit();
  20. void checkESC();
  21. point randomDirection();
  22. void addBall();
  23. int main();
  24.  
  25. struct point {
  26.     int x;
  27.     int y;
  28. };
  29.  
  30. unsigned long seed = (unsigned long)(time(nullptr));    //randomizer seed
  31. std::mt19937_64 rng(seed);                              //random number generator
  32. std::uniform_int_distribution<int> randInt(-3, 3);
  33. point max_size = {0, 0};                                //window size
  34. point start = {0, 1};                                   //balls start point
  35. bool finish = false;
  36. std::vector < Ball* > balls;                            //ball vector
  37. std::vector < std::thread* > thBalls;                   //thread vector
  38.  
  39. std::condition_variable cv;
  40. std::condition_variable cv2;
  41. int max_balls = 12;
  42. int ballInBox = 0;
  43. bool ready = false;
  44.  
  45.  
  46. std::mutex mtx;
  47. std::mutex mtx2;
  48.  
  49.  
  50. class Ball {
  51.     public:
  52.         Ball() {
  53.             position = start;
  54.         }
  55.  
  56.         point getPosition(){
  57.            return(position);
  58.         }
  59.         void setPosition(point nPosition) {
  60.             position = nPosition;
  61.         }
  62.         bool isDeleteFlag() const {
  63.             return deleteFlag;
  64.         }
  65.         void setDeleteFlag(bool deleteFlag) {
  66.             Ball::deleteFlag = deleteFlag;
  67.         }
  68.         void show(){
  69.             mvaddch(position.y, position.x, BALL);
  70.         }
  71.  
  72.         bool isInBox = false;
  73.  
  74.         bool checkBox() {
  75.             if(getPosition().x > (max_size.x * 2 / 3) || getPosition().x < (max_size.x / 3)) {
  76.                 isInBox = true;
  77.                 ballInBox++;
  78.                 return true;
  79.             }
  80.             else
  81.                 return false;
  82.         }
  83.  
  84.     private:
  85.         point position;
  86.         bool deleteFlag;
  87.  
  88. };
  89.  
  90. //ncurses init
  91. void init() {
  92.     initscr();
  93.     noecho();
  94.     curs_set(0);
  95.     getmaxyx( stdscr, max_size.y, max_size.x );
  96.     start.x = max_size.x/2;
  97. }
  98.  
  99. //function that removes old balls
  100. void removeOldBalls() {
  101.     for(unsigned int i = 0; i < balls.size(); i++) {
  102.         if(balls.at(i)->isDeleteFlag()) {
  103.             thBalls.erase(thBalls.begin()+i);
  104.             balls.erase(balls.begin()+i);
  105.         }
  106.     }
  107. }
  108.  
  109. //function that is moving balls
  110. void moveBall(Ball* ball, point direction) {
  111.     unsigned int sleepTime = 100000;
  112.     do {
  113.  
  114.         ball->setPosition(point{ ball->getPosition().x+direction.x, ball->getPosition().y+direction.y });
  115.         usleep(sleepTime);
  116.  
  117.  
  118.         if(ball->checkBox()) {
  119.             std::unique_lock<std::mutex> lck(mtx);
  120.             if(ballInBox >= 4) {
  121.                 cv.wait(lck, [] {return ready;});
  122.             }
  123.             ready = false;
  124.             cv.notify_one();
  125.             lck.unlock();
  126.         }
  127.  
  128.         //check left or right boundary
  129.         if (ball->getPosition().x >= (max_size.x-1) || ball->getPosition().x <= 1) {
  130.             direction.x = -direction.x;
  131.             sleepTime *= 2;
  132.         }
  133.         //check top or bottom boundary
  134.         if (ball->getPosition().y >= (max_size.y-1) || ball->getPosition().y <= 1) {
  135.             direction.y = -direction.y;
  136.             sleepTime *= 2;
  137.         }
  138.     } while (sleepTime <= 800000 && !finish);
  139.     ball->setDeleteFlag(true);
  140.     removeOldBalls();
  141. }
  142.  
  143. //print function
  144. void print() {
  145.  
  146.  
  147.  
  148.     while (!finish) {
  149.         refresh();
  150.         usleep(SCREEN_REFRESH);
  151.         clear();
  152.         for(int i=0;i<max_size.y;i++) {
  153.             mvaddch(i,(max_size.x)/3,'|');
  154.             mvaddch(i,2*(max_size.x)/3,'|');
  155.         }
  156.  
  157.         for (auto &ball : balls) {
  158.             ball->show();
  159.         }
  160.     }
  161.  
  162.     quit();
  163.     clear();
  164.     mvprintw(0, 0, "KONIEC DZIALANIA PROGRAMU");
  165.     refresh();
  166.     sleep(3);
  167. }
  168.  
  169. //function finishing the program
  170. void quit()
  171. {
  172.     for (auto &ball : thBalls) {
  173.         ball->join();
  174.     }
  175.     balls.clear();
  176.     thBalls.clear();
  177. }
  178.  
  179. //function checking if ESC is pressed
  180. void checkESC() {
  181.     while(getch() != 27) {
  182.  
  183.     }
  184.     finish = true;
  185.  
  186. }
  187.  
  188. //randomizer for ball direction
  189. point randomDirection() {
  190.     point dir = {0,0};
  191.     dir.x = randInt(rng);
  192.     dir.y = 1;
  193.     return dir;
  194. }
  195.  
  196. //function adding new ball
  197. void addBall() {
  198.         Ball *ball = new Ball();
  199.         balls.push_back(ball);
  200.         std::thread *th = new std::thread (moveBall, ball, randomDirection());
  201.         thBalls.push_back(th);
  202.         sleep(2);
  203. }
  204.  
  205. int main() {
  206.     init();
  207.  
  208.     std::thread ending(checkESC); //thread for checking if ESC is pressed
  209.     std::thread screen(print); //thread for printing
  210.     while(!finish) {
  211.         addBall();
  212.     }
  213.  
  214.  
  215.  
  216.     ending.join();
  217.     screen.join();
  218.     sleep(2);
  219.  
  220.     endwin();
  221.     return 0;
  222. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement