diff --git a/include/cpp14/DungeonPaint.hpp b/include/cpp14/DungeonPaint.hpp new file mode 100644 index 0000000..e2eb1aa --- /dev/null +++ b/include/cpp14/DungeonPaint.hpp @@ -0,0 +1,134 @@ +#ifndef INCLUDED_DUNGEON_TEMPLATE_LIBRARY_DUNGEON_PAINT +#define INCLUDED_DUNGEON_TEMPLATE_LIBRARY_DUNGEON_PAINT +//:::::----------::::::::::----------:::::// +// Dungeon Template Library // +// Made by Gaccho. // +// This code is licensed under CC0. // +// wanotaitei@gmail.com // +//:::::----------::::::::::----------:::::// + +#include +#include +#include + +//Dungeon Template Library Namespace +namespace dtl { + + struct BucketBuffer { + std::int_fast32_t left_x{}; + std::int_fast32_t right_x{}; + std::int_fast32_t old_y{}; + std::int_fast32_t y{}; + }; + + //塗りツール + template + class Bucket { + public: + //コンストラクタ + constexpr Bucket() noexcept = default; + template + constexpr explicit Bucket(STL_& stl_, const std::int_fast32_t x_, const std::int_fast32_t y_, const Int_ paint_value_) noexcept { + paint(stl_, x_, y_, paint_value_); + } + private: + template + constexpr void setPoint(STL_& stl_, const std::size_t x_, const std::size_t y_, const Int_ value_) const noexcept { + stl_[y_][x_] = value_; + } + template + constexpr Int_ getPoint(const STL_& stl_, const std::size_t x_, const std::size_t y_) const noexcept { + return stl_[y_][x_]; + } + + template + constexpr void scanLine(const STL_& stl_, std::unique_ptr& buffer_, std::size_t& end_n_, std::int_fast32_t left_x_, const std::int_fast32_t right_x_, const std::int_fast32_t y_, const std::int_fast32_t old_y_, const Int_ value_) const noexcept { + while (left_x_ <= right_x_) { + + for (; left_x_ < right_x_; ++left_x_) + if (getPoint(stl_, left_x_, y_) == value_) break; + if (getPoint(stl_, left_x_, y_) != value_) break; + + buffer_[end_n_].left_x = left_x_; + + for (; left_x_ <= right_x_; ++left_x_) + if (getPoint(stl_, left_x_, y_) != value_) break; + + buffer_[end_n_].right_x = left_x_ - 1; + buffer_[end_n_].y = y_; + buffer_[end_n_].old_y = old_y_; + + if (++end_n_ == stl_[0].size()) end_n_ = 0; + } + } + + public: + template + void paint(STL_& stl_, const std::int_fast32_t x_, const std::int_fast32_t y_, const Int_ paint_value_) const noexcept { + if (stl_.size() == 0 || stl_[0].size() == 0) return; + std::int_fast32_t left_x{}; + std::int_fast32_t right_x{}; + std::int_fast32_t old_y{}; + std::int_fast32_t paint_y{}; + + const Int_ value{ getPoint(stl_, x_, y_) }; + if (value == paint_value_) return; + + const std::int_fast32_t size_max_x{ static_cast(stl_[0].size() - 1) }; + const std::int_fast32_t size_max_y{ static_cast(stl_.size() - 1) }; + std::unique_ptr buffer(new BucketBuffer[stl_[0].size()]); + std::size_t start_n{}; + std::size_t end_n{ 1 }; + std::int_fast32_t left_x_sub_1{}; + std::int_fast32_t right_x_add_1{}; + buffer[start_n].left_x = buffer[start_n].right_x = x_; + buffer[start_n].y = buffer[start_n].old_y = y_; + + do { + left_x = buffer[start_n].left_x; + right_x = buffer[start_n].right_x; + paint_y = buffer[start_n].y; + old_y = buffer[start_n].old_y; + left_x_sub_1 = left_x - 1; + right_x_add_1 = right_x + 1; + if (++start_n == stl_[0].size()) start_n = 0; + + if (getPoint(stl_, left_x, paint_y) != value) continue; + + while (right_x < size_max_x) { + if (getPoint(stl_, right_x + 1, paint_y) != value) break; + ++right_x; + } + + while (left_x > 0) { + if (getPoint(stl_, left_x - 1, paint_y) != value) break; + --left_x; + } + + for (std::int_fast32_t i{ left_x }; i <= right_x; ++i) setPoint(stl_, i, paint_y, paint_value_); + + if (paint_y - 1 >= 0) { + if (paint_y - 1 == old_y) { + scanLine(stl_, buffer, end_n, left_x, left_x_sub_1, paint_y - 1, paint_y, value); + scanLine(stl_, buffer, end_n, right_x_add_1, right_x, paint_y - 1, paint_y, value); + } + else scanLine(stl_, buffer, end_n, left_x, right_x, paint_y - 1, paint_y, value); + } + + if (paint_y + 1 <= size_max_y) { + if (paint_y + 1 == old_y) { + scanLine(stl_, buffer, end_n, left_x, left_x_sub_1, paint_y + 1, paint_y, value); + scanLine(stl_, buffer, end_n, right_x_add_1, right_x, paint_y + 1, paint_y, value); + } + else scanLine(stl_, buffer, end_n, left_x, right_x, paint_y + 1, paint_y, value); + } + + } while (start_n != end_n); + + } + + }; + +} + +#endif //Included Dungeon Template Library \ No newline at end of file diff --git a/include/cpp14/FractalIsland.hpp b/include/cpp14/FractalIsland.hpp index 3062a56..3297327 100644 --- a/include/cpp14/FractalIsland.hpp +++ b/include/cpp14/FractalIsland.hpp @@ -27,7 +27,7 @@ namespace dtl { //ワールドマップ生成 template constexpr void create(STL_& world_map, std::size_t seed_ = 0, const std::int_fast32_t max_value_ = 255) const noexcept { - if (seed_ == 0) seed_ = (std::size_t)rnd(0xffff); + if (seed_ == 0) seed_ = static_cast(rnd(0xffff)); std::array, 17> map_{ {} }; //横画面サイズ @@ -44,14 +44,14 @@ namespace dtl { for (std::size_t i{}; i < chunk_x; ++i) for (std::size_t j{}; j < chunk_y; ++j) { //四角形の4点の高さを決定 - rnd.seed((std::uint_fast32_t)(seed_ + i + (j * aslib_world_make_seed1) + ((i^j) * aslib_world_make_seed2))); - map_[0][0] = (Int_)rnd(max_value_); - rnd.seed((std::uint_fast32_t)(seed_ + ((i + 1) % chunk_x) + (j * aslib_world_make_seed1) + ((((i + 1) % chunk_x) ^ j) * aslib_world_make_seed2))); - map_[16][0] = (Int_)rnd(max_value_); - rnd.seed((std::uint_fast32_t)(seed_ + i + (((j + 1) % chunk_y) * aslib_world_make_seed1) + ((i ^ ((j + 1) % chunk_y)) * aslib_world_make_seed2))); - map_[0][16] = (Int_)rnd(max_value_); - rnd.seed((std::uint_fast32_t)(seed_ + ((i + 1) % chunk_x) + (((j + 1) % chunk_y) * aslib_world_make_seed1) + ((((i + 1) % chunk_x) ^ ((j + 1) % chunk_y)) * aslib_world_make_seed2))); - map_[16][16] = (Int_)rnd(max_value_); + rnd.seed(static_cast(seed_ + i + (j * aslib_world_make_seed1) + ((i^j) * aslib_world_make_seed2))); + map_[0][0] = static_cast(rnd(max_value_)); + rnd.seed(static_cast(seed_ + ((i + 1) % chunk_x) + (j * aslib_world_make_seed1) + ((((i + 1) % chunk_x) ^ j) * aslib_world_make_seed2))); + map_[16][0] = static_cast(rnd(max_value_)); + rnd.seed(static_cast(seed_ + i + (((j + 1) % chunk_y) * aslib_world_make_seed1) + ((i ^ ((j + 1) % chunk_y)) * aslib_world_make_seed2))); + map_[0][16] = static_cast(rnd(max_value_)); + rnd.seed(static_cast(seed_ + ((i + 1) % chunk_x) + (((j + 1) % chunk_y) * aslib_world_make_seed1) + ((((i + 1) % chunk_x) ^ ((j + 1) % chunk_y)) * aslib_world_make_seed2))); + map_[16][16] = static_cast(rnd(max_value_)); //チャンク生成 worldMapSimple(map_, max_value_); @@ -67,21 +67,21 @@ namespace dtl { //再起の終了処理 if (size_ == 0) return; //頂点の高さを決める - const std::size_t vertex_height{ ((t1_ + t2_ + t3_ + t4_) / 4) + (std::size_t)rnd((std::int_fast32_t)size_) }; - map_[x_][y_] = ((vertex_height >= max_value_) ? (Int_)max_value_ : (Int_)vertex_height); + const std::size_t vertex_height{ ((t1_ + t2_ + t3_ + t4_) / 4) + static_cast(rnd(static_cast(size_))) }; + map_[x_][y_] = ((vertex_height >= max_value_) ? static_cast(max_value_) : static_cast(vertex_height)); //四角形の2点同士の中点の高さを決定 const std::size_t s1{ ((t1_ + t2_) / 2) }; const std::size_t s2{ ((t1_ + t3_) / 2) }; const std::size_t s3{ ((t2_ + t4_) / 2) }; const std::size_t s4{ ((t3_ + t4_) / 2) }; //4つの地点の座標を決める - map_[x_ + size_][y_] = (Int_)s3; - map_[x_ - size_][y_] = (Int_)s2; - map_[x_][y_ + size_] = (Int_)s4; - map_[x_][y_ - size_] = (Int_)s1; + map_[x_ + size_][y_] = static_cast(s3); + map_[x_ - size_][y_] = static_cast(s2); + map_[x_][y_ + size_] = static_cast(s4); + map_[x_][y_ - size_] = static_cast(s1); //分割サイズを半分にする - const std::size_t& size{ size_ / (std::size_t)2 }; + const std::size_t& size{ size_ / static_cast(2) }; //4つに分割 worldMapMake(x_ - size, y_ - size, size, t1_, s1, s2, map_[x_][y_], map_, max_value_); worldMapMake(x_ + size, y_ - size, size, s1, t2_, map_[x_][y_], s3, map_, max_value_);