MATLABでMinecraft: Education Editionを遊んでみる

# 概要

私の大学でMATLABのCampus Wide Licenseが契約されて学生・教職員が誰でもMATLABを使えるようになりました！
さらにマイクロソフト教育機関向け総合契約（EES）の学生向け Microsoft 365でMinecraft Education Editionが利用できるようになったのでMATLABでマイクラできたら面白いと思いました。

## 今回の目標
![スクリーンショット 2021-08-17 1.31.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345569/404d12de-fce0-5b77-35e1-46005ffc39d8.png)

エージェントをMATLABで操作して豆腐建築をする！


# 必要なもの
* Windows PC
* [Minecraft Education Edition](https://education.minecraft.net/ja-jp/get-started/download)
* [Code Connection for Minecraft](https://www.microsoft.com/ja-jp/p/code-connection-for-minecraft/9ppfpg2fg2qb)
* [MATLAB](https://jp.mathworks.com/)

# Minecraft: Education Editionのインストール

今回はMinecraft: Education EditionをMATLABでいじっていく

下のリンクからダウンロードして実行
[Minecraft Education Edition](https://education.minecraft.net/ja-jp/get-started/download)

学校で配布されているOffice365にサインインする時と同じメールアドレス、パスワードでサインイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345569/41403d55-7cbf-e473-947a-b381626e3b86.png)

成功すると通常のマイクラと同じような画面になる
![minecraft.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345569/bc4dd5e3-c3e1-98e1-0991-7ffbc5baec45.png)

# Code Connection for Minecraft

Microsoft Storeで[Code Connection for Minecraft](https://www.microsoft.com/ja-jp/p/code-connection-for-minecraft/9ppfpg2fg2qb)をインストールします

起動すると以下のようにコマンドをマイクラで入力しろと求められるので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345569/a10d3b97-4928-3bc3-c9e4-10bd6e9c804a.png)

マイクラでワールドを生成し、キーボードで「t」を押しチャット欄に先程のコマンドを貼り付け実行すると
![agent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345569/e4ef0895-9370-30b5-eb60-a57f39b78a60.png)

エージェントが生成されるので今回はMATLABでこのエージェントを動かして遊んでいきます

# MATLABでエージェントを動かす

皆さん当然インストールしてあるであろうMATLABを起動します
Code ConnectionはAPIがあるのでそれをMATLABで叩くことでエージェントを操作していきます
[Code Builder for Minecraft: Education Edition API Documentation](https://education.minecraft.net/wp-content/uploads/Code_Connection_API.pdf)

MATLABで新規ライブスクリプトを作成します

そして下のコードを実行してみてください

```matlab
url = "http://localhost:8080/move?direction=forward";
res = webread(url);
value = jsondecode(res)
```
エージェントが一歩前に進んだと思います

エージェントがどのように機能するかはurl変数のhttp://localhost:8080/ あとによって決まります。
上記のAPIドキュメントを参考にして、ほしい機能を追加してみてください！

十歩、歩かせる場合はfor文を使って見ましょう

```matlab
s = 10;
for i = 1:s
    url = "http://localhost:8080/move?direction=forward";
    res = webread(url);
    value = jsondecode(res);
end
```

## 関数化
先程の前に進むものを関数化しましょう

```matlab
function f_move
url = "http://localhost:8080/move?direction=forward";
res = webread(url);
value = jsondecode(res);
end
```
こうすることで`f_move;`を実行すると前に進むようになりました

## 豆腐を作るスクリプト



関数をたくさん用意しました

```matlab
% 前に移動する関数
function move_f
    url = "http://localhost:8080/move?direction=forward";
    res = webread(url);
    value = jsondecode(res);
end

% 後ろに移動する関数
function move_b
    url = "http://localhost:8080/move?direction=back";
    res = webread(url);
    value = jsondecode(res);
end

% 右に移動する関数
function move_r
    url = "http://localhost:8080/move?direction=right";
    res = webread(url);
    value = jsondecode(res);
end

% 左に移動する関数
function move_l
    url = "http://localhost:8080/move?direction=left";
    res = webread(url);
    value = jsondecode(res);
end

% 上に移動する関数
function move_u
    url = "http://localhost:8080/move?direction=up";
    res = webread(url);
    value = jsondecode(res);
end

% 下に移動する関数
function move_d
    url = "http://localhost:8080/move?direction=down";
    res = webread(url);
    value = jsondecode(res);
end

% 前にものを置く関数
function place
    url = "http://localhost:8080/place?slotNum=1&direction=forward";
    res = webread(url);
    value = jsondecode(res);
end
```

あとはどのように家を組み立てるかを考えます
僕はfor文をぶん回す力わざを行いましたが、
三次元配列を使うともっとスマートにできると思います。

```matlab
h = 5; % 高さ
w = 6; % 幅
d = 5; % 奥行き

for i = 1:h
    for j = 1:w
        for k = 1:d
            if j == 1
                move_b;
                place;
            elseif j == w
                move_b;
                place;
            elseif k == 1
                move_b;
                place;
            elseif k == d
                move_b;
                place;
            elseif i == h
                move_b;
                place;
            else
                move_b;
            end
        end
        move_r;
        for a = 1:d
            move_f;
        end
    end
    move_u;
    for b = 1:w
        move_l;
    end
end
```

# MATLABっぽい山も作ってみた

![matlogo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345569/72d1ef99-f72f-36f8-f858-3804ddf5a2c8.png)

MATLABっぽい山を自動で作らせてみたよ！（もっとでかくもできたけど時間かかりそうだったから小さい山にしました）

今度は配列を使って山を作るプログラムを作ってみました。
MATLABのlogo関数から9×9のMATLAB山（勝手に命名）を生成し配列にしました。
少し高すぎるので高さを4分の1まで抑えてMATLAB山を生成します

```matlab
% matlab logo
mat_logo = [  -4.1474   -2.2221    1.5828    6.2576   10.0233   10.8842    7.5711    0.4568   -8.2948;
            2.6789    7.2273   13.5919   20.7434   26.6830   28.7386   24.7071   14.4545    0.4568;
            5.9884   11.1152   17.9129   25.9224   33.8068   38.3987   35.8258   24.7071    7.5711;
            4.5416    7.8502   12.2509   18.0703   27.0549   36.8454   38.3987   28.7386   10.8842;
            0.6439    1.0859    1.6770    2.1659    8.3970   27.0549   33.8068   26.6830   10.0233;
           -0.0850   -0.1451   -0.2253   -0.7048    2.1659   18.0703   25.9224   20.7434    6.2576;
                 0         0         0   -0.2253    1.6770   12.2509   17.9129   13.5919    1.5828;
                 0         0         0   -0.1451    1.0859    7.8502   11.1152    7.2273   -2.2221;
                 0         0         0   -0.0850    0.6439    4.5416    5.9884    2.6789   -4.1474]

mat_logo_int = round((mat_logo+4)/4)+1  % 負がめんどくさいので大体正の数にして最後に一段分下駄を履かせてあげる
coler_h = round(max(mat_logo_int,[],"all")/6)   % 高さで色分けをするために高さを分割
for h = 1:max(mat_logo_int,[],"all")    % 最大の高さまで繰り返す
    for i = 1:9
        for j = 1:9
            % 配列の要素より低い位置にいる場合にブロックを置く
            if h < mat_logo_int(i,j)
                % ブロックの色分け
                if h < coler_h
                    place1;
                elseif h < coler_h*2
                    place2;
                elseif h < coler_h*3
                    place3;
                elseif h < coler_h*4
                    place4;
                elseif h < coler_h*5
                    place5;
                else
                    place6;
                end
            end
            move_b;
        end
        move_r;
        for a = 1:9
            move_f;
        end
    end
    move_u;
    for a = 1:9
        move_l;
    end
end
```
新たに色分けを導入しているので新しく関数を用意します

```matlab
function place1
    url = "http://localhost:8080/place?slotNum=1&direction=forward";
    res = webread(url);
    value = jsondecode(res);
end

function place2
    url = "http://localhost:8080/place?slotNum=2&direction=forward";
    res = webread(url);
    value = jsondecode(res);
end

function place3
    url = "http://localhost:8080/place?slotNum=3&direction=forward";
    res = webread(url);
    value = jsondecode(res);
end

function place4
    url = "http://localhost:8080/place?slotNum=4&direction=forward";
    res = webread(url);
    value = jsondecode(res);
end

function place5
    url = "http://localhost:8080/place?slotNum=5&direction=forward";
    res = webread(url);
    value = jsondecode(res);
end

function place6
    url = "http://localhost:8080/place?slotNum=6&direction=forward";
    res = webread(url);
    value = jsondecode(res);
end
```
あとはエージェントに好きな色のブロックをもたせて実行するとカラフルなMATLABのロゴの山が出来上がります！