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)