マインクラフト上に迷路をPythonから自動生成して遊ぶ

# はじめに
マインクラフト上に迷路をPythonから自動で作成して遊ぶ方法について記載します。WindowsとMacの両方で実装が可能です。本記事の内容はYouTubeの動画としても投稿しているので、動画の方がわかりやすい方はYouTubeからご視聴ください。

https://youtu.be/iK3V8q2EiI8

# 準備
## 1. Javaのインストール
Javaをインストールします。以下の画面の「同意して無料ダウンロード開始」ボタンからインストーラーをダウンロードして、インストールしてください。

https://java.com/ja/download/


## 2. マインクラフトの購入
この記事ではマインクラフトのJava Editionを対象にしています。以下のリンクから、マインクラフトJava Editionを選択して購入してください。

購入が完了するとマインクラフトのインストーラーがダウンロードできるので、ダウンロードをしてください。

https://www.minecraft.net/ja-jp/store/minecraft-java-edition

マインクラフトのサイトログインにはマイクロソフトアカウントが必要です。まだ持ってない方は作成してください。

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/d350037e-423f-ce0e-95a5-ff69ab10c611.png">

## 3. マインクラフトのインストール
2.でダウンロードしたインストーラーを起動して、インストールします。起動に成功するとこんなマインクラフトのLauncherが起動します。もしもWindows PCでうまく起動しない場合、Microsoft Storeで [Minecraft Launcher] を検索してインストールしてください。また、Windows PCの場合Xboxのアカウントを作成するように促されるので、作成していない人は作成してください。

<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/5e322902-1d3a-3148-bfa2-c712a7432c92.png">

## 4. Forgeインストール
マインクラフトでMod (拡張機能パッケージ) を使うためのForgeというものをインストールします。今回、1.12.2のバージョンを使用します。以下のURLからインストーラーダウンロード画面を開いてください。

https://files.minecraftforge.net/net/minecraftforge/forge/index_1.16.5.html

「Installer」のボタンを押してください。
<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/0dcc00f8-755a-aa03-442f-138a51b62af2.png">
広告が貼ってあるページの飛びます。5秒ほど待つと右上に「Skip」ボタンが表示されるので、「Skip」ボタンを押してインストーラーをダウンロードしてください。
<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/822d0b57-c772-c025-4a86-f4092a738525.png">
Macの場合は、セキュリティとプライバシーのダウンロードしたアプリケーションの実行許可から開く必要があります。
<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/e68c4630-6828-f329-f0ad-febeec410c90.png">
Forgeのインストーラが起動したら、「Install Client」にチェックが付いていることを確認して、「OK」ボタンを押してインストールしてください。
<img width="300" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/26bbe019-ce45-87f1-0a8b-7f71290ad064.png">


## 5. RaspberryJamModのダウンロード
以下のサイトからRaspberryJamModのzipをダウンロードして解凍します。解凍したフォルダの中に1.12.2のフォルダがあって、その中のjarファイルが今回使用するModになります。

https://github.com/arpruss/raspberryjammod/releases

<img width="500" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/f90e1374-1a1a-8b9f-3227-5147b43e196d.png">

解凍したフォルダの中に1.12.2のフォルダがあって、その中のjarファイルが今回使用するModになります。

<img width="200" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/4e2c4a9c-e044-f0a6-b2db-2ed28c65cb3b.png">


## 6. ワールドの作成
マインクラフトのLauncherを起動して、左のタブのJavaEditionタブを押して、上の起動構成タブを押すと、起動構成の画面が表示されます。

