地形生成(セルオートマトン法)🌏

# 🌏母なる大地を創造する🌏

![ri.gif](https://qiita-image-store.s3.amazonaws.com/0/213065/bcdfd255-2a8f-f534-1a33-19bad6a347fc.gif)

**今回は世界を創造する禁断の闇魔術について解説します。**

#🌏セルオートマトン法で作成🌏

![ri3](https://qiita-image-store.s3.amazonaws.com/0/213065/a596a821-a6d2-9159-21ae-da971ceff427.gif)
**セルオートマトン法で作成する地形生成の動作**

**世界生成アルゴリズム**はいくつもの種類が存在します。
その中でも今回は**簡易なコードで生成することに長けている"セルオートマトン法"**を使用します。

**その他の代表的なアルゴリズム：["ボロノイ図法の世界自動生成"](https://qiita.com/Gaccho/items/08710de2c57da912b822)・["チャンク中点変位法の世界自動生成"](https://qiita.com/Gaccho/items/2840450460fa6e00a56c)**

#🌏セルオートマトン島生成クラス🌏

セルオートマトン法で島生成を行う**`SimpleCellularAutomatonIsland`**クラスを作成します。

```cpp:クラス名
namespace dtl {
	template<typename Int>
	class SimpleCellularAutomatonIsland;
}
```

**dtl(Dungeon Template Library)名前空間**に作成します。

![jimen.png](https://qiita-image-store.s3.amazonaws.com/0/213065/8ff212c5-075f-a302-f532-12681fa8fd15.png)

ひとまず導入する準備が出来ました。
次は**陸地生成**の部分を作ります。

#🌏陸地の形状を作成🌏

```cpp:セルオートマトン島の生成(public)
template<typename Matrix_>
constexpr void create(Matrix_& matrix_, const std::size_t max_value_ = 2) const noexcept {
	using dtl::random::mersenne_twister_32bit;
	for (std::size_t row{ 1 }; row < matrix_.size() - 1; ++row)
		for (std::size_t col{ 1 }; col < matrix_[row].size() - 1; ++col)
			if (mersenne_twister_32bit.probability()) matrix_[row][col] = 1;
}
```

**`"create関数"`**は**陸地生成**する関数です。

![ri2](https://qiita-image-store.s3.amazonaws.com/0/213065/5e3fbdac-72c6-56cb-65c1-ce41eb4cfbf3.gif)
画面のふち以外の場所にランダムで陸地を設置します。

#🌏地殻変動🌏

```cpp:地殻変動
template<typename Matrix_>
constexpr void create(Matrix_& matrix_, const std::size_t max_value_ = 2) const noexcept {
using dtl::random::mersenne_twister_32bit;
for (std::size_t row{ 1 }; row < matrix_.size() - 1; ++row)
 for (std::size_t col{ 1 }; col < matrix_[row].size() - 1; ++col)
  if (mersenne_twister_32bit.probability()) matrix_[row][col] = 1;
for (std::size_t i{}; i < max_value_; ++i)
 for (std::size_t row{ 1 }; row < matrix_.size() - 1; ++row)
  for (std::size_t col{ 1 }; col < matrix_[row].size() - 1; ++col) {
   if (matrix_[row][col - 1] && matrix_[row][col + 1] && matrix_[row - 1][col] && matrix_[row + 1][col]) matrix_[row][col] = matrix_[row][col + 1];
   else switch (mersenne_twister_32bit(4))
   {
   case 0:matrix_[row][col] = matrix_[row][col - 1]; break;
   case 1:matrix_[row][col] = matrix_[row][col + 1]; break;
   case 2:matrix_[row][col] = matrix_[row - 1][col]; break;
   case 3:matrix_[row][col] = matrix_[row + 1][col]; break;
  }
 }
}
```

![ri3](https://qiita-image-store.s3.amazonaws.com/0/213065/a596a821-a6d2-9159-21ae-da971ceff427.gif)
地殻変動を起こし、陸地を移動させます。

# 🌏地殻変動をループする🌏

![a](https://github.com/Kasugaccho/DungeonPicture/raw/master/Picture/2D/random/ri_fade_out.gif)

ただひたすら地殻変動を起こします。
良さそうな地形になった時に止めます。

地殻変動の最後は全てが海の底へ沈みます。

# 🌏CUIとして出力🌏

```cpp:cui
#include <array>
#include "DTL.hpp"

int main() {
	using dungeon_t = bool;
	std::array<std::array<dungeon_t, 128>, 128> matrix{ {} };
	dtl::generator::terrain::stl::SimpleCellularAutomatonIsland<dungeon_t> a(matrix,200);
	dtl::console::output::stl::stringBool(matrix, "##", "//");
	return 0;
}
```

<a href="https://github.com/Kasugaccho/DungeonTemplateLibrary"><img src="https://qiita-image-store.s3.amazonaws.com/0/213065/431dbdfc-2513-4fa9-4e1d-76475681ac0b.png" width="256px"></a>
コンソールから出力できました！


# 🌏完成🌏

無事に実装できました。

![ri.gif](https://qiita-image-store.s3.amazonaws.com/0/213065/bcdfd255-2a8f-f534-1a33-19bad6a347fc.gif)

# [🌏実装ライブラリ(ソースコード)🌏](https://github.com/Kasugaccho/DungeonTemplateLibrary)

今回解説した洞窟の自動生成は**["Dungeon Template Library"](https://github.com/Kasugaccho/DungeonTemplateLibrary)**に**["Simple Cellular Automaton Island"](https://github.com/Kasugaccho/DungeonTemplateLibrary/blob/master/README.md#17-roguelike-cave-v0125)**として実装されています。
ぜひ、活用してみてください！

[![logo640.gif](https://qiita-image-store.s3.amazonaws.com/0/213065/b84a7834-2042-6704-fbbe-782a31f06091.gif)](https://github.com/Kasugaccho/DungeonTemplateLibrary)


# 🌏ソースコードのライセンス🌏

These codes are licensed under CC0.
[![CC0](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg "CC0")](http://creativecommons.org/publicdomain/zero/1.0/deed.ja)

この記事のソースコードはCC0ライセンスとします。
ぜひ、自由に改変して遊んでみてください。

**最後までお読みいただきありがとうございました！**