Montag, 31. Oktober 2011

YAML in Ruby 1.9

The other day I downloaded the production database from Zero-X to my local machine to run some tests.
Everything looked fine until I got to the game reports page, which looked wired, especially the agent views. It seemed that every empty field was occupied by an agent "00".

After digging deeper I identified the error in wrong loaded YAML records. Instead of loading a nil I got Syck::PrivateType. A null with only one ! was correctly loaded, but the data from production system had two !, which were loaded differently.

YAML.load ":a: !null"     # => {:a=>nil}
YAML.load ":a: !!null"    # => {:a=>#<Syck::PrivateType:0x000001024e6b98 ,="" @type_id="null" @value="">}

YAML::ENGINE.yamler  #=> "syck"

I tried the same tests on the production system, that runs Ubuntu 10.10 I get the following output:

YAML.load ":a: !null"     # => {:a=>nil}
YAML.load ":a: !!null"    # => {:a=>nil}

YAML::ENGINE.yamler  #=> "psych"

And voilà all data are loaded correctly! The difference is an other YAML Engine, on Mac OS X Snow Leopard Syck is used, while on Ubuntu Psych.
Some investigations later I got the answer. With Ruby 1.9.2 the standard library Syck was replaced with Psych, which depends on the libyaml library. But here it comes, only if it's found when Ruby is compiled. It still uses Sych as a fallback.

So in order to have the same behavior on my local and production system, I had first to install libyaml using ports and then recompile my Ruby.

sudo port install libyaml
rvm install ruby-1.9.2 --with-libyaml-dir=/opt/local/

You could also use homebrew, that has also the advantage that you don't have to specify the path to libyaml. Homebrew installs to /usr/local, which is checked by the install script.

brew install libyaml
rvm install ruby-1.9.2

Starting irb I still had to change to psych explicitly.

YAML::ENGINE.yamler = "psych"

Rails 3 changes automatically to psych if available.

One day later I found out, that I also could install Psych as Gem instead of recompiling Ruby.

gem install psych

UPDATE:

Some other days later, I began a new Rails project and I encountered the following conflict with psych:
../psych.bundle: warning: already initialized constant ANY
../psych.bundle: warning: already initialized constant UTF8
../psych.bundle: warning: already initialized constant UTF16LE
...

If you have psych 1.2.2 installed, than uninstall it again. Psych 1.2.3 should avoid the double laoding.
see here

Samstag, 1. Oktober 2011

Announcing Level Clone War

The second level for the programming game Zero-X is ready. I'm proud to announce the 2nd level Clone War.

The first level Greenfields introduced basic sensors and actions and showed how to control a single population. With Clone War these sensors and actions will be extended. But we also have a new action, now it is possible to split a population.

Split does two things, first it splits the population into two equal sized populations and then moves the new created population to a field of your choice. Split looks the same as move_to it takes a field or position as parameter for the new population.

new_population = old_population.split(field)
new_population = old_population.split(-1, 0)
new_population = old_population.split(x: 1, y: 1)

As we may have multiple populations now, you need to specify the population you want to apply the action:

population_a.look_around
population_b.move_to 1, 1
population_c.size
population_c.resource

As you can see the new introduced action changes quite a lot. In the next blog post I will describe how some well-known actions have been extended.

For more details see the documentation.

Dienstag, 6. September 2011

Winner of 2nd Season Greenfields

Wood Elf strikes again! The winner of the 1st Zero X season is also the winner of 2nd season.

In the 2nd season disengage was introduced and the combat damage, was changed in the favor of the attacker and therefore rewarded a more aggressive behaviour. But little has changed here as a look at the ranking list shows.

As announced at the beginning of this season: you will need an agent with at least an average of 4.0 EPS and 5 tournaments to get to next level "Clone War". Here are the top five agents, who achieved that goal:

6.62 Wood Elf
6.08 Mild Gruyere
6.08 Bulldog
5.66 Rincewind
4.24 Gruyere

The usual suspects at the top, let's have a look at the agents that have won more than one tournament:

1st places
3 Rincewind
2 Wood Elf
2 Bulldog
2 Oreiller

At first glance it looks surprising that Oreiller didn't made it for the next level with two 1st places. But taking a closer look we can see, that it didn't perform very well between the 2nd and 6th tournament. I'm sure he will join soon as well as Tentacle Cat, both are only a few points away.

In the next few blog posts I want to take a closer look at all the new features of the new level Clone War and introduce them step by step.

www.zero-x.net









Sonntag, 29. Mai 2011

Using Ruby 1.9.2 and Bundler with Zero-X

In the last few months I was working on bringing Zero-X to Rails 3. The new agent SDK reflects this changes in using now bundler.
In addition to the Rails migration, I ported Zero-X to Ruby 1.9.2. The next tournament on the 25. June 2011 will be the first running fully on 1.9.2. So make sure you're testing your agents in the future against 1.9.2.