<img width="500" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/6251da2c-65de-281f-1e1a-ac561e491bf5.png">
Forgeのメニューボタンの[編集]ボタンを押します。
<img width="500" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/0ec3e28c-eb08-9f7b-2a99-7e66ad916174.png">
起動構成の編集画面から、ゲームディレクトリの参照ボタンを押して、適当な空フォルダを作って、そのフォルダを選択します。これで保存します。このゲームディレクトリはメモをしておいてください。
<img width="300" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/ff28a667-3e5f-d1cf-7708-fd15b1353c45.png">
起動構成の画面からプレイを押してマインクラフトを起動させます。
<img width="500" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/83a2eb84-c7af-7e50-2d58-ca5afaf471d0.png">
そうすると、こんな画面が表示されてマインクラフトが起動するので、左下に[forge]が記載されていることを確認したら、一旦マインクラフトを終了します。
<img width="500" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/5cd4c467-e841-f4aa-a398-c64bd344fc75.png">
そして、先ほどメモしたゲームディレクトリの中に[mods]というフォルダができているので、そのフォルダの中に5.の手順でダウンロードしたmodのjarファイルを入れます。
<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/70983884-6cec-9c11-a3c0-b53ec12f0914.png">
もう一度、マインクラフトのLauncherを起動して、左のタブのJavaEditionタブを押して、上の起動構成タブを押して、Forgeの[プレイ]ボタンを押して、マインクラフトを起動します。起動した画面の[Mods]ボタンを押します。
<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/0c02596b-359d-a273-0709-a63e5169b4b8.png">
この部分に「Rasberry Jam Mod」って書いてあればOKです。「Done」を押して戻ってください。
<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/21dc9f02-8ff1-df17-4838-a57d049ed8dd.png">
Singleplayerをクリックして、ワールドを選択する画面に移動してください。
<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/c8c88c26-f8f9-f88c-2ae5-27bdfa27437a.png">
Create New Worldボタンを押してください。
<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/34ed6e30-5d4b-1187-4288-440607c3e45e.png">
ワールドの名前を適当につけて、クリエイティブモードに変更して、ワールドを作成してください。
<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/0464a300-5374-8052-bba3-9b3e230ae8f2.png">
これで、マインクラフト側の準備は完了しました。
<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/1d99e43d-9f8e-5aee-be76-a228934376d6.png">



Escキーを押して、一旦、ゲームを抜けてください。

# 迷路を作る
## 1. mcpiをインストール
今度はPython側のライブラリmcpiをインストールします。

https://github.com/martinohanlon/mcpi


```
pip install mcpi
```

mcpiの動作確認として、Pythonからマインクラフトのワールドにチャットを投稿をします。

```python3
from mcpi import minecraft

def main():
    # マインクラフトのオブジェクト作成
    mc = minecraft.Minecraft.create()
    # チャットを投稿
    mc.postToChat('Hello Minecraft World!')

if __name__ == '__main__':
    main()
````

このコードを実行したのち、マインクラフトのゲームに戻ると、以下のようにpostToChatに指定した文字列が投稿されているのが確認できます。
<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/a171c722-179d-e1b3-01a2-2db70a0916c2.png">

## 2. 迷路用の平なスペースを作る

迷路用のスペースを作ります。デフォルトの状態だと、地表が凸凹していて迷路が作りづらいので、平なスペースを確保します。

1. マインクラフトはx座標が東西、y座標が高さ、z座標が南北を表しているので、まずプレーヤを`mc.player.setPos(0, 1, 0)`で、x 座標が 0 ,　y 座標 1 ,　z 座標 0 に移動します。
2. `mc.setBlocks()`でプレーヤーの周りのスペースにあった不要なブロックを削除します。`block.AIR`を使うと何もないブロックが配置されるので、元あったブロックは削除されます。`mc.setBlocks()`は第一引数〜第三引数が、ブロックを配置する開始位置で、第四引数〜第六引数がブロックを配置する終了位置です。その開始位置から終了位置まで全てブロックが敷き詰められます。 第七引数にブロックの種類を指定します。
3. `mc.setBlocks()`でプレーヤーの周りのスペースに草を敷き詰めて、平なスペースを作ります。ブロックの種類は`block.GRASS`にします

```python3
from mcpi import minecraft


def main():
    mc = minecraft.Minecraft.create()

    # 1. プレーヤを移動
    mc.player.setPos(0, 1, 0)

    # 2. 不要なブロックを削除
    mc.setBlocks(
        -3, 0, -3,
        50, 50, 50,
        block.AIR
    )

    # 3. 草のブロックで平なスペースを作成
    mc.setBlocks(
        -3, 0, -3,
        50, 0, 50,
        block.GRASS
    )
