LazyBrush Plays Minecraft on Raspberry Pi

So Where do we start? Perhaps at the re-spawn point. Minecraft is an amazingly addictive game. In Minecraft you mine for blocks and you can use these blocks to craft various shapes and buildings. And Kids love it!

The Raspberry Pi is a small cheap computer which is aimed to get kids into computing. The idea is to not just let them learn how to use a spreadsheet, but how to actually program! The combination of Minecraft and Raspberry Pi should be a winner!  The creators of Minecraft did something else, they added a Python interface to Minecraft so you can craft outside the game and make various shapes and blocks via programming.

When I saw there was a Python interface I thought it could be quite neat to create a image from blocks automagically. As in, pass in a image file and some magic script makes blocks to represent the image. Here is a sample video of the end result.

In order to do this, you need to program some python. Here is a very simple python script which lets you add a block above the player:

import minecraft.minecraft as minecraft
import minecraft.block as block
import time
mc = minecraft.Minecraft.create()
playerPos = mc.player.getPos()
xval = int(playerPos.x)
yval = int(playerPos.y) + 2
zval = int(playerPos.z)
mc.setBlock( xval + 0 , yval + 0, zval, 35 , 15 )

Here, we import various minecraft routines and find the current location of the player. We then change the block at this position (+2 on y axis) to being a ’35’ which is wool. In fact there are 16 different types of wool with the final column of the setBlock being the wool number of interest.

16 Different Flavours of Wool

Cool, we have wool. Next, lets thing about getting pixel info from an image. ImageMagick lets you do lots of clever things with images.  One thing it can do is convert an image into text like this:

$ convert mona.gif text:-
# ImageMagick pixel enumeration: 91,100,255,srgb
0,0: (162,155,104) #A29B68 srgb(162,155,104)
1,0: (151,141, 86) #978D56 srgb(151,141,86)
2,0: (158,148, 95) #9E945F srgb(158,148,95)
3,0: (158,148, 95) #9E945F srgb(158,148,95)
...

The three first 2 numbers are co-ordinates in the image so 0,0 is top left. The next three numbers are the colour, Red, Green and Blue. These numbers range from 0 to 255, so a (0,255,0) would be The Purest Green. In the wool image there is the RGB split for each colour. So ALL we need to do is pick a good wool colour for each image colour we find. We could be clever and convert RGB into a different colour space, but we try not to be too clever most of the time. So lets just compare our image RGB with the wool RGB.

Ok, I said we weren’t going to be too clever, that’s a little white lie. My mate Pythagoras really really liked triangles. We could use his neat idea to find the shortest distance between a colour in our image and one of the wool colours.

So now we almost have everything. Raspberry Pi, Minecraft, Python, Pythagoras anything else? Well, one way to solve this would be to use shell, awk and sed. With all this, mixed with some idle time you might make these scripts.

wool.txt – The same as the above wool image but in a computer readable format.

0 221 221 221   White  #DDDDDD
1 219 125 62    Orange  #DB7D3E
2 179 80  188   Pink  #8350BC
3 107 138 201   Blue  #6B8AC9
4 177 166 39    Yellow  #B1A627
5 65  174 56    Green  #41AE38
6 208 132 153   Salmon  #D08499
7 64  64  64    Grey  #404040
8 154 161 161   LtGrey  #9AA1A1
9 46  110 137   Navy  #2E6E89
10 126 61 181   Purple  #7E3DB5
11 46  56 141   DrkBlue  #2E388D
12 79  50 31    Brown  #4F321F
13 53  70 27    Kacki  #35461B
14 150 52 48    Red  #963430
15 25  22 22    Black  #191616

woolbest.sh – A Shell script to pick a nice wool given a colour RGB value

R=$1
G=$2
B=$3
X=$4
Y=$5
T=$6

cat wool.txt | awk -v Red=$R -v Green=$G -v Blue=$B -v Xco=$X -v Yco=$Y -v Type=$T ' 
        BEGIN   { 
                near=100000
                val=0
                }
        {
                if ($2 < Red)
                        tRed=Red-$2
                else
                        tRed=$2-Red

                if ($3 < Green)
                        tGreen=Green-$3
                else
                        tGreen=$3-Green

                if ($4 < Blue)
                        tBlue=Blue-$2
                else
                        tBlue=$2-Blue
        
                distance = tRed*tRed + tGreen*tGreen + tBlue*tBlue      
                if (near > distance)
                        {
                        near=distance
                        val=$1
                        cols=$2 ", " $3 ", " $4
                        hash=$6
                        }
        } 
        END     { 
                #print val  #minecraft block
                if (Type == "Img")
                  print Xco "," Yco ": ( " cols ",255) " hash " srgba(" cols ",1)"
                else
                  print "mc.setBlock( xval + " Xco " , yval + " Yco ", zval, 35 , " val " )"
                }'

