Minecraft Molehills?

Here’s a little program for generating random holes in the landscape and automatically putting a candle at the bottom. The idea is that this could be run on the Raspberry Pi running as a server so that other players can have a little fun hunting for them.

I’ve discovered that candles don’t like being put underwater… no surprise there!

Hole generated in Python with a candle at the bottom.

Watch your step – a deep hole created by the python program.

Screenshots have been created following the instructions at Raspberry Pi – Spy.

from mcpi import minecraft
import time
import random
mc = minecraft.Minecraft.create()

mc.postToChat("Python is now in control!")

def Molehole(x,y,z,depth):
    mc.setBlocks(x,y+40,z,x+0,y-depth,z+0,0) #clear the space first
    mc.setBlock(x,y-depth,z,50) #Put a candle at the bottom of the tunnel  


for loop in range(20):
    startx = random.randint(-120,120)
    startz = random.randint(-120,120)
    starty = 0
    Molehole(startx,starty,startz,20)
Advertisements

Relief maps in Minecraft

The UK south-west peninsula.

The UK south-west peninsula.

When automatically generating landscapes in Minecraft, it seems easy to get large flat areas by just using the setBlocks() part of the API, but what I wanted was depth, height and texture. I’d seen methods of using bump maps in 3d software, so I wondered if similar techniques could be used. After a bit of searching I came across the fantastic maps-for-free website which has a whole earth view in relief map format – and free, too! (Permission is granted to copy, distribute and/or modify the relief maps and the water layer under the terms of the GNU Free Documentation license, Version 1.2 or any later version published by the Free Software Foundation.).

UK relief map image

UK Map taken from the relief layer shown on http://www.maps-for-free.com/

I quickly copied a section, converted it into a JPEG file of reasonable dimensions and re-coloured the sea so that it was the darkest area. In order to simply convert this into a file that Python can use, I cheated and used jp2a again. This converts images into a set of ASCII characters. I read this into a Python and convert into a list The python program works its way through the list and using setBlocks() creates a stack of blocks whose height is related to the intensity of the image at that point. What’s really pleasing is how well the final landform came out. It’s possible to see the high lands of Dartmoor and Exmoor, Snowdonia and further North, as well as the flat areas of the Norfolk Broads (forgive me if my geography is a bit dodgy… they did try to sort me out at school!).


from mcpi import minecraft
import commands
mc = minecraft.Minecraft.create()
mc.postToChat("Python is now in control!")

#Output from jp2a: Default is "   ...',;:clodxkO0KXNWM"

#jp2a 18 values
jp2ascale=" ",".","'",",",";",":","c","l","o","d","x","k","O","0","K","X","N","W","M"
mcscale=80,82,79,1,4,98,98,98,98,98,98,98,98,98,14,15,16,17,49,98
blockset=8,82,79,1,4,98,98,98,98,98,98,98,98,98,14,15,16,17,49,98

wr_str = "ukmap.jpg"

cmd = 'jp2a --width=255 --height=255 '+wr_str # create an operating system command

line = commands.getoutput( cmd ) # send cmd as a command to the operating system and receive the result.

list_line = line.rstrip().split("\n") # split the result from "figlet" into separate lines (right strip new line feeds)

print "Your picture has been converted to"
print line

#list_line="   ...',;:clodxkO0KXNWM","   ...',;:clodxkO0KXNWM","   ...',;:clodxkO0KXNWM","   ...',;:clodxkO0KXNWM"

startx,starty,startz = mc.player.getPos() #get the player's position

startx=128
starty=-1
startz=128

for row in list_line: # one row at a time from list_line (the result from figlet)
    startz=startz-1 # work down from the top
    column=0
    for letter in row: # work along each row - check each character. If it's a "#" then print a block else leave it as air
        
        column = column+1
        blockheight=jp2ascale.index(letter)
        blocktype=blockset[blockheight]
        mc.setBlocks(startx-column,starty,startz,startx-column,starty+blockheight,startz,blocktype)

print("All done!")


Underground bunker

The underground bunker

A snapshot of the underground bunker.

