Thursday, 17 January 2013

Raspberry Pi - Minecraft - Hide and Seek


Ive been playing around with the pre-release of minecraft on the Raspberry Pi and in particular the API, see this post for some background on the basics, and rather than watching 'Food Inspectors' on the tv, I thought I would see if I could write a game in minecraft (a game in a game I suppose) in an hour.  This is what I came up with....

Minecraft - Hide and Seek!
The concept is really simple, a diamond block is hidden, at a random location, in the minecraft world and you have to find it and stand next to it and its quickest time wins.  You are helped along the way by the game telling you whether you are getting "warmer" or "colder" and how far you are from the block!


I recorded this video using the the pre-release and you will notice towards the end of the video that it starts to go a bit weird, with a flashing screen and the player being moved about!

Download and run
You can download the code direct from git-hub, so run minecraft, open/create a world and follow the instructions:

sudo apt-get install git-core
cd ~
git clone https://github.com/martinohanlon/minecraft-hs.git
cd minecraft-hs
python minecraft-hs.py

The code
If you want learn and have a go yourself, here's how:

Create a directory for the program

mkdir ~/minecraft-hs

Copy the python api class library from minecraft to the programs directory

cp -r ~/mcpi/api/python/mcpi ~/minecraft-hs/minecraft

Create minecraft-hs.py python program

nano ~/minecraft-hs/minecraft-hs.py

or open Idle and save minecraft-hs.py to the minecraft-hs directory

Code

#www.stuffaboutcode.com
#Raspberry Pi, Minecraft - hide and seek

#import the minecraft.py module from the minecraft directory
import minecraft.minecraft as minecraft
#import minecraft block module
import minecraft.block as block
#import time, so delays can be used
import time
#import random module to create random number
import random
#import math module to use square root function
import math

#function to round players float position to integer position
def roundVec3(vec3):
    return minecraft.Vec3(int(vec3.x), int(vec3.y), int(vec3.z))

def distanceBetweenPoints(point1, point2):
    xd = point2.x - point1.x
    yd = point2.y - point1.y
    zd = point2.z - point1.z
    return math.sqrt((xd*xd) + (yd*yd) + (zd*zd))
 
if __name__ == "__main__":

    #Connect to minecraft by creating the minecraft object
    # - minecraft needs to be running and in a game
    mc = minecraft.Minecraft.create()

    #Post a message to the minecraft chat window
    mc.postToChat("Hi, Minecraft Hide & Seek")

    time.sleep(2)
 
    #Find the players position
    playerPos = mc.player.getPos()
 
    #Create random position within 50 blocks from the player, our hidden block will go there
    randomBlockPos = roundVec3(playerPos)
    randomBlockPos.x = random.randrange(randomBlockPos.x - 50, randomBlockPos.x + 50)
    randomBlockPos.y = random.randrange(randomBlockPos.y - 5, randomBlockPos.y + 5)
    randomBlockPos.z = random.randrange(randomBlockPos.z - 50, randomBlockPos.z + 50)
    print randomBlockPos
 
    #Create hidden diamond block
    mc.setBlock(randomBlockPos.x, randomBlockPos.y, randomBlockPos.z, block.DIAMOND_BLOCK)
    mc.postToChat("A diamond has been hidden - go find!")
 
    #Start hide and seek
    seeking = True
    lastPlayerPos = playerPos
    lastDistanceFromBlock = distanceBetweenPoints(randomBlockPos, lastPlayerPos)
    timeStarted = time.time()
    while (seeking == True):
        #Get players position
        playerPos = mc.player.getPos()
        #Has the player moved
        if lastPlayerPos != playerPos:
            #print "lastDistanceFromBlock = " + str(lastDistanceFromBlock)
            distanceFromBlock = distanceBetweenPoints(randomBlockPos, playerPos)
            #print "distanceFromBlock = " + str(distanceFromBlock)
            if distanceFromBlock < 2:
                #found it!
                seeking = False
            else:
                if distanceFromBlock < lastDistanceFromBlock:
                    mc.postToChat("Warmer " + str(int(distanceFromBlock)) + " blocks away")
                if distanceFromBlock > lastDistanceFromBlock:
                    mc.postToChat("Colder " + str(int(distanceFromBlock)) + " blocks away")
         
            lastDistanceFromBlock = distanceFromBlock
         
        time.sleep(2)
    timeTaken = time.time() - timeStarted
    mc.postToChat("Well done - " + str(int(timeTaken)) + " seconds to find the diamond")

    time.sleep(5)
 
    mc.postToChat("www.stuffaboutcode.com")