```

これをPythonで実行して、またゲームに戻ると、このような平なスペースができています。


<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/1844e333-949b-5ec1-a47b-c6174952bc3b.png">

## 3. mazelibライブラリをインストール
迷路を自動生成するmazelibというライブラリをインストールします

```
pip install mazelib
```

WindowsPCでmazelibがpipでインストールできない場合はMicrosoft Visual C++をインストールして、再度pip install を試してみてください。

https://docs.microsoft.com/ja-JP/cpp/windows/overview-of-windows-programming-in-cpp?view=msvc-170

## 4. 迷路をPython上で生成する
一旦、マインクラフト用のスクリプトとは別に、mazelibの動作を確認するためのPythonスクリプトを用意して、Primsクラスを使って迷路を生成します。

以下のコードを動かすと、迷路を表した文字列が表示されます。

```python3
from mazelib import Maze
from mazelib.generate.Prims import Prims


N = 5 # 縦の通路の数
M = 5 # 横の通路の数

mz = Maze()
mz.generator = Prims(N, M)
# 迷路生成
mz.generate()

# スタートとゴールのマークを設置
mz.start = (0, 1)
mz.end = (N * 2, M * 2 - 1)

print(mz)
```

`#`の部分が壁で、`S`が迷路のスタート、`E`が迷路のゴールです。この文字列から、どのマークがマインクラフト上のx座標とz座標に該当するかマッピングして、`#`ならブロックを置いて、`#`以外ならブロックを置かないようにしたら、迷路が作れそうです。


````
#S#########
# #       #
# # ### ###
#   #     #
# ##### # #
#     # # #
# # ##### #
# #     # #
# # ##### #
# #   #   #
#########E#
```




## 5. 迷路をマインクラフト上に作成する
3.で平なスペースを作った上に、4.で生成した迷路の文字列をもとにしてブロックを置いて迷路を作ります。`put_maze_block`関数はマークが`#`なら座標にブロックをおく関数です。文字列を改行コードでsplitして、1行ずつ、どの位置にどのマークかを調べることでx座標とz座標とマークを取得することができます。

```python3
from mazelib import Maze
from mazelib.generate.Prims import Prims
from mcpi import minecraft, block

N = 5
M = 5
H = 2


def put_maze_block(mc, mark, x_pos, z_pos):
    # マークが#の座標にブロックを置く
    if mark == '#':
        mc.setBlocks(
            x_pos, 0, z_pos,
            x_pos, H, z_pos,
            block.STONE
        )


def main():

    mc = minecraft.Minecraft.create()
    mc.player.setPos(0, 1, 0)

    mc.setBlocks(
        -3, 0, -3,
        50, 50, 50,
        block.AIR
    )

    mc.setBlocks(
        -3, 0, -3,
        50, 0, 50,
        block.GRASS
    )

    mz = Maze()
    mz.generator = Prims(N, M)

    mz.generate()
    mz.start = (0, 1)
    mz.end = (N * 2, M * 2 - 1)
    maze_str = str(mz)
    maze_list = maze_str.split('\n')

    for z, mark_list in enumerate(maze_list):
        for x, mark in enumerate(mark_list):
            put_maze_block(mc, mark, x, z)


if __name__ == '__main__':
    main()
```

これを実行してマインクラフトのワールドに戻ると迷路が作成できています。

<img width="450" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/980200/e1c62ba1-c431-7677-25fa-68368b31f77f.png">

定数で持っている`M`(迷路の縦の通路数)と`N`(迷路の横の通路数)と`H`(迷路の壁の高さ)をもっと大きいものにすると、本格的な迷路が作れます！

また、mazelibで迷路を生成するときに乱数を使っているため、毎回違う迷路が作成できます。スクリプトを動かせば、何度も違う迷路ができて飽きないですね！(いや、飽きるでしょうね...)

# おわり
マインクラフトをPythonから操作できるということで、迷路を作ってみました。アイディア次第で、いろんな建物が作れて面白そうです。

今回はv1.12.2で作りましたが、v1.16.5でも動くモジュールもあります！ぜひ、使ってみてください！！

https://github.com/Naohiro2g/minecraft_remote

また、普段はPythonの初心者向けに基本的な文法の解説などをYouTube上で配信しているので、よければ見てみてください😊

https://www.youtube.com/channel/UC5Kgc_HNzx4GJ-w4QMeeKiQ