マインクラフトで直下掘り、危険ですよね?
マグマに落ちたり、どうくつに落下したり…こわい経験をした人も多いはず。
でも、プログラミングで安全に直下掘りができます。
今回は、Pythonで安心安全な直下掘りプログラムを作ってみましょう!
マインクラフトとPythonの連携について
Pythonでマインクラフトを動かすには、準備が必要です。
セットアップ方法は、前の記事でくわしく説明していますので、まだ準備ができていない人はそちらを参考にしてみてください。
このプログラムでやること
このプログラムでは、次のことを行います:
- 足元が岩盤の場合は掘るのをやめる。
- 足元のブロックのさらに下のブロックを確認し、危険があれば掘るのをやめる。
- 足元が掘ってもよいブロックなら、空気ブロックに変えて掘り進め、1ブロック下に移動する。
- 足元が掘ってもよいブロック以外なら、掘るのをやめる。
完成したソースコード
まずは、完成版のプログラムを見てみましょう!
import mcpi.minecraft as minecraft
import time
mc = minecraft.Minecraft.create()
# 掘ってもよいブロックのIDリスト
# 石、草、土、砂、砂利
safe_blocks = [1, 2, 3, 12, 13]
# 危険なブロックのIDリスト
#空気、溶岩、静止した溶岩
danger_blocks = [0, 10, 11]
# 直下掘りを開始
while True:
# プレイヤーの座標を取得
x, y, z = mc.player.getTilePos()
# プレイヤーの足元とその下のブロックIDを取得
block_below = mc.getBlock(x, y - 1, z)
block_below2 = mc.getBlock(x, y - 2, z)
# 直下のブロックが岩盤だったら、直下掘りをやめる
if block_below == 7:
mc.postToChat("Stop digging! Bedrock is here!")
break
# ふたつ下のブロックが危険なブロックだったら、直下掘りをやめる
if block_below2 in danger_blocks:
mc.postToChat("Danger! Lava or a cave is below.")
break
# 掘ってもよいブロックなら、空気(ID: 0)に変換し 1ブロック下に移動
if block_below in safe_blocks:
mc.setBlock(x, y - 1, z, 0)
mc.player.setPos(x, y - 1, z)
else:
mc.postToChat("You found something interesting!")
break
# 少し待ってから次の掘削へ
time.sleep(0.5)
プログラムの説明
リストでデータをまとめる
掘ってもよいブロックと危険なブロックをそれぞれリストで管理しています。
safe_blocks = [1, 2, 3, 12, 13]
# 危険なブロックのIDリスト
danger_blocks = [0, 10, 11]
リストは、いくつかのデータを順番にならべて、まとめてあつかうことができるデータの種類です。
左側にリスト名、右側に角かっこ [] の中にデータをカンマで区切ってならべて、=でつなぐとリストを作成できます。
ずっとくり返す
Pythonでは、「指定した条件を満たしている間、処理くり返す」ときに while 文を使います。while 文では、条件を満たしている(True)かぎり、処理をくり返します。
条件に「True」を指定すると、プログラムを止めるまでずっとくり返します。
ずっとくり返したい処理
True(真) と False(偽)
TrueとFalseは「真」または「偽」を表す真偽値(ブール値)と呼ばれます。
プログラムの条件で「正しいか」「正しくないか」を判断するときに使われます。
- True(真) :条件が「正しい」とき
- False(偽):条件が「正しくない」とき
Pythonでは、数値の0や空の値はFalseとして扱われ、それ以外の値はTrueとされます。
足元のブロックとその下のブロックを調べる
プレイヤーの座標を取得したら、プレイヤーの足元とその下のブロックが何か調べます。
x, y, z = mc.player.getTilePos()
# プレイヤーの直下とその下のブロックIDを取得
block_below = mc.getBlock(x, y – 1, z)
block_below2 = mc.getBlock(x, y – 2, z)
mc.getBlock(x, y, z) で、指定した座標のブロックIDを取得できます。
block_belowには足元のブロック、block_below2にはさらに下のブロックのブロックIDを代入します。
条件によって処理を変える
条件によって処理を分けるときは、if 文を使います。
条件を満たした場合だけ特定の処理をするとき
条件がTrueだった時の処理
条件を満たした場合と、満たさなかった場合、別々の処理をするとき
条件がTrueだった時の処理
else:
条件がFalseだった時の処理
条件がTrue(またはFalse)だった時の処理の前には、半角スペースを4つ入れます。
リストの中に特定の値があるか調べる
in や not in を使うと、「リストや文字列などの中に特定の値があるかどうか」を調べられます。
- in :右辺に左辺が存在する
- not in:右辺に左辺が存在しない
今回のプログラムでは、下のような判定をしています。
- if block_below == 7:
→ 足元のブロック(block_below)が岩盤(7)だったら - if block_below2 in danger_blocks:
→ 2つ下のブロック(block_below2)が危険なブロックのリスト(danger_blocks)の中にあったら - if block_below in safe_blocks:
→ 足元のブロック(block_below)が掘ってもよいブロックのリスト(safe_blocks)の中にあったら
ループからぬける
break は、くり返し(ループ)を途中でぬけたいときに使います。
if block_below == 7:
mc.postToChat(“Stop digging! Bedrock is here!”)
break
# ふたつ下のブロックが危険なブロックだったら
if block_below2 in danger_blocks:
mc.postToChat(“Danger! Lava or a cave is below.”)
break
真下のブロック(block_below)が岩盤(7)だったり、2つ下のブロックが危険なブロックだった場合、メッセージを表示してループをぬけます。
- Stop digging! Bedrock is here!(採掘ストップ!岩盤があります!)
- Danger! Lava or a cave is below.(危険!溶岩か洞窟が下にあります)
プレイヤーを移動させる
足元のブロックが掘っても大丈夫なブロックだったら、空気ブロックに置きかえます。ブロックを空気に置きかえたら、プレイヤーを1マス下に移動させています。
if block_below in safe_blocks:
mc.setBlock(x, y – 1, z, 0) # ブロックを空気(ID: 0)にして掘る
mc.player.setPos(x, y – 1, z) # 1ブロック下に移動
else:
mc.postToChat(“You found something interesting!”)
break
mc.player.setPos(x, y, z)は、プレイヤーを指定した座標に移動する命令です。
足元のブロックが鉱石などsafe_blocksリストにないブロックだった場合は、メッセージを表示してループをぬけます。
- You found something interesting!(何か発見しました!)
少し待つ
掘る動作をゆっくり進めるために、time.sleep(0.5) を使っています。
time.sleep(0.5)
まず、import timeでtime モジュールを読み込みます。
モジュールは、Pythonで使える便利な道具箱のようなものです。よく使う命令や関数がまとまっています。
たとえば、timeモジュールは「時間」をあつかう命令が集まっています。
time.sleep(秒数)を使えば、プログラムを指定した秒数だけ一時停止できます。time.sleep(0.5)なら0.5秒(=500ミリ秒)待てます。
実行してみよう!
プログラムが完成したら「dig.py」という名前でファイルを保存し、実行してみましょう。
安全に掘り進めるプログラムの完成です!
まとめ
今回は、Pythonを使った直下掘りプログラムを紹介しました。
ただし、このプログラムですべての危険を防げるわけではありません。どんな状況が危険なのか、どうすればもっと安全にできるのか、ぜひ考えてみてくださいね!
最後に、今回使用した命令とPythonの構文をおさらいしておきましょう。
今回使用した命令
- mc.player.setPos(x, y, z):指定した座標にプレイヤーを移動する
- time.sleep(秒数):指定した秒数プログラムの動きを一時停止する(timeモジュール)
Pythonの構文
if 文:条件によって処理を分けるときに使う。
条件がTrueだった時の処理
else:
条件がFalseだった時の処理
in:右辺に左辺が存在する
break文:くり返し処理を途中でぬける