For those not familiar with bundler and how to install Ruby 1.9.2, here some steps to get you started:
First we need Ruby 1.9.2. The easiest way to install it is by using RVM (Ruby Version Manager). You can get it by issuing this command in your shell:
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
Next we need the agent SDK, which you can download form the Zero-X website.

Unpack the SDK and change to that directory. You will now be asked to examine the .rvmrc file. This file tells RVM to use a specific Ruby Version within this directory. In our case the file contains:
rvm use 1.9.2
After controlling the file, type "yes". Now RVM is looking for Ruby 1.9.2 and if it doesn't exists, it will prompt you a warning and the instruction how to install it.
rvm install 1.9.2

Next we need bundler. As we installed RVM for the current user, we don't need to use sudo to install gems.
gem install bundler
Bundler can now install all necessary gems and check their dependcies.
bundle
You are set and ready to go:
bundle exec rake
or
bundle exec autotest
Enjoy!

Montag, 17. Januar 2011

Installing Io on my Mac

Currently I'm reading Seven Languages in Seven Weeks by Bruce Tate. The frist new language to learn is Io, a prototype based language. So I installed it on my Mac running Snow Leopard.
These instructions are not by an expert, but just describes the way it worked for me. If you have any suggestions or improvements feel free to add a comment.

The easiest way to install Io is by using Homebrew.
brew install io
If you want the lastest version from github you can alternatively install Io by hand.

First we need CMake, a cross platform make tool. Download the OS X version and install it.

Update: If you want to use the Socket Addon, you must also install libevent.
sudo port install libevent
or use a the corresponding command if you want to install it with Homebrew.

Then we need the lastest version of Io from github. Unpack it and change to that directory, then issue the following commands:
mkdir build && cd build
cmake ..
sudo make install
This will install libraries to /usr/local/lib and add the commands to /usr/local/bin: io and io_static. Then we're ready to test Io's VM with:
io ../libs/iovm/tests/correctness/run.io
If you get an error like this:
dyld: Library not loaded: libbasekit.dylib
  Referenced from: /usr/local/bin/io
  Reason: image not found
Trace/BPT trap
Then we have to show the linker the way to the libraries:
DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/usr/local/lib
export DYLD_LIBRARY_PATH
I added these two lines to my .profile.

After that you should be ready to get started.
io
Io 20090105
Io> "Hello Io" print
Hello Io==> Hello Io


Update: After playing around with Io, I wanted to try out the Socket Addon. But I got this error:
Io> Socket

  Exception: Object does not respond to 'Socket'
  ---------
  Object Socket                        Command Line 1
The missing libevent library was the cause for this error. Io doesn't complain about it, when compiling, but just skips the addon.

Donnerstag, 18. November 2010

Combat Damage in Season 2

The combat damage in ZeroX has been quite high. Until now the combat damage has been divided inversely proportional to the population size, both agents suffered the same combat damage.
With season 2 this will change in favor of the bigger adversary. The combat damage for the smaller will remain the same. But the damage for the bigger will also be inversely proportional to the population sizes. Let's compare the two algorithms with a seek and destroy sequence with:

  Season 1 Season 2
step   Agent 1 Agent 2 Agent 1 Agent 2
1 population 1000 1500 1000 1500
combat damage 600 600 600 400
2 population 400 900 400 1100
combat damage 276 276 293 107
3 population 124 624 106 993
combat damage 103 103 96 11
4 population 21 521 10 982
combat damage 20 20 10 1
5 population 1 501 0 981

As in season 1 both adversary were classified excat the same, therefore they suffered the same damage. The bigger one could never take advantage of his population superiority. This will now be considered.

Mittwoch, 10. November 2010

Secure your steps, how to disengage from a move action

Update: This feature has been removed in with the beginning of the 3rd season. Instead use look_at for agents in level Clone War.

In Zero X the simulation and all agents are running continuously. That's one big difference to other programming games, that usually are round based. The consequence is, that in the time between an agent inspects his environment with a look_around and the action he takes, with a move_to for example, the environment can change.
For example a field is free, when he makes the look_around, but has been occupied in the meanwhile by another agent, when he moves. This would result in a unintended attack against this other agent.

Although this case is rare, as a look_around and a move_to are very close. But this time gape can grow bigger as the analysis of the environment takes more time. In general agents have to deal with this kind of insecurity about their perception. This one of the many challenges in this game.

But in order to handle better this kind of insecurity, starting with season 2, move_to can now take a block.
move_to(x,y) {|target| ... }
The argument passed to the block is another view of the target field at the exact time of the movement. This gives the agent the chance to check the preconditions of his action. If they are not fulfilled anymore, he can now disengage from the move action.

move_to(x,y) do |target|
  unless target.has_no_population?
     disengage 'field is not free anymore!'
  end
end
Disengage can take a message, that will then be displayed in your reports. The action is canceled and the agent remains on his starting field. But disengage comes not for free. A move_to would cost 6 action points, disengage from this action still costs 3 action points.

Disengage can only be used within an action block like the one in move_to.