From d916d1c3830775068d1bf2becabb03c340665651 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Thu, 19 Dec 2024 19:02:27 -0500 Subject: [PATCH] A very jank circle algorithm that overdraws many of the lines but mostly works. --- assets/config.json | 2 +- matrix.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++ matrix.hpp | 16 ++++++++++++++ status.txt | 9 ++------ tests/matrix.cpp | 22 ++++++++++++++++++++ 5 files changed, 93 insertions(+), 8 deletions(-) diff --git a/assets/config.json b/assets/config.json index d4b2c97..141dcb9 100644 --- a/assets/config.json +++ b/assets/config.json @@ -5,7 +5,7 @@ "PLAYER_TILE": "\ua66b", "ENEMY_TILE": "\u1d5c", "BG_TILE": "█", - "WATER_TILE": "\u26c6" + "WATER_TILE": "\u224b" }, "enemy": { "HEARING_DISTANCE": 8 diff --git a/matrix.cpp b/matrix.cpp index 6701a46..eb6996a 100644 --- a/matrix.cpp +++ b/matrix.cpp @@ -179,6 +179,58 @@ namespace matrix { } } + + circle::circle(Point center, int radius) : + center(center), radius(radius) + { + xi = 0; + yi = radius; + m = 5 - 4 * radius; + step = 0; + } + + void circle::update() { + if(m > 0) { + yi--; + m -= 8 * yi; + } + xi++; + m += 8 * xi + 4; + } + + bool circle::next() { + if(xi <= yi) { + switch(step % 4) { + case 0: + x0 = center.x - xi; + y = center.y - yi; + x1 = center.x + xi; + break; + case 1: + x0 = center.x - yi; + y = center.y - xi; + x1 = center.x + yi; + break; + case 2: + x0 = center.x - yi; + y = center.y + xi; + x1 = center.x + yi; + break; + case 3: + x0 = center.x - xi; + y = center.y + yi; + x1 = center.x + xi; + update(); + break; + } + + step++; + return true; + } else { + return false; + } + } + void dump(const std::string &msg, Matrix &map, int show_x, int show_y) { println("----------------- {}", msg); diff --git a/matrix.hpp b/matrix.hpp index acb475e..97425e8 100644 --- a/matrix.hpp +++ b/matrix.hpp @@ -108,4 +108,20 @@ namespace matrix { line(Point start, Point end); bool next(); }; + + struct circle { + Point center; + int radius = 0; + int xi = 0; + int yi = 0; + int m = 0; + int step = 0; + int x0; + int x1; + int y; + + circle(Point center, int radius); + void update(); + bool next(); + }; } diff --git a/status.txt b/status.txt index e7dcbf6..c0d2cea 100644 --- a/status.txt +++ b/status.txt @@ -5,23 +5,18 @@ TODAY'S GOAL: * Flame pillars icon \u2e3e * Room should always be found. -* Change the test matrix to be irregular dimensions. * Study https://github.com/hirdrac/gx_lib/blob/main/gx/Unicode.hh * Study this https://en.cppreference.com/w/cpp/language/explicit * Study https://en.cppreference.com/w/cpp/language/member_functions#Special_member_functions -* Light should flood using the dijkstra map rather than use a box. - -1. Learn std::initializer_list by using it. 0. \ua3fd causes the character immediately after to vanish. Make a test and solve it. 1. Why do Sliders only have to be kept around forever and can't go in containers like everything else? -* Make a for-loop generator thing, and figure out whatever this magic matrix-processing-without-for-loops tech is (that probably doesn't exist). - -"you could make an iterator type that you create with the Matrix & a box - then it iterates though each row/column and updates its x/y values. More code over all but loops like you're doing now could be simpler" - TODO: +* Add a char lookup input to the designer. + * Make the light directional. * Hot key for debug view. diff --git a/tests/matrix.cpp b/tests/matrix.cpp index d708525..7d9c94b 100644 --- a/tests/matrix.cpp +++ b/tests/matrix.cpp @@ -224,3 +224,25 @@ TEST_CASE("prototype line algorithm", "[matrix:line]") { REQUIRE(f_found); } } + +TEST_CASE("prototype circle algorithm", "[matrix:circle]") { + size_t width = Random::uniform(10, 13); + size_t height = Random::uniform(10, 15); + Map map(width,height); + // create a target for the paths + Point start{.x=map.width() / 2, .y=map.height()/2}; + + for(int radius = 2; radius < 5; radius++) { + // use an empty map + Matrix result = map.walls(); + + for(matrix::circle it{start, radius}; it.next();) { + println("y={}, x0={}, x1={}", it.y, it.x0, it.x1); + for(int i = it.x0; i < it.x1; i++) { + result[it.y][i] += 1; + } + } + + matrix::dump("RESULT AFTER CIRCLE", result, start.x, start.y); + } +}