Python Minecraft II – Hello World

So in this post  for the Naas-Sallins Coder Dojo we are going to look at writing a program which will allow us to alter the state of the python minecraft world which we looked at in the last post. The first thing we need to do is amend the saveModule.py file in our pymc folder to allow for the two new blocks we added. If we look at lines 9 and 11 we have the following

        self.coordDictSave = { str(main.GRASS):'GRASS', str(main.SAND):'SAND', str(main.BRICK):'BRICK', str(main.STONE):'STONE' }

        self.coordDictLoad = { 'GRASS':main.GRASS, 'SAND':main.SAND, 'BRICK':main.BRICK, 'STONE':main.STONE }

we can see the structure of the save and load lines. We don’t really need to know everything the code does to guess that we can extend it to add our 2 blocks DOJO & DOJO2 so we get

        self.coordDictSave = { str(main.GRASS):'GRASS', str(main.SAND):'SAND', str(main.BRICK):'BRICK', str(main.STONE):'STONE',str(main.DOJO):'DOJO',str(main.DOJO2):'DOJO2' }

        self.coordDictLoad = { 'GRASS':main.GRASS, 'SAND':main.SAND, 'BRICK':main.BRICK, 'STONE':main.STONE, 'DOJO':main.DOJO, 'DOJO2':main.DOJO2 }

Now when we run our main.py program we can save the world by pressing F5. This creates a file called savegame.sav in our pymc folder.

This file has the following structure.

[-8, -3, 21]=>STONE
[52, -2, -39]=>GRASS
[66, -2, 19]=>GRASS

each line in the file represents the coordinates and texture of every block in our world. We can think of these numbers as the x, y and z of our world, where x is length, y is height and z is depth. Once we know the structure of our save file it gives the opportunity to write code to change the file and the world itself.

Our first step is to make a copy of the save file which we will call savegame.bak, this is so that we can start with a default state as we test our code. In our pymc folder create and edit a new file called world.py and add the following code

import shutil

shutil.copyfile('savegame.bak','savegame.sav')
world=open('savegame.sav','a')
world.close()

In this snippet we import the shutil library which allows us to perform operations on files on our computer. Our next line simply copies our default world state from our backup savegame.bak to savegame.sav . We then show how to open and close that file. The ‘a’ in the open statement says that we are going to open the file for append, which just means that we are going to add on to the end of the file.

Next we are going to alter our world by adding lines to the savegame.sav file. In this example we are going to create a large ‘hello world’ message in blocks. So we are going to create a function which will draw each letter.


def do_h(startx,starth,starty,texture):
    """ draw the letter H """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+4,starty,texture))
    return(myletter)

This function is different than the ones we had in earlier posts, if we look at the first line we can see that we have some values in between the brackets after our name do_h. These values are called parameters and they represent the variables that we want this function to do its work on. In this case they are startx, starth, starty, texture which represent the beginning coordinates of the first block we want to place in our world along with the texture we want to use. After that we create a new list called myletter and then begin to create the lines which will draw our letter H. We do this by adding onto the beginning position of our first block. For example if we want to add a block on top of our first (which will be part of our first leg of the letter H) we have

startx,starth+1,starty,texture

so you can see that all we are changing  is the height of the block by one in comparison to the first. To explain the rest of the line, mylist.append simply means that we add onto our list. The next bit

("[%d,%d,%d]=>%s\n" % (startx+3,starth+4,starty,texture))

says to replace the placeholders (%d for digits and %s for words) with the following variables. Really all this is saying is that we want to create a line that will have the same structure as our savegame.sav file. In general our function creates a list of the lines we want to add to our file given a start position and texture. In order to actually add this letter H to our world we need to call the function so our code becomes

import shutil
def do_h(startx,starth,starty,texture):
    """ draw the letter H """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+4,starty,texture))
    return(myletter)

shutil.copyfile('savegame.bak','savegame.sav')
world=open('savegame.sav','a')

nextletter = do_h(20,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)

world.close()

Here we can see that in order to create our H we call the function do_h and send it our values for startx, starty, startz and texture. The values passed to our function when we call it need to be in the format and order that our function expects in order for it to work. By changing these values we can alter where the letter will be placed in our world.   The variable next letter takes on the value returned by our function and we then loop through that list writing the details to our world file. If we run this program we will then be able to see our floating letter when we run our world using main.py. All that is required to spell out Hello World is to define a function for each letter and then call it with the correct starting coordinates.
helloworld

Its a fair bit to take in but once you get the hang of it you can create all sorts of objects by code alone. The full Hello world code is below. Note how once we have defined the letter, we only need to change the coordinates to position it somewhere else.

import shutil

def do_e(startx,starth,starty,texture):
    """ draw the letter E """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+4,starty,texture))
    return(myletter)
def do_h(startx,starth,starty,texture):
    """ draw the letter H """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+4,starty,texture))
    return(myletter)
def do_l(startx,starth,starty,texture):
    """ draw the letter L """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth,starty,texture))
    return(myletter)
def do_o(startx,starth,starty,texture):
    """ draw the letter O """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+4,starty,texture))
    return(myletter)
def do_w(startx,starth,starty,texture):
    """ draw the letter W """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+4,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+4,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+4,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+4,starth+4,starty,texture))
    return(myletter)
def do_r(startx,starth,starty,texture):
    """ draw the letter R """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth,starty,texture))
    return(myletter)
def do_d(startx,starth,starty,texture):
    """ draw the letter O """
    myletter = []
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+3,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+1,starth+4,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+2,starth+4,starty,texture))
    #myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+1,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+2,starty,texture))
    myletter.append("[%d,%d,%d]=>%s\n" % (startx+3,starth+3,starty,texture))
    return(myletter)

shutil.copyfile('savegame.bak','savegame.sav')
world=open('savegame.sav','a')

nextletter = do_h(20,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_e(25,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_l(29,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_l(33,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_o(37,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_w(43,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_o(49,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_r(54,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_l(59,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
nextletter = do_d(63,4,-8,'DOJO2')
for i in nextletter:
    world.write(i)
world.close()

 

Advertisements

Getting Started with Python

So this is the first post in a short series for the Naas-Sallins Coder Dojo about using the Python programming language. It is aimed at the people who have got pretty familiar with scratch and are looking to try something new. There are a ton of python resources on the web and I will list some of these later.

 

Step 1. Get Python

unless you are on Linux chances are that you will need to install python. At the moment python has 2 major versions 2.7 and 3.3 which have some real differences. I recommend for our purposes that you download and install the 2.7 version for your operating system from ActiveState as it comes bundled with some good help files an editor and documentation. If your install asks if you want to let python through your firewall select yes since we will use this feature later.

Step 2. Hello World

Okay so now lets check that python is installed correctly.  It’s pretty much a standard to do ‘Hello World’ when starting any new programming language. The idea is to confirm that you have everything installed correctly by writing the code to print out the message ‘Hello World’.  If you are on windows and have a start menu try running the Python Interactive shell from the ActiveState Group or you can type python from a command shell.

 

You should get something like this

ActivePython 2.7.5.6 (ActiveState Software Inc.) based on
Python 2.7.5 (#65, Mar 30 2005, 09:33:37 [MSC v.1310 32 bit (Intel)] on
win32
Type “help”, “copyright”, “credits” or “license” for more information.
>>>

You can use the Python shell to interactively run Python code, so in our case at the >>> prompt type

print “Hello World”

If you get

Hello World

congrats you have python installed! If something went wrong along the way don’t worry, I will give you a hand at the next dojo session.