From 0938b139812a7ef8a47c6316a770403f52a93c66 Mon Sep 17 00:00:00 2001
From: namark <namark@disroot.org>
Date: Fri, 4 Oct 2019 03:05:59 +0400
Subject: [PATCH] Bonus example 03 - unnatural order

---
 examples/bonus_03_unnatural_order.cpp | 152 ++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)
 create mode 100644 examples/bonus_03_unnatural_order.cpp

diff --git a/examples/bonus_03_unnatural_order.cpp b/examples/bonus_03_unnatural_order.cpp
new file mode 100644
index 0000000..79789e6
--- /dev/null
+++ b/examples/bonus_03_unnatural_order.cpp
@@ -0,0 +1,152 @@
+#include <cstdio>
+#include <cerrno>
+#include <chrono>
+#include <thread>
+#include <algorithm>
+#include <random>
+
+#include "simple/graphical/initializer.h"
+#include "simple/graphical/software_window.h"
+#include "simple/graphical/algorithm.hpp"
+#include "simple/support/algorithm.hpp"
+#include "simple/support/misc.hpp"
+
+using namespace simple::graphical;
+using namespace std::chrono_literals;
+using namespace simple::graphical::color_literals;
+
+using simple::support::advance_vector;
+using simple::support::range;
+
+// dumb sort
+// smarter sorts don't work
+template <typename It>
+void selection_sort(It begin, It end)
+{
+	for(auto i = begin; i != end; ++i)
+	{
+		auto min = i;
+		for(auto j = i+1; j != end; ++j)
+			if(*j < *min)
+				min = j;
+		std::swap(*i, *min);
+	}
+}
+
+// dumb equal range
+// smarter one below works, but not as well
+template <typename It>
+range<It> equal_range(It begin, It end)
+{
+	auto i = begin+1;
+	for(;i != end &&
+		(
+			!(*i < *(begin))
+			&&
+			!(*(begin) < *i)
+		);
+	++i)
+	{}
+	return {begin,i};
+}
+
+// template <typename It>
+// range<It> equal_range(It begin, It end)
+// {
+// 	auto r = std::equal_range(begin, end, *begin);
+// 	return {r.first,r.second};
+// }
+
+int main(int argc, char** argv) try
+{
+
+	initializer init;
+
+	int2 size{};
+	auto flags = window::flags::borderless;
+
+	using simple::support::ston;
+	if(argc == 2)
+	{
+		size = int2::one(ston<int>(argv[1]));
+	}
+	else if(argc > 2)
+	{
+		size = int2{
+			ston<int>(argv[1]),
+			ston<int>(argv[2])
+		};
+	}
+	else
+	{
+		std::puts("Running in fullscreen mode. This could take a logn time...\n");
+		flags = flags | window::flags::fullscreen_desktop;
+	}
+
+	software_window win("unnatural order", size, flags);
+
+	std::vector<int2> points;
+
+	// generate all points
+	auto i = int2::zero();
+	auto dimension = i.begin();
+	while(dimension != i.end())
+	{
+		points.push_back(i);
+		dimension = advance_vector(i, int2::zero(), win.size());
+	}
+
+	// if you skip this, selection sort has no effect
+    std::shuffle(points.begin(), points.end(), std::mt19937(std::random_device{}()));
+
+	selection_sort(points.begin(), points.end());
+
+	surface canvas(win.surface().size(), pixel_format(pixel_format::type::rgb24));
+	auto pixels = std::get<pixel_writer<rgb_pixel, surface::byte>>(canvas.pixels());
+
+	auto colors = std::array{
+		0x000000_rgb,
+		0x111111_rgb,
+		0x222222_rgb,
+		0x333333_rgb,
+		0x444444_rgb,
+		0x555555_rgb,
+		0x666666_rgb,
+		0x777777_rgb,
+		0x888888_rgb,
+		0x999999_rgb,
+		0xaaaaaa_rgb,
+		0xbbbbbb_rgb,
+		0xcccccc_rgb,
+		0xdddddd_rgb,
+		0xeeeeee_rgb,
+		0xffffff_rgb};
+	int color_index = 0;
+	for(auto i = points.begin(); i != points.end();
+		std::this_thread::sleep_for(100ms))
+	{
+		auto range = equal_range(i, points.end());
+		for(auto point : range)
+			pixels.set( colors[color_index], point );
+		i = range.end();
+		color_index = (color_index + 1) % colors.size();
+		blit(canvas, win.surface());
+		win.update();
+	}
+
+	canvas.save("unnatural_order.bmp");
+	std::this_thread::sleep_for(3313ms);
+
+	return 0;
+}
+catch(...)
+{
+	if(errno)
+		std::perror("ERROR");
+
+	const char* sdl_error = SDL_GetError();
+	if(*sdl_error)
+		std::puts(sdl_error);
+
+	throw;
+}
-- 
GitLab