From 3c725d105eecc4e20264849983c039b0164dc0ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20H=C3=B6rdt?= <6329417-neop_@users.noreply.gitlab.com> Date: Sat, 3 Aug 2024 22:06:57 +0200 Subject: [PATCH] naive rendering of random walk points --- main.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/main.cpp b/main.cpp index 6b36601..9558607 100644 --- a/main.cpp +++ b/main.cpp @@ -2,10 +2,13 @@ #include +#include #include +#include #include #include #include +#include template struct sdl_wrapper_t : std::unique_ptr { @@ -19,13 +22,18 @@ using window_t = sdl_wrapper_t; using surface_t = sdl_wrapper_t; using renderer_t = sdl_wrapper_t; -struct Point { - int x; - int y; -}; +auto operator+(SDL_Point a, SDL_Point b) { + return SDL_Point{.x = a.x + b.x, .y = a.y + b.y}; +} -auto operator+(Point a, Point b) { - return Point{.x = a.x + b.x, .y = a.y + b.y}; +auto operator<=>(const SDL_Point& a, const SDL_Point& b) { + auto y_comp = a.x <=> b.x; + if (y_comp != std::strong_ordering::equal) { return y_comp; } + return a.y <=> b.y; +} + +auto operator==(const SDL_Point& a, const SDL_Point& b) { + return a.x == b.x && a.y == b.y; } constexpr int width = 3440; @@ -59,8 +67,10 @@ int main() { auto surface = surface_t{SDL_GetWindowSurface(window)}; - auto point = Point{.x = width / 2, .y = height / 2}; - const Point directions[] = { + std::vector points; + SDL_Point pos{.x = width / 2, .y = height / 2}; + points.push_back(pos); + const SDL_Point directions[] = { {.x = -1, .y = 0}, {.x = 1, .y = 0}, {.x = 0, .y = -1}, @@ -68,28 +78,69 @@ int main() { }; std::mt19937_64 rne(std::random_device{}()); - std::uniform_int_distribution dist(0, 3); + std::uniform_int_distribution dist(0, 3); - bool quit = false; - auto next_frame = std::chrono::steady_clock::now(); - while (!quit) { - SDL_RenderDrawPoint(renderer, point.x, point.y); - Point newpoint; - do { - newpoint = point + directions[dist(rne)]; - } while (newpoint.x < 0 or newpoint.x >= width or newpoint.y < 0 or - newpoint.y >= height); - point = newpoint; + bool continu = true; + const auto start = std::chrono::steady_clock::now(); + auto next_frame = start; + long total_points = 0; + while (continu) { + { + SDL_Point newpoint; + do { + newpoint = pos + directions[dist(rne)]; + } while (newpoint.x < 0 or newpoint.x >= width or + newpoint.y < 0 or newpoint.y >= height); + pos = newpoint; + points.push_back(newpoint); + ++total_points; + } + const auto goal = 200'000'000; + if (total_points >= goal) { + continu = false; + std::println( + "took {} to get to {} random steps", + std::chrono::duration_cast>( + std::chrono::steady_clock::now() - start + ), + goal + ); + } - if (std::chrono::steady_clock::now() > next_frame) { + // render present; poll events + auto render_start = std::chrono::steady_clock::now(); + if (render_start > next_frame) { next_frame += std::chrono::milliseconds{200}; + { + std::ranges::sort(points, std::less<>{}); + auto [first, last] = std::ranges::unique(points); + points.resize(std::ranges::distance(points.begin(), first)); + } + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderDrawPoints( + renderer, points.data(), std::ssize(points) + ); + SDL_RenderPresent(renderer); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + SDL_Event e; while (SDL_PollEvent(&e)) { - if (e.type == SDL_QUIT) { quit = true; } + if (e.type == SDL_QUIT) { continu = false; } + } + + auto render_end = std::chrono::steady_clock::now(); + + std::println( + "drawn {} points in {}", std::ssize(points), + std::chrono::duration_cast( + render_end - render_start + ) + ); + if (render_end > next_frame) { + next_frame = render_end + std::chrono::milliseconds{100}; } - SDL_RenderPresent(renderer); - // SDL_RenderClear(renderer); } } }