Building overground is great… but what about working underground. Those little secret bunkers left over from the cold war that are being turned into dwellings. Here’s a version for minecraft. There are two important variables that set the depth (it’s still there as tower height as a throwback to the last post) and the width. If you go too low (perhaps only to 5 or less) then the stairs don’t work. The torches get placed in funny positions sometimes or end up scattered on the floor. I think it’s to do with the fact that I haven’t put in facing-directions yet, but I’m not sure.

This could be interesting if started not far from a cliff-edge – you could then tunnel in to meet it somewhere. The bunker position is based on where “Steve” is standing at the moment the script is run.

Edited… some of the indenting went wrong last night!

from mcpi import minecraft
import time
mc = minecraft.Minecraft.create()
 
mc.postToChat("Python is now in control!")
 
def Bunker(x,y,z,height,width):
    y=y-height
    useblock=45
    centre=width/2
    mc.setBlocks(x,y,z,x+width,y+height,z+width,0) #clear the space first
 
    mc.setBlocks(x,y,z,x+width,y+height,z,useblock) #build a wall
    mc.setBlocks(x,y,z,x,y+height,z+width,useblock) #build a wall
    mc.setBlocks(x+width,y,z,x+width,y+height,z+width,useblock) #build a wall
    mc.setBlocks(x,y,z+width,x+width,y+height,z+width,useblock) #build a wall
 
    mc.setBlocks(x,y+height,z,x+width,y+height,z+width,42) #add a lid
    mc.setBlocks(x+3+centre,y+height,z+1,x+1+centre,y+height,z+2,0) #add a hole in the floor
 
    for floorheight in range(int(y)-1,int(y+height)-1,4):
        print "Putting in a floor at ",floorheight
        mc.setBlocks(x,floorheight,z,x+width,floorheight,z+width,17) #add a floor
        mc.setBlocks(x+3+centre,floorheight,z+1,x+1+centre,floorheight,z+2,0) #add a hole in the floor
 
        mc.setBlocks((x+centre)-1,floorheight+2,z,x+1+centre,floorheight+2,z,50) #add torch to front
        mc.setBlocks(x,floorheight+2,(z+centre)-1,x,floorheight+2,z+1+centre,50) #add torch to right side
        mc.setBlocks((x+centre)-1,floorheight+2,z+width,x+1+centre,floorheight+2,z+width,50) #add torch to rear
        mc.setBlocks(x+width,floorheight+2,(z+centre)-1,x+width,floorheight+2,z+1+centre,50) #add torch to left side
 
        for stepheight in range(1,4):
            mc.setBlock(x+stepheight+centre,floorheight+stepheight,z+1,67,0) # add an ascending east step block
            mc.setBlock(x+stepheight+centre,floorheight+stepheight,z+2,67,0) # add an ascending east step block
 
startx,starty,startz = mc.player.getPos() #get the player's position
 
towerheight=60
towerwidth=10
Bunker(startx,starty,startz,towerheight,towerwidth)

Another Minecraft tower (or two)

High rise towers from a Python program

Create two high-rise towers with this simple script

This program creates two towers next to each other. They’re rather sparse, having only four windows, an entrance door and a staircase to the top. It’s possible to walk up the staircase although you’ll get pretty dizzy in the process. I need to edit the program to stop it putting a useless staircase right at the top, but other than this it’s quite effective. Perhaps with a little work it would be possible to populate the minecraft world with a whole range of flats – even maybe using random for different heights and positions. Another refinement would be to clear the space it occupies so that you don’t have to remove the trees and landscape from the placement position.

from mcpi import minecraft
import time
mc = minecraft.Minecraft.create()

mc.postToChat("Python is now in control!")
#mc.setBlocks(-100,0,-100,100,100,100,0)
#mc.setBlocks(-100,1,-100,100,1,100,1)


