はじめに
うちの子(小学生)がMinecraftにハマっている。
そろそろプログラミングの学習をさせたいとおもっていたところ、「Minecraftで楽しく学べるpythonプログラミング」(斎藤大輔著)なる本を入手した。
私自身はMinecraftはやったことがなく、カクカクしたブロックの世界を横目で見たことしかない。いろいろな種類のブロックで建築物を作ったりできるらしいことは知っている。
Minecraftでpythonを動かす
まずは本を読んで学習した。
私の理解では、MinecraftではModと呼ばれる改変用のプログラムを追加で導入して、利用することができる。
Modは様々なものが、公開されている。Mod群の管理に使うのがForgeというものらしい。
Minecraftのバージョンと、Forgeのバージョン、さらに、Modのバージョンの3つをぴったり揃える必要があるようだ。
Minecraftに「Raspberry jam」Modを導入すると、pythonのスクリプトを、Minecraftのチャット入力用のテキストフィールドから実行できるようになる。
実行するpythonスクリプト側からは、mcpiモジュールを使用して、raspberry jam環境が動いているMinecraftの世界とデータをやりとりする。
本に従って、Minecraftの世界でphtyonを動かせるようにした。まずは、helloworld.pyを実行。Hello Worldが表示されて、ひと段落。足元のブロックがダイヤモンドに変わって子供は大喜び。
ダイヤモンドを置くコードを調べたらたった1行だ。これなら世界中をダイヤモンドにすることもできそうだ。
導入時のトラブル
Minecraftでpython scriptを実行しようとしたら、モジュールがimportできない、という問題が発生した。モジュール検索パスを調べるスクリプトを書いて実行したらpython2が動いていることが判明した。
raspberry modの設定ファイルを変更する必要があるが、これに関しては本を参考にしてほしい(ただし、本書サポートページで入手できる設定ファイルを開いて、pythonのバージョンを実際に使用するバージョンに書き換える必要があった)。
著者によるMac用python3の環境構築についてはこちらに解説がある。
ちょっとうちの子には早かったかな?
困ったことに、うちの子の興味がpythonの方に向かない。なんとかして興味を繋ぎ止めたい、ということで、いろいろ考えてみた。
コードをちょっと変えてみて変化を調べたりするのは早すぎたのかもしれない。エクセルでブロックの配置を指定するデータファイルを作成して、これを読み込ませて建物が建てられるようにしたらどうだろうか?
うちの子は、そもそもエクセルすら触ったことがなく、コピーとかペーストも多分したことがない。エクセルのマスに数字を入力するだけでも大きな前進だ。
57はブロックの種類の指定で、ダイアモンドブロックを指定している。A列の数値は、その右側の着色部分の繰り返し回数ということにする。何も数字がないところは、空間。
この図では、8ブロックx8ブロックx5ブロックの中空の直方体を指定してる。
A1からI28をコピーして、テキストファイルとして保存し、これを以下のpythonスクリプトで読み込むことにした(セルとセルの区切りは\t、改行は\n)。
pythonスクリプトと、データファイルの置き場所は、本を参考にしていただきたい。
from mcpi.minecraft import Minecraft
from mcpi.block import *
mc = Minecraft.create()
pos = mc.player.getTilePos()
# 建物のデータを読み込む
f = open('mc_input.txt','r')
data = f.read()
f.close
# データを読み込んで整理
floors = []
repeats = []
lines = data.split('\n')
for line in lines:
d = line.split('\t')
if d[0] != '':#各行の先頭に文字があったら、繰り返し指定。
repeats.append(int(d[0]))
k = []
floors.append(k)
k.append(d[1:])
# ブロックを置く
y = 0
for index in range(len(repeats)):
for i in range(repeats[index]):
z = 0
y = y + 1
for lines in floors[index]:
x = 0
for b in lines:
#ブロックを置く処理
if b != '':
mc.setBlock(pos.x + x,pos.y + y,pos.z + z,Block(int(b)))
x = x + 1
z = z + 1
Minecraftの世界では、平面方向にx座標とz座標が伸びており、垂直方向がy座標になっている。
できました。
こんな風になりました。こちらではブロックIDとして133(エメラルドブロック)を使用しています。

結局
うちの子にとっては、内部に湧いたモンスターを倒すのが楽しいらしい。
