Projekty z kursu Systemy operacyjne 2 na PWr
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include <cstdlib>
  2. #include <ctime>
  3. #include <iostream>
  4. #include <string>
  5. #include <thread>
  6. #include <vector>
  7. #include <ncurses.h>
  8. #include <unistd.h>
  9. #include "Brick.h"
  10. #include "Platform.h"
  11. #include "Stopwatch.h"
  12. const int gameTime = 120;
  13. int xMax, yMax;
  14. bool refreshing = false;
  15. bool climate = false;
  16. std::vector<Brick> bricks;
  17. Platform platform;
  18. Stopwatch gameClock;
  19. // "Monitor" function
  20. void refreshScreen()
  21. {
  22. while(refreshing == true)
  23. {
  24. Scene::ncursesMutex.lock();
  25. clear();
  26. for(int i = 0; i < bricks.size(); i++)
  27. {
  28. // Easter egg (1)
  29. if(climate)
  30. {
  31. attron(COLOR_PAIR(bricks[i].getColor()));
  32. mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "*");
  33. attroff(COLOR_PAIR(bricks[i].getColor()));
  34. }
  35. else
  36. {
  37. attron(COLOR_PAIR(bricks[i].getColor()));
  38. mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "#");
  39. attroff(COLOR_PAIR(bricks[i].getColor()));
  40. }
  41. }
  42. attron(COLOR_PAIR(platform.getColor()));
  43. mvprintw(yMax - 2, platform.getPosition(), platform.getSprite());
  44. attroff(COLOR_PAIR(platform.getColor()));
  45. mvprintw(yMax - 1, 0, "%.3f", gameClock.read());
  46. mvprintw(yMax - 1, xMax - 3, "%.3d", Scene::getPoints());
  47. refresh();
  48. Scene::ncursesMutex.unlock();
  49. // Refresh every 0.01 s
  50. usleep(10000);
  51. }
  52. }
  53. int main(int argc, char *argv[])
  54. {
  55. std::vector<std::thread> brickThreads;
  56. srand(time(0));
  57. // Easter egg (2)
  58. if(argc == 2)
  59. {
  60. std::string param(argv[1]);
  61. if(param == "--globalwarming")
  62. {
  63. climate = true;
  64. }
  65. }
  66. // Initialize ncurses
  67. initscr();
  68. curs_set(0);
  69. getmaxyx(stdscr, yMax, xMax);
  70. // Initialize colors
  71. start_color();
  72. init_pair(1, COLOR_RED, COLOR_BLACK);
  73. init_pair(2, COLOR_GREEN, COLOR_BLACK);
  74. init_pair(3, COLOR_YELLOW, COLOR_BLACK);
  75. init_pair(4, COLOR_BLUE, COLOR_BLACK);
  76. init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
  77. init_pair(6, COLOR_CYAN, COLOR_BLACK);
  78. // Non-blocking input for platform-movement
  79. timeout(0);
  80. // Initialize scene
  81. Scene::init(xMax, yMax);
  82. Brick::setPlatform(&platform);
  83. // Initialize all bricks...
  84. for(int i = 0; i < xMax; i++)
  85. {
  86. // ...with random descent rate in range 0 (slow) to 15 (fast)
  87. Brick brick(i, rand() % 16);
  88. bricks.push_back(brick);
  89. }
  90. // Start monitor
  91. refreshing = true;
  92. std::thread monitor(refreshScreen);
  93. // Start platform treads
  94. std::thread platformMover(platform.moveKeyThread());
  95. std::thread platformColorChanger(platform.colorChangeThread());
  96. // Start game
  97. gameClock.start();
  98. while(gameClock.read() < gameTime)
  99. {
  100. // Freeze game
  101. if(Scene::isFreezed() == true)
  102. {
  103. std::unique_lock<std::mutex> freezeLock(Scene::freezeMutex);
  104. while(Scene::isFreezed() == true)
  105. {
  106. Scene::freezeCondition.wait(freezeLock);
  107. }
  108. }
  109. // Determine random brick...
  110. int randBrick = rand() % xMax;
  111. while(bricks.at(randBrick).isFalling())
  112. {
  113. // ...which still isn't falling down...
  114. randBrick = rand() % xMax;
  115. }
  116. // ...and launch it with nuclear-powered hammer ;-)
  117. brickThreads.push_back(bricks.at(randBrick).fallThread());
  118. // Random time in range 400 to 800 ms until next fall
  119. unsigned randTime = rand() % 4 + 4;
  120. usleep(100000 * randTime);
  121. }
  122. // Stop clock
  123. gameClock.stop();
  124. // Stop scene objects threads
  125. Scene::terminateAll();
  126. platformMover.join();
  127. platformColorChanger.join();
  128. for(int i = 0; i < brickThreads.size(); i++)
  129. {
  130. brickThreads.at(i).join();
  131. }
  132. // Stop monitor
  133. refreshing = false;
  134. monitor.join();
  135. sleep(1);
  136. // Close ncurses
  137. endwin();
  138. std::cout << "Your score: " << Scene::getPoints() << " points" << std::endl;
  139. if(Scene::getPoints() != 0)
  140. {
  141. std::cout << "Congratulations!" << std::endl;
  142. }
  143. std::cout << std::endl;
  144. std::cout << "BRIcks-ng Caban Kernel-thread System Next Generation v1.0" << std::endl;
  145. std::cout << "Jan Potocki 2018" << std::endl;
  146. std::cout << "(beerware)" << std::endl;
  147. std::cout << std::endl;
  148. std::cout << '"' << "...Back around that Halloween," << std::endl;
  149. std::cout << "Microsoft said open source would never last," << std::endl;
  150. std::cout << "But now they use the repo tools," << std::endl;
  151. std::cout << "In the same open access way..." << '"' << std::endl;
  152. std::cout << "(and recently acquired GitHub)" << std::endl;
  153. std::cout << std::endl;
  154. // Easter egg (3)
  155. if(climate)
  156. {
  157. std::cout << "SEVERE WEATHER ALERT: major snowfall predicted in 48h forecast for Lower Silesia, south-western Poland" << std::endl;
  158. std::cout << "Global warming affecting again!... ;-)" << std::endl;
  159. }
  160. else
  161. {
  162. std::cout << "Beware of BRICKS! ;-)" << std::endl;
  163. }
  164. return 0;
  165. }