def Tower(x,y,z,height,width):
    useblock=1
    centre=width/2
    mc.setBlocks(x,y,z,x+width,y+height,z,useblock)
    mc.setBlocks(x,y,z,x,y+height,z+width,useblock)
    mc.setBlocks(x+width,y,z,x+width,y+height,z+width,useblock)
    mc.setBlocks(x,y,z+width,x+width,y+height,z+width,useblock)
    mc.setBlocks(x+centre,y,z,x+1+centre,y+1,z,0) #add doorway to front


    for floorheight in range(int(y)-1,int(y+height),4):
        print "Putting in a floor at ",floorheight
        mc.setBlocks(x,floorheight,z,x+width,floorheight,z+width,useblock) #add a floor
        mc.setBlocks(x+3+centre,floorheight,z+centre,x+1+centre,floorheight,z+1+centre,0) #add a hole in the floor

        mc.setBlocks((x+centre)-1,floorheight+2,z,x+1+centre,floorheight+2,z,102) #add window to front
        mc.setBlocks(x,floorheight+2,(z+centre)-1,x,floorheight+2,z+1+centre,102) #add window to right side
        mc.setBlocks((x+centre)-1,floorheight+2,z+width,x+1+centre,floorheight+2,z+width,102) #add window to rear
        mc.setBlocks(x+width,floorheight+2,(z+centre)-1,x+width,floorheight+2,z+1+centre,102) #add window to left side
        for stepheight in range(1,4):
            mc.setBlock(x+stepheight+(width/2),floorheight+stepheight,z+(width/2),67,0) # add an ascending east step block
            mc.setBlock(x+stepheight+(width/2),floorheight+stepheight,z+1+(width/2),67,0) # add an ascending east step block

startx,starty,startz = mc.player.getPos() #get the player's position

#startx=0
#starty=0
#startz=0

towerheight=60
towerwidth=10
Tower(startx,starty,startz,towerheight,towerwidth)
Tower(startx+20,starty,startz,towerheight,towerwidth)

Minecraft / Python apologies

Picture of Python code

Code snippet showing correct highlighting.

My apologies to anyone following this blog hoping to try the Python programming examples. It appears that copying and pasting sections of codes works well if I enclose┬áit correctly, but then the formatting gets messed up if I go back and edit the post. Quotes / speech marks get expanded┬áinto the html “&quot” which then means that Python doesn’t understand it.

I’m using code language=”Python” with /code

to enclose the code and enable the key word highlighting. Perhaps someone can suggest a better method?

I think the solution will eventually be to use some sort of file hosting site, but for now I’ll try to keep a closer eye on what’s going on.

Minecraft Skeleton

Minecraft Skeleton figure.

Minecraft Skeleton drawn using the Symbol program written in Python.

Experimenting with the symbol drawing routine can give interesting results. I’m not a great artist, so hopefully this will give some inspiration. I found it easiest to put each of the lines in the list one after the other and then fill in with # symbols. They then need joining together again to create a proper Python list.

While I remember, it also seems easier to create the programs using nano running over SSH from another computer to save having to minimise Minecraft and switch over to IDLE. Just a thought.

 

from mcpi import minecraft
mc = minecraft.Minecraft.create()
mc.postToChat("Python is now in control!")

line = "  #####  "," ####### ","#########","#  ###  #","#########","#### ####","#########"," # # # # "," #######","  #####  ","   ###   ","#########","#   #   #","# ##### #","#   #   #","# ##### #","#   #   #","# ##### #","# #   # #","  #   #  ","  #   #  ","  #   #  "," ##   ## ","###   ###"

print line

startx,starty,startz = mc.player.getPos() #get the player's position

starty=starty+24 #lift the starty so that it's not written under your feet!

for row in line: # one row at a time from list_line (the result from figlet)
    starty=starty-1 # work down from the top
    column=0
    for letter in row: # work along each row - check each character. If it's a "#" then print a block else leave it as air
        column = column+1
        if letter =="#":
            mc.setBlock(startx-column,starty,startz,1)
        else:
            mc.setBlock(startx-column,starty,startz,0)

Minecraft aircraft

 

Minecraft passenger plane.

Passenger plane generated by a Python Program

I was set the challenge of creating a Python program that automatically creates an aircraft at the player’s position. I used the symbol generating routine as a starting position for the fuselage and then added a few loops to create the wings and tail fin. I’d like to play with the textures and various block ids to see what can be achieved, but at the moment I feel that they’d make an interesting addition to many Minecraft scenes.

#Airplane program... IPRoulson 2015
from mcpi import minecraft
mc = minecraft.Minecraft.create()
mc.postToChat("Python is now in control!")

