Monday, 31 March 2014

Creating Minecraft Pi Earthquakes

I've been playing around with controlling the Pi edition of Minecraft from Squeak Smalltalk and had a thought: wouldn't it be cool to create earthquakes?

Some people have tried this already from within Minecraft, e.g. in this video:
https://www.youtube.com/watch?v=dqJg0WW691Y

But what about if you could create cracks in the ground more randomly as you wander around your world?

First follow this article to get Squeak controlling Minecraft.

Now try this from a Workspace in Squeak:

m := Minecraft connect. 
p := m playerTile + {0. 0. 2}.    "two blocks in front of me"
100 timesRepeat: [
    m blockAt: p put: 0.
    p := p - {0. 1. 0}.           "move one block down"
]

That should create a deep hole in front of you, right through to the end of the world!

So you could now repeat this for several more blocks in front of you and add in a bit of randomness:

m := Minecraft connect. 
p := m playerTile + {0. 0. 2}.    "two blocks in front of me"
20 timesRepeat: [
    q := p.
    50 + 10 atRandom timesRepeat: [
        m blockAt: q put: 0.
        q := q - {0. 1. 0}.       "move one block down"
    ].
    p := p + {0. 0. 1}.           "move one block away"
]

Now we have a very straight crack, running 20 blocks ahead of us.

What next?

What about making the crack run in a more zig zag fashion? 

Or make branches off of the main crack?

Let me know how you get on...

Saturday, 29 March 2014

Programming Raspberry Pi Minecraft with Squeak Smalltalk

You can control Minecraft from Smalltalk, create blocks, make shapes and more, all from Squeak.

In this example we'll draw a rainbow, make tables and build trees, all without having to place blocks with the mouse.

First you need to install the Smalltalk Minecraft Bindings (thanks to Dr. Bert Freudenberg for writing them :). Open up Squeak, then open a Monticello browser from the Tools menu. Now:
  1. Click +Repository
  2. Choose HTTP
  3. Paste in this code:
MCHttpRepository
    location: 'http://ss3.gemstone.com/ss/minecraft'
    user: ''
    password: ''

Then...
  1. You'll see the minecraft repository on the right hand side of the window
  2. Make sure its selected and then click Open
  3. Now click the underlined item on the right and click Load to load the latest version, then repeat for the Demo collection
  4. You can now open a Browser from the Tools menu and find two new Minecraft collections at the end of the list: Minecraft-Pi-Base and Minecraft-Pi-Demo

Connecting to Minecraft

Before you can control Minecraft you need to connect Squeak to it. If you are running Squeak and Minecraft on the same computer then it's easy to connect -- however you might find that your Pi struggles to run both, with everything slowing down considerably.

To connect to Minecraft on the same computer:

m := Minecraft connect.

To connect to another computer

Find your Minecraft computer's IP address by running ifconfig in a Terminal -- look for the line under eth0 that starts with inet addr:192.168.1.... That bit starting192.168.1. is your IP address. Make a note of it.

In Squeak run the following from a Workspace window (making sure you use your own IP address):

m := Minecraft connectTo: '192.168.1.113'.

Drawing a block

Once you have created a Minecraft object and stored it in the variable m using one of the lines above you can send Minecraft messages.

