From 21e234d27395eb0bf3c905079035d2498294297d Mon Sep 17 00:00:00 2001 From: Kasugaccho <30593725+Kasugaccho@users.noreply.github.com> Date: Tue, 8 Jan 2019 20:57:50 +0900 Subject: [PATCH] add include cpp14 --- include/cpp14/BoardGame.hpp | 270 ++++++++++++++++++++++++++++++ include/cpp14/DTL.hpp | 7 +- include/cpp14/DungeonPaint.hpp | 16 ++ include/cpp14/DungeonStandard.hpp | 170 +++++++++++++++++++ include/cpp14/RogueLike.hpp | 34 ++-- 5 files changed, 479 insertions(+), 18 deletions(-) create mode 100644 include/cpp14/BoardGame.hpp diff --git a/include/cpp14/BoardGame.hpp b/include/cpp14/BoardGame.hpp new file mode 100644 index 0000000..1ceb6aa --- /dev/null +++ b/include/cpp14/BoardGame.hpp @@ -0,0 +1,270 @@ +#ifndef INCLUDED_DUNGEON_TEMPLATE_LIBRARY_BOARD_GAME +#define INCLUDED_DUNGEON_TEMPLATE_LIBRARY_BOARD_GAME +//:::::----------::::::::::----------:::::// +// Dungeon Template Library // +// Made by Gaccho. // +// This code is licensed under CC0. // +// wanotaitei@gmail.com // +//:::::----------::::::::::----------:::::// + +#include +#include +#include +#include + +//Dungeon Template Library Namespace +namespace dtl { + + //指定した場所に駒を置く + template + std::size_t putPieceReversi(STL_& stl_, const std::size_t x_, const std::size_t y_, const Int_ turn_, const bool is_put_) noexcept { + if (stl_.size() == 0) return 0; + std::size_t piece_turn_num{}; + if (stl_[y_][x_] > 0) return 0; + + std::unique_ptr stl_tmp_x(new std::int_fast32_t[stl_[0].size()]); + std::unique_ptr stl_tmp_y(new std::int_fast32_t[stl_.size()]); + + for (std::int_fast32_t y{ -1 }; y <= 1; ++y) + for (std::int_fast32_t x{ -1 }; x <= 1; ++x) { + for (std::size_t i{}; i < stl_[0].size(); ++i) stl_tmp_x[i] = 0; + for (std::size_t i{}; i < stl_.size(); ++i) stl_tmp_y[i] = 0; + for (std::size_t turn_tmp_id{};; ++turn_tmp_id) { + std::int_fast32_t turn_x{ static_cast(x_) + x * (static_cast(turn_tmp_id) + 1) }; + std::int_fast32_t turn_y{ static_cast(y_) + y * (static_cast(turn_tmp_id) + 1) }; + if (turn_x < 0 || turn_x >= stl_[0].size() || turn_y < 0 || turn_y >= stl_.size() || stl_[turn_y][turn_x] == 0) break; + if (stl_[turn_y][turn_x] == turn_) { + if (is_put_) + for (std::size_t i{}; i < turn_tmp_id; ++i) + stl_[static_cast(stl_tmp_y[i])][static_cast(stl_tmp_x[i])] = turn_; + piece_turn_num += turn_tmp_id; + break; + } + stl_tmp_x[turn_tmp_id] = turn_x; stl_tmp_y[turn_tmp_id] = turn_y; + } + } + if (piece_turn_num > 0 && is_put_) stl_[y_][x_] = turn_; + return piece_turn_num; + } + //パスの有無 + template + constexpr bool isPassReversi(STL_& stl_, const Int_ turn_) noexcept { + for (std::size_t i{}; i < stl_.size(); ++i) + for (std::size_t j{}; j < stl_[i].size(); ++j) + if (putPieceReversi(stl_, j, i, turn_, false)) return false; + return true; + } + //最初に見つけた置ける場所を選ぶ + template + constexpr bool reversiAI_Simple(STL_& stl_, const Int_ turn_) noexcept { + for (std::size_t i{}; i < stl_.size(); ++i) + for (std::size_t j{}; j < stl_[i].size(); ++j) + if (putPieceReversi(stl_, j, i, turn_, true)) return true; + return true; + } + //最も多くの駒が取れる場所を選ぶ + template + constexpr bool reversiAI_Greed(STL_& stl_, const Int_ turn_) noexcept { + std::size_t piece_turn_max{}; + std::size_t put_piece_x{}, put_piece_y{}; + for (std::size_t i{}; i < stl_.size(); ++i) + for (std::size_t j{}; j < stl_[i].size(); ++j) { + const auto& num{ putPieceReversi(stl_, j,i, turn_, false) }; + if (piece_turn_max < num || (piece_turn_max == num && dtl::rnd.randBool())) { + piece_turn_max = num; + put_piece_x = j; + put_piece_y = i; + } + } + putPieceReversi(stl_, put_piece_x, put_piece_y, turn_, true); + return true; + } + //最も少なく駒が取れる場所を選ぶ + template + constexpr bool reversiAI_Unselfishness(STL_& stl_, const Int_ turn_) noexcept { + std::size_t piece_turn_min{ std::numeric_limits::max() }; + std::size_t put_piece_x{}, put_piece_y{}; + for (std::size_t i{}; i < stl_.size(); ++i) + for (std::size_t j{}; j < stl_[i].size(); ++j) { + const auto& num{ putPieceReversi(stl_, j,i, turn_, false) }; + if (num > 0 && (piece_turn_min > num || (piece_turn_min == num && dtl::rnd.randBool()))) { + piece_turn_min = num; + put_piece_x = j; + put_piece_y = i; + } + } + putPieceReversi(stl_, put_piece_x, put_piece_y, turn_, true); + return true; + } + //優先順位 + constexpr std::int_fast32_t checkPriorityReversi(std::int_fast32_t x_, std::int_fast32_t y_, const std::int_fast32_t x_max_, const std::int_fast32_t y_max_) noexcept { + if (x_ == x_max_) x_ = 0; + else if (x_ == x_max_ - 1) x_ = 1; + else if (x_ == x_max_ - 2) x_ = 2; + if (y_ == y_max_) y_ = 0; + else if (y_ == y_max_ - 1) y_ = 1; + else if (y_ == y_max_ - 2) y_ = 2; + switch (x_) + { + case 0: + switch (y_) + { + case 0:return 0; + case 1:return 6; + case 2:return 2; + default:return 1; + } + case 1: + switch (y_) + { + case 0:return 6; + case 1:return 6; + case 2:return 6; + default:return 4; + } + case 2: + switch (y_) + { + case 0:return 2; + case 1:return 5; + case 2:return 2; + default:return 3; + } + } + switch (y_) + { + case 0:return 1; + case 1:return 4; + case 2:return 3; + default:return 3; + } + return 0; + } + //優先順位の高い場所を選ぶ + template + constexpr bool reversiAI_Priority(STL_& stl_, const Int_ turn_) noexcept { + std::size_t piece_turn_max{}; + std::size_t put_piece_x{}, put_piece_y{}; + for (std::uint_fast8_t piece_priority{}; piece_priority < 7 && piece_turn_max == 0; ++piece_priority) + for (std::size_t i{}; i < stl_.size(); ++i) + for (std::size_t j{}; j < stl_[i].size(); ++j) { + if (checkPriorityReversi(static_cast(j), static_cast(i), static_cast(stl_[i].size()) - 1, static_cast(stl_.size()) - 1) != piece_priority) continue; + const auto& num{ putPieceReversi(stl_, j, i, turn_, false) }; + if (piece_turn_max < num || (piece_turn_max == num && dtl::rnd.randBool())) { + piece_turn_max = num; + put_piece_x = j; + put_piece_y = i; + } + } + putPieceReversi(stl_, put_piece_x, put_piece_y, turn_, true); + return true; + } + //AI同士をまとめる関数 + template + constexpr bool reversiAI(STL_& stl_, const Int_ turn_, bool(*black_ai_)(STL_&, const Int_), bool(*white_ai_)(STL_&, const Int_), const bool is_black_ai_) noexcept { + return (is_black_ai_) ? black_ai_(stl_, turn_) : white_ai_(stl_, turn_); + } + + template + constexpr std::int_fast32_t checkResultReversi(STL_& stl_) noexcept { + std::array piece_num{ {} }; + std::int_fast32_t result{}; + for (std::size_t i{}; i < stl_.size(); ++i) + for (std::size_t j{}; j < stl_[i].size(); ++j) + if (stl_[i][j] > 0) ++piece_num[stl_[i][j] - 1]; + if (isPassReversi(stl_, (Int_)1) && isPassReversi(stl_, (Int_)2)) { + if (piece_num[0] > piece_num[1]) result = 1; + else if (piece_num[0] < piece_num[1]) result = 2; + else result = 3; + } + return result; + } + + enum :std::size_t { + reversi_empty, + reversi_white, + reversi_black + }; + //リバーシを初期化する + template + constexpr void createReversi(STL_& stl_, const Int_ black_ = 2, const Int_ white_ = 1) noexcept { + if (stl_.size() < 2 || stl_[0].size() < 2) return; + const std::size_t& set_y{ stl_.size() / 2 }; + const std::size_t& set_x{ stl_[0].size() / 2 }; + stl_[set_y - 1][set_x - 1] = white_; + stl_[set_y - 1][set_x] = black_; + stl_[set_y][set_x - 1] = black_; + stl_[set_y][set_x] = white_; + } + template + class Reversi { + public: + //コンストラクタ + constexpr Reversi() noexcept = default; + template + constexpr explicit Reversi(STL_& stl_, const Int_ black_ = 2, const Int_ white_ = 1) noexcept { + create(stl_, black_, white_); + } + template + constexpr void create(STL_& stl_, const Int_ black_ = 2, const Int_ white_ = 1) noexcept { + createReversi(stl_, black_, white_); + } + }; + + enum :std::size_t { + shogi_empty, + shogi_next_place1, + shogi_next_place2, + //王将&玉将 + shogi_osho, + shogi_gyokusho, + //金将 + shogi_kinsho1, + shogi_kinsho2, + + //ここより先は成る。---------------------------------------- + + //飛車 + shogi_hisha1, + shogi_ryuo1, + shogi_hisha2, + shogi_ryuo2, + //角行 + shogi_kakugyo1, + shogi_ryuma1, + shogi_kakugyo2, + shogi_ryuma2, + + //ここより先は成ると金と同じ動きになる。-------------------- + + //銀将 + shogi_ginsho1, + shogi_narigin1, + shogi_ginsho2, + shogi_narigin2, + //桂馬 + shogi_keima1, + shogi_narikei1, + shogi_keima2, + shogi_narikei2, + //香車 + shogi_kyosha1, + shogi_narikyo1, + shogi_kyosha2, + shogi_narikyo2, + //歩兵 + shogi_fuhyo1, + shogi_tokin1, + shogi_fuhyo2, + shogi_tokin2 + }; + + template + constexpr bool isShogiNarikin(const Int_ koma_) noexcept { + if (koma_ >= shogi_ginsho1 && shogi_narigin1 % 2 == koma_ % 2) return true; + return false; + } + +} + +#endif //Included Dungeon Template Library \ No newline at end of file diff --git a/include/cpp14/DTL.hpp b/include/cpp14/DTL.hpp index 6c26380..21b396a 100644 --- a/include/cpp14/DTL.hpp +++ b/include/cpp14/DTL.hpp @@ -7,18 +7,23 @@ // wanotaitei@gmail.com // //:::::----------::::::::::----------:::::// - +//�֘A�c�[�� #include "DungeonBinarization.hpp" #include "DungeonNoise.hpp" #include "DungeonOutput.hpp" #include "DungeonRandom.hpp" #include "DungeonStandard.hpp" +//�����n #include "FractalIsland.hpp" #include "MazeDig.hpp" #include "RogueLike.hpp" #include "SimpleRogueLike.hpp" #include "SimpleTerrain1.hpp" #include "SimpleVoronoiIsland.hpp" +#include "BoardGame.hpp" + +//�ύX�c�[�� +#include "DungeonPaint.hpp" #endif //Included Dungeon Template Library \ No newline at end of file diff --git a/include/cpp14/DungeonPaint.hpp b/include/cpp14/DungeonPaint.hpp index e2eb1aa..00d451b 100644 --- a/include/cpp14/DungeonPaint.hpp +++ b/include/cpp14/DungeonPaint.hpp @@ -21,6 +21,22 @@ namespace dtl { std::int_fast32_t y{}; }; + // + template + class Pen { + public: + //コンストラクタ + constexpr Pen() noexcept = default; + template + constexpr explicit Pen(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_); + } + template + constexpr void paint(STL_& stl_, const std::int_fast32_t x_, const std::int_fast32_t y_, const Int_ paint_value_) const noexcept { + stl_[y_][x_] = paint_value_; + } + }; + //塗りツール template class Bucket { diff --git a/include/cpp14/DungeonStandard.hpp b/include/cpp14/DungeonStandard.hpp index f314d12..6a6223f 100644 --- a/include/cpp14/DungeonStandard.hpp +++ b/include/cpp14/DungeonStandard.hpp @@ -12,6 +12,156 @@ //Dungeon Template Library Namespace namespace dtl { + // + template + constexpr void createPointGrid(STL_& stl_) noexcept { + for (std::size_t i{}; i < stl_.size(); i += 2) + for (std::size_t j{}; j < stl_[i].size(); j += 2) + stl_[i][j] = 1; + } + template + constexpr void createPointGrid(STL_& stl_, const Int_ value_) noexcept { + for (std::size_t i{}; i < stl_.size(); i += 2) + for (std::size_t j{}; j < stl_[i].size(); j += 2) + stl_[i][j] = value_; + } + //クラス版 + template + class PointGrid { + public: + //コンストラクタ + constexpr PointGrid() noexcept = default; + template + constexpr explicit PointGrid(STL_& stl_, const Int_ value_ = 1) noexcept { + create(stl_, value_); + } + template + constexpr void create(STL_& stl_, const Int_ value_ = 1) noexcept { + createPointGrid(stl_, value_); + } + }; + + //外枠(内部を奇数マスにする) + template + constexpr void createBorderOdd(STL_& stl_) noexcept { + if (stl_.size() < 2) return; + for (std::size_t i{}; i < stl_[0].size(); ++i) + stl_[0][i] = 1; + if (stl_.size() % 2 == 1) { + for (std::size_t i{}; i < stl_[stl_.size() - 1].size(); ++i) + stl_[stl_.size() - 1][i] = 1; + } + else for (std::size_t i{}; i < stl_[stl_.size() - 1].size(); ++i) { + stl_[stl_.size() - 2][i] = 1; + stl_[stl_.size() - 1][i] = 1; + } + for (std::size_t i{}; i < stl_.size(); ++i) { + if (stl_[i].size() < 2) continue; + stl_[i][0] = 1; + if (stl_[i].size() % 2 == 0) stl_[i][stl_[i].size() - 2] = 1; + stl_[i][stl_[i].size() - 1] = 1; + } + } + template + constexpr void createBorderOdd(STL_& stl_, const Int_ value_) noexcept { + if (stl_.size() < 2) return; + for (std::size_t i{}; i < stl_[0].size(); ++i) + stl_[0][i] = value_; + if (stl_.size() % 2 == 1) { + for (std::size_t i{}; i < stl_[stl_.size() - 1].size(); ++i) + stl_[stl_.size() - 1][i] = value_; + } + else for (std::size_t i{}; i < stl_[stl_.size() - 1].size(); ++i) { + stl_[stl_.size() - 2][i] = value_; + stl_[stl_.size() - 1][i] = value_; + } + for (std::size_t i{}; i < stl_.size(); ++i) { + if (stl_[i].size() < 2) continue; + stl_[i][0] = value_; + if (stl_[i].size() % 2 == 0) stl_[i][stl_[i].size() - 2] = value_; + stl_[i][stl_[i].size() - 1] = value_; + } + } + //クラス版 + template + class BorderOdd { + public: + //コンストラクタ + constexpr BorderOdd() noexcept = default; + template + constexpr explicit BorderOdd(STL_& stl_, const Int_ value_ = 1) noexcept { + create(stl_, value_); + } + template + constexpr void create(STL_& stl_, const Int_ value_ = 1) noexcept { + createBorderOdd(stl_, value_); + } + }; + + //クラス版 + template + class PointGridField { + public: + //コンストラクタ + constexpr PointGridField() noexcept = default; + template + constexpr explicit PointGridField(STL_& stl_, const Int_ value_ = 1) noexcept { + create(stl_, value_); + } + template + constexpr void create(STL_& stl_, const Int_ value_ = 1) noexcept { + createPointGrid(stl_, value_); + createBorderOdd(stl_, value_); + } + }; + + //Border + template + constexpr void createBorder(STL_& stl_) noexcept { + if (stl_.size() == 0) return; + for (std::size_t i{}; i < stl_.front().size(); ++i) + stl_.front()[i] = 1; + for (std::size_t i{}; i < stl_.back().size(); ++i) + stl_.back()[i] = 1; + for (std::size_t i{}; i < stl_.size(); ++i) { + if (stl_[i].size() == 0) continue; + stl_[i].front() = 1; + stl_[i].back() = 1; + } + } + template + constexpr void createBorder(STL_& stl_, const Int_ value_) noexcept { + if (stl_.size() == 0) return; + for (std::size_t i{}; i < stl_.front().size(); ++i) + stl_.front()[i] = value_; + for (std::size_t i{}; i < stl_.back().size(); ++i) + stl_.back()[i] = value_; + for (std::size_t i{}; i < stl_.size(); ++i) { + if (stl_[i].size() == 0) continue; + stl_[i].front() = value_; + stl_[i].back() = value_; + } + } + //クラス版 + template + class Border { + public: + //コンストラクタ + constexpr Border() noexcept = default; + template + constexpr explicit Border(STL_& stl_, const Int_ value_ = 1) noexcept { + create(stl_, value_); + } + template + constexpr void create(STL_& stl_, const Int_ value_ = 1) noexcept { + createBorder(stl_, value_); + } + }; + + //----------*----------*----------*----------*----------* + //初期化系 + //----------*----------*----------*----------*----------* + //全てのマスを0で埋める template constexpr void dungeonInit(STL_& stl_) noexcept { @@ -26,6 +176,22 @@ namespace dtl { for (std::size_t j{}; j < stl_[i].size(); ++j) stl_[i][j] = value_; } + //クラス版 + template + class DungeonInit { + public: + //コンストラクタ + constexpr DungeonInit() noexcept = default; + template + constexpr explicit DungeonInit(STL_& stl_, const Int_ value_ = 0) noexcept { + create(stl_, value_); + } + template + constexpr void create(STL_& stl_, const Int_ value_ = 0) noexcept { + dungeonInit(stl_, value_); + } + }; + //全てのマスを0で埋める template constexpr void dungeonInit_RangeBasedFor(STL_& stl_) noexcept { @@ -41,6 +207,10 @@ namespace dtl { j = value_; } + //----------*----------*----------*----------*----------* + //初期化系 + //----------*----------*----------*----------*----------* + template constexpr bool dungeonArrayCheckBitset(const STL_& stl_) noexcept { if (stl_.size() < 1 || stl_[0].size() < 1) return false; diff --git a/include/cpp14/RogueLike.hpp b/include/cpp14/RogueLike.hpp index d2068d8..0a232e1 100644 --- a/include/cpp14/RogueLike.hpp +++ b/include/cpp14/RogueLike.hpp @@ -15,8 +15,8 @@ namespace dtl { //四角形の位置と大きさ template - struct Rect { - Rect() = default; + struct RogueLikeRect { + RogueLikeRect() = default; //位置 Int_ x{}, y{}; //大きさ @@ -45,12 +45,12 @@ namespace dtl { //コンストラクタ constexpr RogueLike() noexcept = default; template - constexpr explicit RogueLike(STL_& stl_, const std::size_t way_max_) noexcept { + constexpr explicit RogueLike(STL_& stl_, const std::size_t way_max_ = 20) noexcept { create(stl_, way_max_); } //マップ生成 template - constexpr void create(STL_& stl_, const std::size_t way_max_) noexcept { + constexpr void create(STL_& stl_, const std::size_t way_max_ = 20) noexcept { room_rect.clear(); branch_point.clear(); //最初の部屋を生成 @@ -62,9 +62,9 @@ namespace dtl { private: //部屋の位置情報 - std::vector> room_rect; + std::vector> room_rect; //部屋または通路の生成可能な面の位置情報 - std::vector> branch_point; + std::vector> branch_point; //タイルを取得 template @@ -131,7 +131,7 @@ namespace dtl { constexpr std::int_fast32_t minRoomSize{ 3 }; constexpr std::int_fast32_t maxRoomSize{ 6 }; - Rect room; + RogueLikeRect room; room.w = rnd(minRoomSize, maxRoomSize); room.h = rnd(minRoomSize, maxRoomSize); @@ -157,13 +157,13 @@ namespace dtl { if (placeRect(stl_, room, room_id)) { room_rect.emplace_back(room); if (dir_ != direction_south || firstRoom_) //上 - branch_point.emplace_back(Rect{ room.x, room.y - 1, room.w, 1 }); + branch_point.emplace_back(RogueLikeRect{ room.x, room.y - 1, room.w, 1 }); if (dir_ != direction_north || firstRoom_) //下 - branch_point.emplace_back(Rect{ room.x, room.y + room.h, room.w, 1 }); + branch_point.emplace_back(RogueLikeRect{ room.x, room.y + room.h, room.w, 1 }); if (dir_ != direction_east || firstRoom_) //左 - branch_point.emplace_back(Rect{ room.x - 1, room.y, 1, room.h }); + branch_point.emplace_back(RogueLikeRect{ room.x - 1, room.y, 1, room.h }); if (dir_ != direction_west || firstRoom_) //右 - branch_point.emplace_back(Rect{ room.x + room.w, room.y, 1, room.h }); + branch_point.emplace_back(RogueLikeRect{ room.x + room.w, room.y, 1, room.h }); return true; } return false; @@ -173,7 +173,7 @@ namespace dtl { constexpr std::int_fast32_t minWayLength{ 3 }; constexpr std::int_fast32_t maxWayLength{ 15 }; - Rect way; + RogueLikeRect way; way.x = x_; way.y = y_; @@ -220,17 +220,17 @@ namespace dtl { } if (!placeRect(stl_, way, way_id)) return false; if (dir_ != direction_south && way.w != 1)//上 - branch_point.emplace_back(Rect{ way.x, way.y - 1, way.w, 1 }); + branch_point.emplace_back(RogueLikeRect{ way.x, way.y - 1, way.w, 1 }); if (dir_ != direction_north && way.w != 1)//下 - branch_point.emplace_back(Rect{ way.x, way.y + way.h, way.w, 1 }); + branch_point.emplace_back(RogueLikeRect{ way.x, way.y + way.h, way.w, 1 }); if (dir_ != direction_east && way.h != 1)//左 - branch_point.emplace_back(Rect{ way.x - 1, way.y, 1, way.h }); + branch_point.emplace_back(RogueLikeRect{ way.x - 1, way.y, 1, way.h }); if (dir_ != direction_west && way.h != 1)//右 - branch_point.emplace_back(Rect{ way.x + way.w, way.y, 1, way.h }); + branch_point.emplace_back(RogueLikeRect{ way.x + way.w, way.y, 1, way.h }); return true; } template - constexpr bool placeRect(STL_& stl_, const Rect& rect, const Int_ tile_) noexcept { + constexpr bool placeRect(STL_& stl_, const RogueLikeRect& rect, const Int_ tile_) noexcept { if (rect.x < 1 || rect.y < 1 || rect.x + rect.w >(std::int_fast32_t)((stl_.empty()) ? 0 : stl_.front().size()) - 1 || rect.y + rect.h >(std::int_fast32_t)(stl_.size()) - 1) return false; for (std::int_fast32_t y = rect.y; y < rect.y + rect.h; ++y)