fuselage_mtl = 42
wing_mtl = 57
fin_mtl = 57
tailfin_mtl = 49
seat_mtl=41

startx,starty,startz = mc.player.getPos() #get the player's position

#start in the same place each time:
#startx=0
#starty=2
#startz=0

#create fuselage from pattern
line = "  ###  "," #   # ","#     #","#     #","#     #"," ##### ","  ###  "

for fuselage in range(1,45):
    yplot=starty+10 #lift the starty so that it's not written under your feet!  
    
    for row in line: # one row at a time from list line
        yplot=yplot-1 # work down from the top
        column=0
        for letter in row: # work along each row - check each character. If it's a "#" then print a block else leave it as air
            column = column+1
            if letter =="#":
                mc.setBlock(startx-column,yplot,startz+fuselage,fuselage_mtl)
            else:
                mc.setBlock(startx-column,yplot,startz+fuselage,0)

#create nose cone
xoffset=4

#MAIN SOLID
mc.setBlocks(startx-(xoffset+2),(starty+5),(startz),(startx-xoffset)+2,starty+6,(startz-6),fuselage_mtl)
mc.setBlocks(startx-(xoffset+1),(starty+5),(startz-6),(startx-xoffset)+1,starty+6,(startz-7),fuselage_mtl)

#clear cockpit area
mc.setBlocks(startx-(xoffset+1),(starty+5),(startz),(startx-xoffset)+1,starty+6,(startz-4),0)

#floor cockpit
mc.setBlocks(startx-(xoffset+1),(starty+4),(startz),(startx-xoffset)+1,starty+4,(startz-4),fuselage_mtl)

#MAIN WINDOW BLOCK
mc.setBlocks(startx-(xoffset+1),(starty+7),(startz),(startx-xoffset)+1,starty+8,(startz-4),20)
#FRONT TAPER OF WINDOW
mc.setBlocks(startx-(xoffset+1),(starty+7),(startz-5),(startx-xoffset)+1,starty+7,(startz-5),20)    
#clear cockpit glass
mc.setBlocks(startx-xoffset,starty+7,startz,startx-xoffset,starty+7,startz-4,0)

#punch out windows
for window in range(5,42,3):
    xoffset=4
    mc.setBlock(startx-(xoffset+3),starty+6,startz+window,20)
    mc.setBlock((startx-xoffset)+3,starty+6,startz+window,20)

#fit the seats
for window in range(6,45,3):
    xoffset=4
    mc.setBlock(startx-(xoffset+2),starty+5,startz+window,seat_mtl)
    mc.setBlock((startx-xoffset)+2,starty+5,startz+window,seat_mtl)
    mc.setBlock(startx-(xoffset+1),starty+5,startz+window,seat_mtl)
    mc.setBlock((startx-xoffset)+1,starty+5,startz+window,seat_mtl)

#draw wing
for wing in range(1, 15):
    xoffset=4
    zoffset=11
    length=13
    mc.setBlocks(startx-(xoffset+wing+length),starty+3,startz+zoffset+wing,(startx-xoffset)+wing+length,starty+3,startz+zoffset+wing,wing_mtl)

#draw tailplane
for fin in range(1, 10):
    xoffset=4
    zoffset=35
    length=2
    mc.setBlocks(startx-(xoffset+fin+length),starty+9,startz+zoffset+fin,(startx-xoffset)+fin+length,starty+9,startz+zoffset+fin,fin_mtl)

#draw tailfin
for fin in range(2,10):
    xoffset=4
    zoffset=44
    mc.setBlocks(startx-xoffset,starty+19-fin,startz+zoffset,(startx-xoffset),starty+19-fin,startz+zoffset-fin,tailfin_mtl)
fighter

Eurofighter Typhoon generated by a Python program

 

The second image is loosely based on the Eurofighter Typhoon. There are no air intakes and the engines are not set to afterburner – perhaps someone would like to try adding these.

One addition I’m considering is to use the half-steps to create smoother edges. I am sure it’s possible and it would really improve the look of many of these objects. Maybe sometime later…

#Eurofighter Typhoon program... IPRoulson 2015
from mcpi import minecraft
mc = minecraft.Minecraft.create()
mc.postToChat("Python is now in control!")