Try the following (you don't need to type the bit in quotes):

p := m playerTile.     "store the player's location"
m blockAt: p put: 1.   "place a block of stone"

Now look down in Minecraft, you should see a stone block. Try this next:

1 to: 100 do: [ :i | 
    m blockAt: (p + {i. i. i}) put: 1.
]

You now have a stone staircase! It's actually pretty difficult to climb this staircase as each block is diagonal to the last one, see if you can fix this. Hint: {i. i. i} represents {x. y. z} for each value of i from 1 to 100, where x is left/right, y up/down and z forwards/backwards.

Try the demos

The class MinecraftDemo contains a few demo methods including one to draw a rainbow, a table and a tree.

If Minecraft is running on a different computer you'll need to connect first.

MinecraftDemo host: '192.168.1.113'.

Now try the demos, run each line at a time. Look around in Minecraft to see the results (they may be behind you).

MinecraftDemo tree: 15.
MinecraftDemo table: 5.
MinecraftDemo rainbow: 10.

What next?

A good next step is to take a look at the code in the demo class. Type MinecraftDemo into the search box, or select that class name and hit Ctrl-B to browse the code.

This is how the method `table:` is defined:

table: size
 "E.g. Draw a 5x5 table with legs 5 high:
  MinecraftDemo table: 5"
 | mc pos |

 mc := Minecraft connectTo: self host.
 pos := mc playerTile.

 "Table top"
 1 to: size do: [ :x | 
  1 to: size do: [ :z | 
   mc blockAt: (pos + {x. size. z})
    put: Stone.
  ]
 ].

 "Legs"
 1 to: size do: [ :i |
  mc blockAt: (pos + {1. i. 1}) put: Stone.
  mc blockAt: (pos + {size. i. 1}) put: Stone.
  mc blockAt: (pos + {1. i. size}) put: Stone.
  mc blockAt: (pos + {size. i. size}) put: Stone.
 ].

 mc close.

Thursday, 20 March 2014

Finding Factors with Smalltalk

I've been looking for ways to cover the primary maths curriculum with real world examples or visual representations. Some of the curriculum is easy (for angles and gradients we can cycle up some hills) but some is a bit harder.

What about factors and prime numbers? While I have a think about the real world example of this I thought I'd put together a visual created with a little Smalltalk program to explore further.

You can see the results here... circles represent factors, so 10 has factors of 2 and 5, and each factor has a white stripe up to the number, so the whiter the background the more factors. This makes the primes easy to spot, e.g. 3, 5, 7, 11...


Some interesting questions:


  1. Why do some numbers have more factors than others? 
  2. Are there any repeating patterns in the dots?
  3. Do we see any of the numbers with a high number of factor (e.g. 12, 24, 36) in real life?
--

Here's the code:

First add the new class...

Object subclass: #FactorGrid
instanceVariableNames: 'rect max spacing'
classVariableNames: ''
poolDictionaries: ''
category: 'GeekClub'

And then the methods...

drawXLabels
| t |

1 to: max do: [ :i | 
t := TextMorph new.
t newContents: i asStringWithCommas.
t position: (i * spacing)@25.
rect addMorph: t.
]

highlightNumber: i forFactor: f
| r |

r := RectangleMorph new.
r position: ((i * spacing )- 4)@25.
r extent: (spacing * 0.9)@((f * 25) - 5).
r color: ((Color white) alpha: 0.2).
r borderWidth: 0.
rect addMorph: r.

initialize
max := 40.
spacing := 24.

rect := RectangleMorph new openInWorld.
rect color: (Color r: 0.972 g: 0.878 b: 0.819).
rect extent: 1000@500.
rect position: 0@20.
rect borderWidth: 1.

self drawXLabels.

plot: aNumber
| c t |

t := TextMorph new.
t newContents: aNumber asStringWithCommas.
t position: 5@(aNumber * 25).
rect addMorph: t.

1 to: max do: [ :i | 
(i \\ aNumber) isZero ifTrue: [ 
c := CircleMorph new.
c position: ((i * spacing) + 3)@(aNumber * 25).
c extent: 10@10.
(i = aNumber) ifTrue: [
c color: Color red.
]
ifFalse: [
self highlightNumber: i forFactor: aNumber.
].
rect addMorph: c.
]
]

plot: i to: j 
i to: j do: [ :a | self plot: a ].

Now you can create the drawing... open a new Workspace and run the following (one line at a time):

g := FactorGrid new.
g plot: 2.
g plot: 3.
g plot: 4 to: 20.


Smalltalk on the Raspberry Pi

Smalltalk is a great language for learning. Everything runs in an integrated environment, so it's quick to try things out; it's simple to grasp the basics and there are lots of visual things included in the environment.

Each Raspberry Pi comes with the Squeak version of the Smalltalk programming language. Well almost, most of what you need it there, but there are a few bits to collect from the internet to complete the package. Run these commands from a terminal shell to get them...

mkdir squeak-downloads; cd squeak-downloads

wget http://ftp.squeak.org/4.1/SqueakV41.sources.gz
gunzip SqueakV41.sources.gz

wget http://ftp.squeak.org/4.4/Squeak-4.4-All-in-One.zip
unzip -j Squeak-4.4-All-in-One.zip "**Squeak4.*.image"
unzip -j Squeak-4.4-All-in-One.zip "**Squeak4.*.changes"

sudo mv SqueakV41.sources /usr/share/squeak
sudo mv Squeak4.*.image /usr/share/squeak/
sudo mv Squeak4.*.changes /usr/share/squeak/

Starting Squeak

Now you can start up Squeak, you'll find it in the programming menu, and open a new Workspace from the Tools menu. This is where you can execute commands with immediate effect.

Type in the line below and execute it by bringing up the right mouse menu, or pressing Ctrl-D (for 'do it').

b := BouncingAtomsMorph new openInWorld.

You should see a panel with some bouncing atoms in it. Now try each line below, running each one in turn:

b setAtomCount.
b startInfection.

When you've had enough you can kill the morph by Alt-Clicking it and choosing the X icon, or type `b delete`

Drawing with a Pen

Now type in the following:

p := Pen new.
p goto: 300@300.
p squareNib: 4.
p down.
p spiral: 200 angle:45.

Select all the lines (Ctrl-A), right click and choose 'do it' from the menu. You should see a nice rainbow spiral.

What just happened? You created a new `Pen` and sent it some messages:
  • to go to a point some way into the middle of the screen
  • that you want a square nib of width 4 pixels
  • to put the pen down ready for drawing
  • to draw a spiral with 200 segments turning 45 degrees at each step.
There's lots more you can do with pens, take a look by typing Pen in the search box at the top of the page and browsing all of its methods. E.g. try: `p filberts: 5 side: 4.`

A few things to notice:
  • messages that take a parameter, e.g. `p goto: 300@300` have a colon after the message name, this style is repeated if you need to supply multiple parameters. 
  • each Smalltalk expression ends in a dot '.' -- don't forget this otherwise Smalltalk will join your lines together and you'll get strange error messages.
  • for more info on Syntax see http://en.wikipedia.org/wiki/Smalltalk#Syntax

Sound?

Sound doesn't work in Squeak without a bit of tweaking. Here's what I tried first:

FMSound bass1 play.

...nothing. But there's a solution here: http://raspberrypi.stackexchange.com/a/13221/12203

What next?

You could try creating some Fractal Trees.

If the above has got you interested, a good place to learn more is the free book: http://squeakbyexample.org/

Monday, 10 March 2014

Smalltalk Fractal Trees

Making Fractal Trees in Smalltalk is pretty simple, especially with Squeak, which has lots of drawing classes included out of the box.

All the drawing in the example below is done with the Pen class, I've used recursion to build up the tree branch by branch—there's not much code so you should be able to see what's going on—plus there's some example enhancements at the end of the page.

First download Squeak here: http://ftp.squeak.org/4.4/Squeak-4.4-All-in-One.zip 



Start by opening a new Browser from the Tools menu, right click in the first column and add a new category to contain your new class. I called mine 'GeekClub', but you can pick whatever name you like. Now add this new class...

Object subclass: #FractalTree
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'GeekClub'

Add these two methods to the class...

tree: aPoint length: aLength angle: anAngle
    | p a |
        
    (aLength > 10) ifTrue: [
        p := Pen new.
        p up.
        p goto: aPoint.
        p turn: anAngle.
        p down.
        5 timesRepeat: [
            p go: aLength / 5.
            p turn: 5.
        ].
        a := anAngle - 30.
        3 timesRepeat: [
            self tree: p location length: aLength * 0.7 angle: a.
            a := a + 30.
        ]
    ].

draw
    Display restoreAfter: [
        Display fillWhite.      
        self tree: 700@700 length: 200 angle: 0.
    ]

Now open a Workspace and enter:

FractalTree new draw.

You should see a fractal tree like the one above. Click to return to the code view.

Improvements

There's lots of improvements you can make to the above code, try these:

Make thicker branches at the base, add this to the tree method after p up.
p squareNib: aLength / 25.

Add a bit of randomness to the angle between branches, replace a := a + 30. with
a := a + 30 + (20 atRandom).

Find out more

There's a great, free PDF book here if you want to find out more about Squeak: http://squeakbyexample.org/ and the official Squeak site: http://www.squeak.org/