mkblock.sh – A shell script to take an image in and output a python script.

img=$1
type=$2
img_new=new_$1
img_mc=new_$1.py
img_txt=tmp_$1.txt
img_txt_head=tmp_head_$1.txt
img_txt_tail=tmp_tail_$1.txt
img_sh=tmp_$1.sh
img_new_txt=tmp_new_$1.txt

echo Proceessing Block $img

if [ "$type" = "MC" ]
then
        flip=" -flip "
else
        flip=""
fi



echo Convert to Text
convert -resize 64x64 $flip $img text:- > $img_txt

echo Get the Head
head -1 $img_txt > $img_txt_head

echo Get the Tail
len=`wc -l $img_txt | awk '{print $1}'`
len=`expr $len - 1`
tail -$len $img_txt > $img_txt_tail

echo Build up Pixel Changing Script
cat $img_txt_tail | awk 'BEGIN{FS=","} { print $1 " " $2 " " $3 " " $4 }' | sed 's/://g' | sed 's/(//g' | sed 's/)//g' | awk -v T=$type '{print "./woolbest.sh " $3 " " $4 " " $5 " " $1 " " $2 " " T }' > $img_sh

chmod +x $img_sh

if [ "$type" = Img ]
then
  echo Type Img Change Pixels
  cat $img_txt_head > $img_new_txt
  ./$img_sh >> $img_new_txt

  echo Convert back from Text to Img
  convert text:$img_new_txt $img_new
fi

if [ "$type" = MC ]
then
cat << DONE > $img_mc
import minecraft.minecraft as minecraft
import minecraft.block as block
import time

mc = minecraft.Minecraft.create()

playerPos = mc.player.getPos()

xval = int(playerPos.x) 
yval = int(playerPos.y) + 2
zval = int(playerPos.z) 


DONE

  ./$img_sh >> $img_mc
fi

echo Tidy Up
rm -f $img_txt $img_txt_head $img_txt_tail $img_sh $img_new_txt

I also decided it might be useful to see what the image could look like before we load it into minecraft with python. With ImageMagick it not only coverts to text format it converts from it too. So a little tweak to the mkblock.sh script means we can do the following:

Andys-iMac:mine andy$ ./mkblock.sh mona.gif Img
Proceessing Block mona.gif
Convert to Text
Get the Head
Get the Tail
Build up Pixel Changing Script
Type Img Change Pixels
Convert back from Text to Img
Tidy Up
Andys-iMac:mine andy$ 

Which makes an image with the wool colours and at the resolution that we see in minecraft.
Mona Wool Colours

You can download these scripts and convert your images into python scripts by doing the following:

Andys-iMac:mine andy$ ./mkblock.sh mona.gif MC
Proceessing Block mona.gif
Convert to Text
Get the Head
Get the Tail
Build up Pixel Changing Script
Tidy Up
Andys-iMac:mine andy$ 

Note the ‘MC’ at the end which then makes a script called ‘new_mona.gif.py’ which you can run with python on a raspberry pi.

If you are unsure what images to try, why not see what Mona Lisa likes to do in her spare time.

Thanks for reading!

Comments
4 Responses to “LazyBrush Plays Minecraft on Raspberry Pi”
  1. AndrewS says:

    Why mix shell, awk, sed and Python, rather than doing the whole lot just in Python?
    If you used Python Imaging Library (PIL) you could get rid of the use of ImageMagick too 😉

    P.S. One of the neat things about the Pythagoras formula is that the inputs always get squared, i.e. it doesn’t matter if they’re initially negative, i.e. you don’t need to check “if ($2 < Red)" etc.

    • lazybrush says:

      Hello AndrewS! All good comments. The fun of Unix is that there are many ways to solve a problem. I’d say for quick prototyping pick any tools you like and then you can refine your solution later.

      • AndrewS says:

        “for quick prototyping pick any tools you like and then you can refine your solution later”
        Yeah, that’s what I usually do too 🙂

        But in your article you specifically mentioned “get kids into computing”, and I reckon they’d be put off by such a mix of languages all at once.

  2. Whoa it is realy performing first class gaming, i’ve got to talk about that may this can be a perfect gaming in fact, together with our loved one along with my spouse and i finaly observed this excellent write-up that means it is more excellent using this type of free stuff appreciate it!
    Good appreciate it greatly for this good stuff my spouse and i minecraft liked that write-up and also this video game device for you to is incredibly beneficial.

Leave a comment