Here's an interesting programming puzzle (thanks Nige). The challenge is to write a (stateless?) control function for a warrior, and have it fight its way up the stairs to the next level. This is the level I'm stuck on:Level 6
The wall behind you feels a bit further away in this room. And you hear more cries for help.
Tip: You can walk backward by passing ':backward' as an argument to walk!. Same goes for feel, rescue! and attack!. --------
|C @ S aa|
--------
> = Stairs
@ = groo (20 HP)
C = Captive (1 HP)
S = Thick Sludge (24 HP)
a = Archer (7 HP)
Available Abilities:
warrior.walk!
Move in given direction (forward by default).
warrior.rest!
Gain 10% of max health back, but do nothing more.
warrior.feel
Returns a Space for the given direction (forward by default).
warrior.health
Returns an integer representing your health.
warrior.rescue!
Rescue a captive from his chains (earning 20 points) in given direction (forward by default).
warrior.attack!
Attack the unit in given direction (forward by default).
Give it a shot.
Aug 29, 2009
Ruby Warrior
Posted
11:36 PM
0
comments
Links to this post
Why Groovy? Why Not Ruby?
I was talking to an old friend and telling him that I was coding a lot in Groovy in my spare time. He asked me why I wasn't coding my project in Ruby. I really didn't have a good answer for him.
In fact I just looked back at some old Ruby code of mine and it does in fact look very similar to the Groovy code I've been writing. Hmm.
Posted
6:36 PM
3
comments
Links to this post
Aug 15, 2009
Opening Ports to a Virtualbox VM
If you want to be able to connect to a service running on your Virtualbox VM, this is how to go about it. (global means it applies to any Virtualbox VM you run)See the full documentation for more info.$ VBoxManage setextradata global "VBoxInternal/Devices/pcnet/0/LUN#0/Config/serviceName/Protocol" TCP
$ VBoxManage setextradata global "VBoxInternal/Devices/pcnet/0/LUN#0/Config/serviceName/GuestPort" portInVM
$ VBoxManage setextradata global "VBoxInternal/Devices/pcnet/0/LUN#0/Config/serviceName/HostPort" portExposedAs
Posted
11:03 PM
0
comments
Links to this post
Labels: vm
Setting Up Telnetd
Every couple of years I want to setup telnetd on my linux box again. Each time I get telnetd installed and then try and figure out why it's not started. So this time around this is what I needed to do:This included openbsd-inetd for me. However:sudo apt-get install telnetd
reported:sudo /etc/init.d/openbsd-inetd restart
The missing step was to include this line in /etc/inetd.conf:Not starting internet superserver: no services enabled.
telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd
Posted
10:54 PM
0
comments
Links to this post
Aug 5, 2009
Start the Day Laughing
On my way in to work I walked past a corporate van for a company called Conejo something or rather. I bet the founders knew "conejo" meant "rabbit", yet probably not that it means something else as well!
Posted
7:44 PM
0
comments
Links to this post
Labels: fun
Aug 4, 2009
An Internal DSL in Groovy
There's an approach to robotic control called Reactive Action Packages. It's a way of specifying what to what, when, in what sequence, and with what taking priority over what. All of it specified in a robust manner and driven by external sensors. Anyway, I've coded my take on RAPs a number of times and never really been happy with the result. This time though my solution really feels right. Groovy builders work so well here:The basic idea is that this DSL can be evaluated each time my robot needs to take an action. DSL statements are evaluated in sequence until one provides an action. So, if it's lost it explores. If it's not lost and it's score is under 1000 and it's already at somePlace then it does someAction. Sweet!
this.brain = new NodeBuilder()
.code {
when('lost') {
explore()
}
when('score < 1000') {
go('somePlace')
someAction()
}
}
The only gotcha to evaluating the NodeBuilder result is that closure('aString') statement1 ; statement2 } evaluates to a Node whose value() is ['aString', node1, node2]:this.eval = { code ->
if (code instanceof Node) {
return evalNode(code)
}
def iterator = code.iterator()
def result = null
while(!result && iterator.hasNext()) {
def node = iterator.next()
result = eval(node)
}
return result
}
this.evalNode = { node ->
def result = actions[node.name()](node.value())
return result
}actions are defined easily enough:The last piece of the puzzle is setting up the this.actions = [
when: { args ->
if (shell.evaluate(args[0])) {
return eval(args[1,-1])
}
return false;
},
explore: { "EXPLORE" },
go: { to ->
def loc = shell.evaluate("loc")
if (loc == to) {
return false
}
def direction = navigator.directionTo(loc, to)
return "DIR $direction"
},
someAction: { "SOME_ACTION" }]GroovyShell with it's context and evaluating the DSL code:To those who made builders a part of Groovy: thanks so much!this.act = {
shell = new GroovyShell()
shell.setVariable("loc", loc)
shell.setVariable("score", score)
def action = eval(brain.value())
if (action) {
// do magic
} else {
println "No action chosen!"
}
}
Posted
11:28 PM
1 comments
Links to this post
Aug 2, 2009
Git At Home
Setting up your own git server at home is easy enough. Once you have sshd running (or Remote Login enabled), your friends for interacting with the remote repository are:git clone username@machineIP:path
git remote add remoteRepoNickname username@machineIP:path
git push remoteRepoNickname branchName
git pull remoteRepoNickname branchName
I got started using Pragmatic Version Control Using Git. There's also an online book: Pro Git.
Above and beyond 'there is no server', the main thing I needed to get my head around was that git has the concept of 'staging' commits. For example:
git add filewill stagefile's deltas.git statuswill show you your staged changes.git commit -m 'comment'will then commit your staged changes.git push remoteRepoNickname masterthen pushes your committed changes to another machine.
Posted
5:42 PM
0
comments
Links to this post
Labels: git