Minecraft Command ひっかけクイズ

この記事は [Minecraft Command Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mccmd "Minecraft Command Advent Calendar 2023") N日目の記事です。
## はじめに
今まさにMinecraftのコマンドを学ぼうと頑張っている人に向けて、少しでも為になる記事を書きたいと思ったのですが、ただ情報を連ねていくだけでは読者が飽きてしまいそうなので、私が実際にコマンドを学んでいる最中に引っかかってしまった「罠」をクイズ形式にして幾つか出題することにしました。
コマンドを学び始めたそこの貴方や、コマンドに自信があるそこの貴方も良ければ挑戦していってください。
ちなみにこのクイズは [Minecraft wiki](https://minecraft.wiki/ "Minecraft wiki") 持ち込み可能となっていますので解答が分からなくてもガンガン調べてもらって構いません。
また実行環境は最新バージョンである 1.20.2 です。

## Q1 （初心者向け）
以下のコマンドをチャットで実行した際の実行結果を言葉で説明しなさい。

```
/tp @s ^ ^ ^2
```

<details><summary>ヒント</summary>
Z座標が変わるだけやんって思った人はちょっと待って！　この「^」マークの意味を調べてみよう。
</details>

<details><summary>解答</summary>

正解は向いている方向 **2m前方** にテレポートする、でした。

![tp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629850/fa6573b0-6218-a145-78a7-12b9c6e39ddc.gif)

Minecraftの座標の表記方法には絶対座標表記、チルダ表記、キャレット表記の3パターンがあり、今回は三番目のキャレット表記です。キャレット表記の場合は、ローカル座標と言って自分の向いている方向を基準とした座標系になります。なのでZ軸方向に2m進む、ではなく2m前方にテレポートしました。

座標の表記方法に関しては以下のリンクに情報が連ねられているので良かったら確認してみてください。
[Minecraft wiki - 座標](https://minecraft.fandom.com/wiki/Coordinates "Minecraft wiki - 座標")

</details>

## Q2 （初心者向け）
以下のコマンドをチャットで実行した際の実行結果を言葉で説明しなさい。

```
/tp @e[type=zombie,distance=..10] ~ ~2 ~
```

<details><summary>ヒント</summary>

これ、実はセレクター`@e`に関する問題かと思いきや根本的なところに引っ掛け要素があります。

</details>

<details><summary>解答</summary>

正解は自分を中心とした半径10mの範囲内にいるゾンビ全員を**自身の頭上**（足元から2m上の場所）にテレポートさせる、でした。

![tp2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629850/49d84a4a-3473-61b2-df85-8ee52da50c18.gif)

コマンドに慣れていない人がこれを見ると、ゾンビが2m上にテレポートして、ぴょんぴょん跳ねるだけと勘違いしがちですが……残念ながらそうではありません。
コマンドを書く上で意識するべきなのは **誰がどこで** コマンドを実行しているかです。
用語で表すならば、 **実行者** と **実行位置** ですね。これらが自分が想像しているものと乖離している場合、コマンドを頑張って書いても思い通りに動かなくなってしまいます。

今回の場合は
* 実行者　：コマンドをチャットで打ったプレイヤー
* 実行位置：コマンドをチャットで打ったプレイヤーの足元

なのでゾンビがぴょんぴょんするわけではなく、自身の頭上までテレポートしてくるんです。

ちなみにゾンビをその場でぴょんぴょんさせたいならば
以下のようなコマンドを書くことになります。
```
/execute as @e[type=zombie,distance=..10] at @s run tp @s ~ ~2 ~
```
初心者にとっての最初の壁である`execute`が混ざっていますがこれらの意味合いは割と簡単です。
`execute as`は実行者の変更、`execute at`は実行位置の変更です。

なので上のコマンドの場合は

* 実行者　：半径10m以内にいるゾンビ全員
* 実行位置：それぞれのゾンビの足元

となり、ぴょんぴょんと跳ねるようになるわけです

![tp3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629850/8a8dda8b-d358-d1a8-13e4-3156c33249af.gif)

</details>

## Q3 （初心者向け）
以下のコマンドをチャットで実行した際の実行結果を言葉で説明しなさい。

```
/execute rotated ~ -90 positioned ^ ^ ^3 run particle heart
```

<details><summary>ヒント</summary>

先程のクイズで重要なのは **誰がどこで** コマンドを実行しているか、だと言いましたが今回はもうひとつ意識すべきものがあります。

</details>

<details><summary>解答</summary>

正解は自分の足元から3m上の場所にハートのパーティクルを表示させる、でした。

![tp4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629850/00806a22-a341-b806-8dc5-7eff8db57a37.gif)

先程あえて説明しなかったのですがコマンドで書く上でもうひとつ意識すべきものがあります。それが **実行方向** です。どっちを向きながらコマンドを実行しているか、という要素も大事なんですね。
`execute`では主にコマンドを実行する上で大事な要素である **実行者**、**実行位置**、**実行方向** を変えるサブコマンドが揃っています。

今回の場合は

`execute rotated ~ -90`　：　実行方向を真上に設定
`execute positioned ^ ^ ^3`　：　向いている方向（真上）に3m進んだ先を実行位置に設定

となり

* 実行者　：コマンドをチャットで打ったプレイヤー
* 実行位置：コマンドをチャットで打ったプレイヤーの足元から3m上
* 実行方向：真上

となるので頭上にハートのパーティクルが表示されるようになるのです。

`execute`に関しては以下のリンクに情報が連ねられているので良かったら確認してみてください。
[Minecraft wiki - execute](https://minecraft.fandom.com/wiki/Commands/execute "Minecraft wiki - execute")

</details>

## Q4 （中級者向け）
以下のコマンド群をチャットで実行した際の実行結果を言葉で説明しなさい。

```
/data modify storage test: Ella set value 1.5d
/execute store result storage test: Ella double 1.1 run data get storage test: Ella
/tellraw @s {"storage":"test:","nbt":"Ella"}
```

<details><summary>ヒント</summary>

この仕様に騙される人は結構多いと勝手に思っていますが、スコアボードのとある仕様を思い出せばおのずと答えはわかるはずです。

</details>

<details><summary>解答</summary>

正解はチャットに**1.1d**と表示される、でした。

![2023-11-28_14.31.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629850/b0f871c0-3ff3-a5ea-180e-f2133317995d.png)

どうしてですか！？　っとなった方、安心してください。
自分も初めはそう思ったので。

なぜ実行結果が`1.5 × 1.1`の答えである`1.65d`ではなく`1.1d`になるかというと、おそらく`data get storage test: Ella`のタイミングで自動的に`1.5d`の少数部分が切り捨てられてしまうからです。
そのため、本来`1.5 × 1.1`であったところが`1 × 1.1`になってしまい、最終的に1.1dと表示されてしまうのです。

実際にスコアボードを用いて四則演算する場合は、スコアがint型である都合上、自動的に小数点以下は切り落とされる仕様となっているのでここにもint型を用いる仕様が紛れ込んでいるのではないかと私は推測しましたが……実際のところはなんでこうなるかはよく分かってなかったりします。

ちなみに`1.65`を表示させたいのであれば以下のようにコマンド群を入力する必要があります。
```
/data modify storage test: Ella set value 1.5d
/execute store result storage test: Ella double 0.11 run data get storage test: Ella 10
/tellraw @s {"storage":"test:","nbt":"Ella"}
```

</details>

## Q5 （中級者向け）
以下のコマンド群をチャットで実行した際の実行結果を言葉で説明しなさい。

```
/data modify storage test: Ella set value [1d,1d]
/execute store result storage test: Ella[0] int 2 run data get storage test: Ella[0]
/tellraw @s {"storage":"test:","nbt":"Ella"}
```

<details><summary>ヒント</summary>

プログラミングを少しでも学んだことがある人であれば、なんとなく答えは分かるんじゃないかなと思います。
ただプログラミングに一切触れたことがない人にとっては難しいかも……。

</details>

<details><summary>解答</summary>

正解はチャットに [**1.0d,1.0d**] と表示される、でした。

![2023-11-28_14.50.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629850/18229b1c-b3d2-4784-d452-90cdcd135572.png)

直感的に考えれば`data get storage test: Ella[0]`で配列の1番目の数である`1d`を取り出し、それを2倍していれているので`[2.0d,1.0d]`になりそうですが、実際は違います。

これは`execute store result storage test: Ella[0] int 2`のタイミングでストレージに数を代入する処理が失敗してしまっているからです。
なぜ失敗するのか、それは型が異なっているからです。

プログラミングを少しでも学んだことがある人であれば、int型やdouble型など聞いたことがあるかもしれませんが、配列は`{}`などでくくってCompoundにしてあげない限り、別々の型を並べることはできないのです。

今回は`data modify storage test: Ella set value [1d,1d]`にて配列にdouble型の値を入れているのでこの配列はdouble型と言えるでしょう。しかし`execute store result storage test: Ella[0] int 2`の部分でint型として入れようとしてしまっているため、代入する処理が失敗してしまっているのです。

int型やdouble型と言われてもピンとこない人は[ここ](https://java-code.jp/68 "java入門")を覗いてみたり、データ型で検索して調べたりすると良いでしょう。

</details>

## おわりに
ということでクイズはここまでです。
ちょっと数が少なかったかもしれませんが、少しでも頭の体操になったのであれば幸いです。
Mincraftのコマンドはかなり癖の強い要素が多いので実際に色々考えて、書いて、学んでいくのが一番いいと思います。最近はマクロが増えてコマンドがより複雑化しようとしているタイミングなので、学ぶなら今のうちです！