bonus_03_unnatural_order.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <cstdio>
  2. #include <cerrno>
  3. #include <chrono>
  4. #include <thread>
  5. #include <algorithm>
  6. #include <random>
  7. #include "simple/graphical/initializer.h"
  8. #include "simple/graphical/software_window.h"
  9. #include "simple/graphical/algorithm/blit.h"
  10. #include "simple/support/algorithm.hpp"
  11. #include "simple/support/misc.hpp"
  12. using namespace simple::graphical;
  13. using namespace std::chrono_literals;
  14. using namespace simple::graphical::color_literals;
  15. using simple::support::advance_vector;
  16. using simple::support::range;
  17. // dumb sort
  18. // smarter sorts don't work
  19. template <typename It>
  20. void selection_sort(It begin, It end)
  21. {
  22. for(auto i = begin; i != end; ++i)
  23. {
  24. auto min = i;
  25. for(auto j = i+1; j != end; ++j)
  26. if(*j < *min)
  27. min = j;
  28. std::swap(*i, *min);
  29. }
  30. }
  31. // dumb equal range
  32. // smarter one below works, but not as well
  33. template <typename It>
  34. range<It> equal_range(It begin, It end)
  35. {
  36. auto i = begin+1;
  37. for(;i != end &&
  38. (
  39. !(*i < *(begin))
  40. &&
  41. !(*(begin) < *i)
  42. );
  43. ++i)
  44. {}
  45. return {begin,i};
  46. }
  47. // template <typename It>
  48. // range<It> equal_range(It begin, It end)
  49. // {
  50. // auto r = std::equal_range(begin, end, *begin);
  51. // return {r.first,r.second};
  52. // }
  53. int main(int argc, char** argv) try
  54. {
  55. initializer init;
  56. int2 size{};
  57. auto flags = window::flags::borderless;
  58. using simple::support::ston;
  59. if(argc == 2)
  60. {
  61. size = int2::one(ston<int>(argv[1]));
  62. }
  63. else if(argc > 2)
  64. {
  65. size = int2{
  66. ston<int>(argv[1]),
  67. ston<int>(argv[2])
  68. };
  69. }
  70. else
  71. {
  72. std::puts("Running in fullscreen mode. This could take a long time...\n");
  73. flags = flags | window::flags::fullscreen_desktop;
  74. }
  75. software_window win("unnatural order", size, flags);
  76. std::vector<int2> points;
  77. // generate all points
  78. auto i = int2::zero();
  79. auto dimension = i.begin();
  80. while(dimension != i.end())
  81. {
  82. points.push_back(i);
  83. dimension = advance_vector(i, int2::zero(), win.size());
  84. }
  85. // if you skip this, selection sort has no effect
  86. std::shuffle(points.begin(), points.end(), std::mt19937(std::random_device{}()));
  87. selection_sort(points.begin(), points.end());
  88. surface canvas(win.surface().size(), pixel_format(pixel_format::type::rgb24));
  89. auto pixels = std::get<pixel_writer<rgb_pixel, surface::byte>>(canvas.pixels());
  90. auto colors = std::array{
  91. 0x000000_rgb,
  92. 0x111111_rgb,
  93. 0x222222_rgb,
  94. 0x333333_rgb,
  95. 0x444444_rgb,
  96. 0x555555_rgb,
  97. 0x666666_rgb,
  98. 0x777777_rgb,
  99. 0x888888_rgb,
  100. 0x999999_rgb,
  101. 0xaaaaaa_rgb,
  102. 0xbbbbbb_rgb,
  103. 0xcccccc_rgb,
  104. 0xdddddd_rgb,
  105. 0xeeeeee_rgb,
  106. 0xffffff_rgb};
  107. int color_index = 0;
  108. for(auto i = points.begin(); i != points.end();
  109. std::this_thread::sleep_for(100ms))
  110. {
  111. auto range = equal_range(i, points.end());
  112. for(auto point : range)
  113. pixels.set( colors[color_index], point );
  114. i = range.end();
  115. color_index = (color_index + 1) % colors.size();
  116. blit(canvas, win.surface());
  117. win.update();
  118. }
  119. canvas.save("unnatural_order.bmp");
  120. std::this_thread::sleep_for(3313ms);
  121. return 0;
  122. }
  123. catch(...)
  124. {
  125. if(errno)
  126. std::perror("ERROR");
  127. const char* sdl_error = SDL_GetError();
  128. if(*sdl_error)
  129. std::puts(sdl_error);
  130. throw;
  131. }