#block ids used? 42 - iron block, 49 - obsidian, 41 - gold block
fuselage_mtl = 42
wing_mtl = 42
fin_mtl = 42
tailfin_mtl = 42
seat_mtl=41

mc.setBlocks(-30,0,-30,40,30,45,0)

startx,starty,startz = mc.player.getPos() #get the player's position

#start in the same place each time:
#startx=0
#starty=2
#startz=0

#create fuselage from pattern
line = "   #   "," ##### ","#     #","#     #"," ##### ","  ###  "

for fuselage in range(1,25):
    yplot=starty+10 #lift the starty so that it's not written under your feet!  
    
    for row in line: # one row at a time from list line
        yplot=yplot-1 # work down from the top
        column=0
        for letter in row: # work along each row - check each character. If it's a "#" then print a block else leave it as air
            column = column+1
            if letter =="#":
                mc.setBlock(startx-column,yplot,startz+fuselage,fuselage_mtl)
            else:
                mc.setBlock(startx-column,yplot,startz+fuselage,0)
#create engine                
xoffset=4

mc.setBlocks(startx-(xoffset+3),(starty+5),(startz+23),(startx-xoffset)-1,starty+7,(startz+24),49)
mc.setBlocks(startx-(xoffset-1),(starty+5),(startz+23),(startx-xoffset)+3,starty+7,(startz+24),49)
mc.setBlock(startx-(xoffset+2),starty+6,startz+24,35,14)
mc.setBlock(startx-(xoffset-2),starty+6,startz+24,35,14)
#create nose cone
xoffset=4

#MAIN SOLID
mc.setBlocks(startx-(xoffset+2),(starty+5),(startz),(startx-xoffset)+2,starty+6,(startz-6),fuselage_mtl)
mc.setBlocks(startx-(xoffset+1),(starty+5),(startz-6),(startx-xoffset)+1,starty+6,(startz-7),fuselage_mtl)
mc.setBlock(startx-xoffset,starty+6,startz-8,fuselage_mtl)

#draw canard
for fin in range(1, 4):
    xoffset=4
    zoffset=-3
    length=5
    mc.setBlocks(startx-(xoffset+fin+length),starty+6,startz+zoffset+fin,(startx-xoffset)+fin+length,starty+6,startz+zoffset+fin,fin_mtl)

#clear cockpit area
mc.setBlocks(startx-(xoffset+1),(starty+5),(startz),(startx-xoffset)+1,starty+6,(startz-4),0)

#floor cockpit
mc.setBlocks(startx-(xoffset+1),(starty+4),(startz),(startx-xoffset)+1,starty+4,(startz-4),fuselage_mtl)

#MAIN WINDOW BLOCK
mc.setBlocks(startx-(xoffset+1),(starty+7),(startz),(startx-xoffset)+1,starty+8,(startz-4),20)
#FRONT TAPER OF WINDOW
mc.setBlocks(startx-(xoffset+1),(starty+7),(startz-5),(startx-xoffset)+1,starty+7,(startz-5),20)    
#clear cockpit glass
mc.setBlocks(startx-xoffset,starty+7,startz,startx-xoffset,starty+7,startz-4,0)

#draw wing
for wing in range(1, 18):
    xoffset=4
    zoffset=7
    length=3
    mc.setBlocks(startx-(xoffset+wing+length),starty+4,startz+zoffset+wing,(startx-xoffset)+wing+length,starty+4,startz+zoffset+wing,wing_mtl)
#draw wingtips
xoffset=4
zoffset=17
length=6
mc.setBlocks(startx-(xoffset+20),starty+4,startz+zoffset,startx-(xoffset+20),starty+4,startz+zoffset+length,wing_mtl)
mc.setBlocks((startx-xoffset)+20,starty+4,startz+zoffset,(startx-xoffset)+20,starty+4,startz+zoffset+length,wing_mtl)

#draw tailfin
for fin in range(2,10):
    xoffset=4
    zoffset=24
    mc.setBlocks(startx-xoffset,starty+15-fin,startz+zoffset,(startx-xoffset),starty+15-fin,startz+zoffset-fin,tailfin_mtl)