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)
Advertisement

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)

More Minecraft programming

Symbols

SymbolI’ve done some more experiments with the Minecraft API – trying to use it to create shapes and patterns, as well as a few automatic structures. The first little program uses a pattern stored as “#” symbols in a list and reads them one-by-one. If there is a “#” then it creates a block, and if not it creates air.

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+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 (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)

 
 

Heart
Heart This program is a development of the symbol program, but to create a heart and fill it with wool. The wool has can have another number added to the block id which means that the colour can be controlled. Just the thing with Valentines day a few weeks ago…


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+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 (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,35,10)
        else:
            mc.setBlock(startx-column,starty,startz,0)

 
 

Heart2
Heart2Here I’ve added another version of the heart program. At the beginning it generates random coordinates and a random colour for the wool blocks.



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


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

#print line

for loop in range(1,100):
    startx=random.randint(-127,127)
    starty=random.randint(10,20)
    startz=random.randint(-127,127)
    colour =random.randint(1,16)
    #print(loop," : ",startx,starty,startz)
    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,35,colour)
            else:
                mc.setBlock(startx-column,starty,startz,0)

 
 

Face
Face

The face program reads the characters from the list and turns them into blocks in the shape of a face. It wouldn’t take a great deal of work to make all sorts of structures, doorways or windows with this type of program. By extending the “if letter ==”#” section of the program to include other characters, it would be possible to use a variety of block effects.


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

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



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

starty=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 (the result from figlet)
    starty=starty-1 # work down from the top
    column=0
    print row
    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)

 
 

Tile
tile
This program is similar to the Face program, but it creates a patterned tile on the ground. This could be altered to produce interesting mosaic flooring designs or perhaps even direction indicator markers.


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

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



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

startz=startz+10 #lift the starty so that it's not written under your feet!
starty=starty-1 # put it under the feet
for row in line: # one row at a time from list_line (the result from figlet)
    startz=startz-1 # work down from the top
    column=0
    print row
    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,2)
        else:
            mc.setBlock(startx-column,starty,startz,1)

 
 

Tower
Tower

I’ve seen a program to create a pyramid on another website and wondered if I could develop my own from scratch. I also wanted to see if some kind of communication tower could be created – or perhaps a pylon.

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

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

def Pillars(x,y,z,height,width):
    #put in the four pillars
    mc.setBlocks(x,y,z,x,y+height,z,1)
    mc.setBlocks(x+width,y,z,x+width,y+height,z,1)
    mc.setBlocks(x,y,z+width,x,y+height,z+width,1)
    mc.setBlocks(x+width,y,z+width,x+width,y+height,z+width,1)
    #join the corners
    mc.setBlocks(x,y+height,z,x+width,y+height,z,1)
    mc.setBlocks(x,y+height,z,x,y+height,z+width,1)
    mc.setBlocks(x+width,y+height,z,x+width,y+height,z+width,1)
    mc.setBlocks(x,y+height,z+width,x+width,y+height,z+width,1)
    
#   ] time.sleep(10)
#    mc.setBlocks(x,y,z,x+width,y+height,z+width,0)

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

towerheight=3
offset=0
towerwidth=10
for i in range(0,towerwidth/2):
    print i, offset, starty+offset
    Pillars(startx+i,starty+offset,startz+i,3,towerwidth-(i*2))
    offset=offset+towerheight

 
 

Tower2
Tower2

Here’s a development of the above program. It is a bit better structurally, having better support on the upright pieces. There’s very little to it, so perhaps more useful to illustrate how to develop the idea further.

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

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