The complete code repository is also on githubhttps://github.com/martinohanlon/minecraft-hs.git.

Run 
Note - minecraft must be running and you must be in a game

python ~/minecraft-hs/minecraft-hs.py

or if using Idle, click Run Module

11 comments:

  1. Well done! I think you should try integrating a python video game into Minecraft Pi Edition, like snake. That would be a challenge!

    ReplyDelete
  2. Hi Martin, my 10 year old loves minecraft and his raspberry pi, he is setting up a blog and would like to blog about this and post the code onto github - would that be OK? Of course he would attribute the work to you! Cheers.

    ReplyDelete
    Replies
    1. Hi, I would love for you son to blog about this post, anyone is welcome to link to my blog, its always 'nicer' to provide links rather than cut and paste content, that way the original author also gets a hit. Ive put the code on github (ill update the post), see https://github.com/martinohanlon/minecraft-hs.git. Martin

      Delete
    2. Martin, Thanks for that, he had created a repo, but instead we will fork yours.

      Cheers,
      Peter

      Delete
  3. Hi Martin,
    I have followed your steps in the above and I don't think I missed anything but got this when I tried to run it:

    pi@raspberrypi ~ $ python ~/minecraft-hs/minecraft-hs.py
    File "/home/pi/minecraft-hs/minecraft-hs.py", line 17
    SyntaxError: Non-ASCII character '\xc2' in file /home/pi/minecraft-hs/minecraft-hs.py on line 17, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
    pi@raspberrypi ~ $

    I'm very new to all this so please forgive me if I'm being silly and have missed a trick.

    many thanks

    Tim

    ReplyDelete
    Replies
    1. Hi Tim,

      It sounds like you have got some odd characters in your code, web browsers have a habit of doing if you cut and paste. Head over to my github page, https://github.com/martinohanlon/minecraft-hs.git, open the minecraft-hs.py file, click raw and cut and paste the code from there.

      Martin

      Delete
  4. Wow! Thank you. This should help me learn to do some basic programming! Thanks Again.

    ReplyDelete
  5. hi martin
    now you may get this or not, but when i type in 'python ~/minecraft-hs/minecraft-hs.py' i get back bash: python ~/minecraft-hs.py: no such file or directory
    I'm completely new to programming so if you can help that'd be great.
    -Tyler

    ReplyDelete
    Replies
    1. So, I would say your problems are either down to the code not having downloaded so the file ~/minecraft-hs/minecraft-hs.py doesn't exist or there is a mistake in the command "python ~/minecraft-hs/minecraft-hs.py". My advice would be check to see if the file is there and see if the file exists.

      Delete
  6. hey martin um i downloaded pretty much all of your programs and their all awesome but now i cant open minecraft and it gives me an error: "failed to add ervice, already in use?" i dont know what it means.pls help

    by the way sorry for the misuse of grammar

    ReplyDelete
    Replies
    1. I have never seen the error myself, but I quick google seach led me to here http://www.instantsupportsite.com/self-help/raspberry-pi/raspberry-failed-service/ which suggests the error occurs if you dont have enough memory allocated to the GPU. Have you by any chance setup a minecraft server on your Pi? If you followed my tutorial I change the memory allocation to take the memory away from the GPU so the server has more.

      Delete