【Raspberry Pi】Pythonでマインクラフトを遊んでみた【Scratch2MCPI】

はじめに

こんにちは、がんがんです。
Raspberry Pi用OSであるRaspbianにはマインクラフトがデフォルトでインストールされています。

以前遊んでみて楽しかったマイクラ×Pythonですが、
今回は勉強会で使用するということでMinecraft Pi editionを遊んだときのことを改めてまとめておきます。

目的

Minecraftに関する面白い記事

Minecraft × 強化学習

Minecraft強化学習の分野にて環境として用いられており、
イクラ環境内でいろいろなタスクに挑戦するコンテストも行われているみたいです。
以下の記事はとても面白いなと思って読みました。
qiita.com

STEP1 VPN ViewerをWindowsにインストール

VPNの設定をしてなかったのでまずはVPNを有効にして環境を構築します。
やっている人は飛ばしてください。

こちらのサイトを参考にして進めていきました。
www.fabshop.jp

VNC Viewerのサイトへのリンクも貼っておきます。
VNC Viewerのサイト
Download VNC Viewer | VNC® Connect

STEP2 Scratch2MCPIをインストールし、Scratchからマイクラをできるようにする

次に、Scratch2MCPIをインストールしていきます。
参考記事はこちらです。
www.fabshop.jp

以下のコマンドでScratch2MCPIを落とします。

sudo curl http://scratch2mcpi.github.io/install.sh | sh

デスクトップ上にScratch2MCPIとScratch2MCPIのTerminalがあればインストールは完了です。

STEP3 Minecraft Pi editionをPythonで遊んでみた

Scratchのインストールも終わったので、次はPythonでマイクラを遊んでみます。
実は以前Pythonで遊んだことがあり、そのときの記事が途中だったので改めてまとめていきます。

遊んだ際に参考にした本

改めて遊んでみて参考にした記事

igarashi-systems.com

実験

実験としては、主に本に書いてあることを試してみました。
もっと詳しく知りたい方は本を買われて遊んでみてください。

実験1「木材ブロックを置いてみる」

まずはブロックを置いてみました。

コード
#setblock for Python3
import mcpi.minecraft as mine
import mcpi.block as block

mc = mine.Minecraft.create()    #  マインクラフトに接続
x, y, z = mc.player.getPos()    #  プレイヤーの位置を取得
mc.setBlock( x, y+3, z+5, block.WOOD_PLANKS.id)    #  ブロックをセット
結果

f:id:gangannikki:20190426232235p:plain

実験2「砂ブロックを落下させる」

次はブロックを落下させてみます。

コード
#  setblock 2 for Python3
import mcpi.minecraft as mine
import mcpi.block as block

#  空間を初期化する
mc = mine.Minecraft.create()
mc.setBlocks( -10, 0, -10, 10, 99, 10, block.AIR.id)
mc.setBlocks( -10, -1, -10, 10, -99, 10, block.GRASS.id)
x = 0
y = 0
z = 0
#  プレイヤーを移動
mc.player.setPos(x, y, z-9)

#  石ブロックをセット
mc.setBlocks(x-3, y+3, z-3, x, y+3, z, block.STONE.id)
#  砂ブロックをセット
mc.setBlocks(x-3, y+6, z-3, x+3, y+6, z+3, block.SAND.id)
結果

f:id:gangannikki:20190426232257p:plain

実験3「流体の水ブロックを流す」

コード
#  setblock 2 for Python3
import mcpi.minecraft as mine
import mcpi.block as block

#  空間を初期化
mc = mine.Minecraft.create()
mc.setBlocks( -10, 0, -10, 10, 99, 10, block.AIR.id)
mc.setBlocks( -10, -1, -10, 10, -99, 10, block.GRASS.id)
x = 0
y = 0
z = 0
mc.player.setPos(x, y, z-9)

#  石ブロックをセット
mc.setBlocks(x-3, y+3, z-3, x+3, y+3, z+3, block.STONE.id)
#  流体の水ブロックをセット
mc.setBlocks(x, y+6, z, block.WATER_FLOWING.id)
結果

f:id:gangannikki:20190426232325p:plain

実験4「ウォータースライダーの作成」

最後は流水ブロックを用いたスライダーの作成です。

コード
#  setblock 2 for Python3
import mcpi.minecraft as mine
import mcpi.block as block
import time

#  空間の初期化
mc = mine.Minecraft.create()
mc.setBlocks( -10, 0, -10, 10, 99, 10, block.AIR.id)
mc.setBlocks( -10, -1, -10, 10, -99, 10, block.GRASS.id)

#  滑り台の定義(配置テーブル)
map = [
  ['11111111000','77777777111','00000007777','00000000000'],
  ['18000000000','77777777001','00000007777','00000000000'],
  ['11111111000','77777777101','00000007777','00000000000'],
  ['00000000000','00000000101','00000000777','00000000000'],
  ['00000000000','00000000101','00000000777','00000000000'],
  ['00000000000','00000000101','00000000777','10100000000'],
  ['00000000000','00000000101','00000000777','10100000000'],
  ['00000000000','00000000101','00000000101','10100000777'],
  ['00000000000','00000000000','00000111101','10111177777'],
  ['00000000000','00000000000','00000000001','10000177777'],
  ['00000000000','00000000000','00000111111','11111177777']]

#  滑り台の配置
for h in range(4):
    for j in range(11):
        for i in range(11):
            id = int(map[j][h][i])
            x = i - 5
            y = 3 - h
            z = j - 5
            mc.setBlock( x, y, z, id)
            #  水ブロックの初期位置をプレイヤーの初期位置に設定
            if(id == 8):
                sx = x + 0.5
                sy = y
                sz = z + 0.5

#  プレイヤーの移動
mc.player.setPos(sx, sy, sz)

#  下に降りたプレイヤーを上に戻す
while True:
    x1, y1, z1 = mc.player.getPos()
    time.sleep(1)
    x2, y2, z2 = mc.player.getPos()
    if( (x1==x2) & (y1==y2) & (z1==z2) ):
        mc.player.setPos(sx, sy, sz)
結果

画像なので分かりにくいですが、実際にはしっかり無限ループしています。
f:id:gangannikki:20190426232401p:plain

実験5「TNTブロックも置いてみる」

せっかくなら爆破がやりたい!と思ったので、こちらを参考にして爆破しました。
Modding Minecraft with Python - PythonでMinecraftをコントロールします | Raspberry Pi Projects

コード
#----------------
#  coding:utf-8
#-----------------
from mcpi.minecraft import Minecraft

mc = Minecraft.create()
mc.postToChat("Hello world")

#  ポジションの取得
x, y, z = mc.player.getPos()

#  TNTブロックの設置
mc.setBlocks( x+1, y+1, z+1, x+11, y+11, z+11, 46, 1)
結果

見事にTNTの山が出来ています。
f:id:gangannikki:20190426234626p:plain

剣を当てると起爆します。
この量のTNTなので爆発の瞬間は処理落ちしてしまいます(笑)。

まとめ

今回は勉強会に向けてMinecraft Pi Editionの準備を進めました。
GPIOと組み合わせたりいろいろ遊べそうなので、GWにでもやってみます。

今日のコードはGitHub

コードはすべてGitHubに挙げています。
github.com