def Pillars(x,y,z,height,width):
    #put in the four pillars
    mc.setBlocks(x,y,z,x,y+height,z,1)
    mc.setBlocks(x+width,y,z,x+width,y+height,z,1)
    mc.setBlocks(x,y,z+width,x,y+height,z+width,1)
    mc.setBlocks(x+width,y,z+width,x+width,y+height,z+width,1)

    #join the top corners
    mc.setBlocks(x,y+height,z,x+width,y+height,z,1)
    mc.setBlocks(x,y+height,z,x,y+height,z+width,1)
    mc.setBlocks(x+width,y+height,z,x+width,y+height,z+width,1)
    mc.setBlocks(x,y+height,z+width,x+width,y+height,z+width,1)

    #join the bottom corners
    mc.setBlocks(x,y,z,x+width,y,z,1)
    mc.setBlocks(x,y,z,x,y,z+width,1)
    mc.setBlocks(x+width,y,z,x+width,y,z+width,1)
    mc.setBlocks(x,y,z+width,x+width,y,z+width,1)
    
startx,starty,startz = mc.player.getPos() #get the player's position

towerheight=3
offset=0
towerwidth=10
for i in range(0,towerwidth/2):
    print i, offset, starty+offset
    Pillars(startx+i,starty+offset,startz+i,3,towerwidth-(i*2))
    offset=offset+towerheight


 
 

Tower3
Tower3

Here’s the Pyramid that I was originally intending to have a go at creating. The door isn’t centred properly and perhaps there’s more elegant coding, but it’s suitable as a quick structure to add to the Minecraft landscape. I’d like to have a go at creating a labyrinth inside the pyramid eventually, so watch this space…

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 Pillars(x,y,z,height,width):
    useblock=1
    #join the bottom corners
    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)
    
startx,starty,startz = mc.player.getPos() #get the player's position

towerheight=4
offset=0
towerwidth=10
for i in range(0,towerwidth/2):
    Pillars(startx+i,starty+offset,startz+i,towerheight,towerwidth-(i*2))
    offset=offset+towerheight

#create door
    mc.setBlocks((startx-1)+(towerwidth/2),starty,startz,startx+1,starty+2,startz,0)


Minecraft Text Generator

RPi Kitchen written in blocks

Using block-type 1 to automatically write text from a Python file.

A few more experiments with the Minecraft API and Python has brought be to this point… combining figlet with Python to create a minecraft text generator. More information on figlet can be found at www.figlet.org.

First… install figlet on your Raspberry Pi using:

sudo apt-get install figlet

Then test figlet by using:

figlet "hello world"

The basic structure of the program requires:

  • A connection to the Minecraft API.
  • Input the phrase to be rendered into a string variable.
  • Send the string to the operating system to be processed by figlet using the banner font.
  • Read the response back into a string variable and then split it into individual lines.
  • Work along each line creating a block or air depending on whether figlet added a “#” symbol to represent part of the text.

The screenshots were generated by raspi2png using the instructions from Raspberry Pi Spy.

The Python program is shown below:

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

wr_str = raw_input('What would you like to write? ') # ask the user what they'd like to write at the current position

cmd = 'figlet -f banner '+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 text has been converted to'
print line

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

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

for row in list_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)

Something that looks rather nice is to replace the “air” blocks (code 0 in the penultimate line) with something like 22 which translates to Lapis Lazuli. Alternatively, use 8 for the block type, which becomes water which flows from the words shown.

.

Minecraft on the Raspberry Pi

mysnapshot_04Well… I escaped the whole Minecraft phenomenon for this long. Sure, I’d heard about it from the students and a few visitors at the Exeter Raspberry Jam loaded it up on my Pi, but I’d never delved any further.

Minecraft appears to be a game which puts the user in control of “Steve” – a superhero who can hop and fly at the touch of the spacebar. Armed with his trusty sword which can build and tear down (echoes of Ecclesiastes 3) he can navigate the cubic world at will. The world coordinates are limited to +/- 127 units but that’s a fair amount of walking and flying. I’m guessing the scale is somewhere around 1 unit = 1 metre. It’s all vaguely reminiscent of 3d Construction Kit which I used to run on my Amiga. Continue reading