Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <ncurses.h>
- #include <thread>
- #include <unistd.h>
- #include <vector>
- #include <random>
- #include <mutex>
- #include <condition_variable>
- #define BALL 'o'
- #define SCREEN_REFRESH 100000
- class Ball;
- struct point;
- void init();
- void removeOldBalls();
- void moveBall(Ball* ball, point direction);
- void print();
- void quit();
- void checkESC();
- point randomDirection();
- void addBall();
- int main();
- struct point {
- int x;
- int y;
- };
- unsigned long seed = (unsigned long)(time(nullptr)); //randomizer seed
- std::mt19937_64 rng(seed); //random number generator
- std::uniform_int_distribution<int> randInt(-3, 3);
- point max_size = {0, 0}; //window size
- point start = {0, 1}; //balls start point
- bool finish = false;
- std::vector < Ball* > balls; //ball vector
- std::vector < std::thread* > thBalls; //thread vector
- std::condition_variable cv;
- std::condition_variable cv2;
- int max_balls = 12;
- int ballInBox = 0;
- bool ready = false;
- std::mutex mtx;
- std::mutex mtx2;
- class Ball {
- public:
- Ball() {
- position = start;
- }
- point getPosition(){
- return(position);
- }
- void setPosition(point nPosition) {
- position = nPosition;
- }
- bool isDeleteFlag() const {
- return deleteFlag;
- }
- void setDeleteFlag(bool deleteFlag) {
- Ball::deleteFlag = deleteFlag;
- }
- void show(){
- mvaddch(position.y, position.x, BALL);
- }
- bool isInBox = false;
- bool checkBox() {
- if(getPosition().x > (max_size.x * 2 / 3) || getPosition().x < (max_size.x / 3)) {
- isInBox = true;
- ballInBox++;
- return true;
- }
- else
- return false;
- }
- private:
- point position;
- bool deleteFlag;
- };
- //ncurses init
- void init() {
- initscr();
- noecho();
- curs_set(0);
- getmaxyx( stdscr, max_size.y, max_size.x );
- start.x = max_size.x/2;
- }
- //function that removes old balls
- void removeOldBalls() {
- for(unsigned int i = 0; i < balls.size(); i++) {
- if(balls.at(i)->isDeleteFlag()) {
- thBalls.erase(thBalls.begin()+i);
- balls.erase(balls.begin()+i);
- }
- }
- }
- //function that is moving balls
- void moveBall(Ball* ball, point direction) {
- unsigned int sleepTime = 100000;
- do {
- ball->setPosition(point{ ball->getPosition().x+direction.x, ball->getPosition().y+direction.y });
- usleep(sleepTime);
- if(ball->checkBox()) {
- std::unique_lock<std::mutex> lck(mtx);
- if(ballInBox >= 4) {
- cv.wait(lck, [] {return ready;});
- }
- ready = false;
- cv.notify_one();
- lck.unlock();
- }
- //check left or right boundary
- if (ball->getPosition().x >= (max_size.x-1) || ball->getPosition().x <= 1) {
- direction.x = -direction.x;
- sleepTime *= 2;
- }
- //check top or bottom boundary
- if (ball->getPosition().y >= (max_size.y-1) || ball->getPosition().y <= 1) {
- direction.y = -direction.y;
- sleepTime *= 2;
- }
- } while (sleepTime <= 800000 && !finish);
- ball->setDeleteFlag(true);
- removeOldBalls();
- }
- //print function
- void print() {
- while (!finish) {
- refresh();
- usleep(SCREEN_REFRESH);
- clear();
- for(int i=0;i<max_size.y;i++) {
- mvaddch(i,(max_size.x)/3,'|');
- mvaddch(i,2*(max_size.x)/3,'|');
- }
- for (auto &ball : balls) {
- ball->show();
- }
- }
- quit();
- clear();
- mvprintw(0, 0, "KONIEC DZIALANIA PROGRAMU");
- refresh();
- sleep(3);
- }
- //function finishing the program
- void quit()
- {
- for (auto &ball : thBalls) {
- ball->join();
- }
- balls.clear();
- thBalls.clear();
- }
- //function checking if ESC is pressed
- void checkESC() {
- while(getch() != 27) {
- }
- finish = true;
- }
- //randomizer for ball direction
- point randomDirection() {
- point dir = {0,0};
- dir.x = randInt(rng);
- dir.y = 1;
- return dir;
- }
- //function adding new ball
- void addBall() {
- Ball *ball = new Ball();
- balls.push_back(ball);
- std::thread *th = new std::thread (moveBall, ball, randomDirection());
- thBalls.push_back(th);
- sleep(2);
- }
- int main() {
- init();
- std::thread ending(checkESC); //thread for checking if ESC is pressed
- std::thread screen(print); //thread for printing
- while(!finish) {
- addBall();
- }
- ending.join();
- screen.join();
- sleep(2);
- endwin();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement