I'm pleased to announce, that I released the beta version of Zero X yesterday.
Zero X is a programming game, that let's you create an agent program, that will then compete with others agents in different tournaments.
The first test tournament will take place this month, the exact date will be announced in this blog.
If you are interested in artificial intelligence, artificial life, robotics or cybernetic systems then check it out!
www.zero-x.net
Montag, 1. März 2010
Freitag, 26. Februar 2010
How to initialize your agent
Since last week the first beta testers could access the stage environment of Zero X.
I received some first feedbacks and could already fullfill one of the wishes.
In order to have a proper place to initialize the agent, a first callback method has been introduced. Right after the agent has been started after_start is called once.
Thanks to Tungmar for his feedback!
In order to have a proper place to initialize the agent, a first callback method has been introduced. Right after the agent has been started after_start is called once.
module Demo
class Example < Tournament::Agent
def after_start
# initialize
end
def think
# called periodically
end
end
end
after_start is called just after the thread for the agent has been forked and one step before the think loop. Here's a simplificated code snippet from the game class, to see how it's implemented:
Thread.fork do
agent.after_start
begin
agent.think
end until stopped?
end
In your test cases the agent should now be created again before each test, as create_agent also calls after_start.
before :all do load_field_fixtures 'greenfields' end before :each do @agent = create_agent Demo::TheGood endThere's also a test helper method create_agent_without_start, if you need to set test expectations before calling after_start.
Thanks to Tungmar for his feedback!
Samstag, 20. Februar 2010
Avoid Ruby 1.8.7 p248 and p249 with ActiveSupport
Yesterday I updated the stage environment of Zero X to ruby 1.8.7, but after that I suddenly couldn't login anymore. The problem was a Segmentation fault in Marshal.load used by ActiveSupport:
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.3/lib/active_support/multibyte/unicode_database.rb:37: [BUG] Segmentation fault ruby 1.8.7 (2010-01-10 patchlevel 249) [powerpc-darwin8.11.0]As described in the ticket the error occurs only in patchlevel 248 and 249. So I had to go back to p174 and now everything runs smoothly again.
Sonntag, 7. Februar 2010
Codename Zero X
Zero X is a new programming game, written in ruby and made to write in ruby. The first level is based on the greenfield scenario described in an early (german) post.
The players can code agents, which then will be uploaded to participate to the tournaments.
I hope to release a first beta version still this month, until then I leave you with a first screenshot showing the ranking page:
The players can code agents, which then will be uploaded to participate to the tournaments.
I hope to release a first beta version still this month, until then I leave you with a first screenshot showing the ranking page:
Labels:
programming game,
Ruby,
scenario greenfields,
zero x
Donnerstag, 24. September 2009
Migration auf Ruby 1.9.1
In den letzten Tagen habe ich mein Simulation Projekt auf Ruby 1.9 migriert. Leider verlief die Migration nicht ganz so einfach, wie ich mir das vorgestellt hatte. Teilweise muss nämlich eine exakte Version eines Gems installiert werden, ansonsten hagelt es Fehlermeldungen.
Um Ruby 1.8 und 1.9 parallel auf meinem Mac betreiben zu können, habe ich RVM installiert. Dies installiert alle zusätzlichen Ruby Versionen im Home-Verzeichnis unter .rvm. Zudem werden auch alle command line Befehle wie etwa 'rails' oder 'cucumber' separat gehandhabt. Unter RVM ist allerdings zu beachten, dass alle so hinzugefügten Gems nicht mit sudo installiert werden. Zudem musste ich eine frühere Version von Ruby 1.9, die ich noch unter /usr/local hatte, zuerst wegputzen.
Ich will hier nicht alle Leerläufe beschreiben, deshalb hier gleich die hoffentlich richtig Anleitung:
Um auf Ruby 1.9 zu wechseln:
Danach wenden wir uns gleich Rails selber zu. Die neuste Version 2.3.4 ist leider nicht lauffähig unter Ruby 1.9. Wenn auf die Session zugegriffen wird, erhaltet man folgenden Fehler:
Um Ruby 1.8 und 1.9 parallel auf meinem Mac betreiben zu können, habe ich RVM installiert. Dies installiert alle zusätzlichen Ruby Versionen im Home-Verzeichnis unter .rvm. Zudem werden auch alle command line Befehle wie etwa 'rails' oder 'cucumber' separat gehandhabt. Unter RVM ist allerdings zu beachten, dass alle so hinzugefügten Gems nicht mit sudo installiert werden. Zudem musste ich eine frühere Version von Ruby 1.9, die ich noch unter /usr/local hatte, zuerst wegputzen.
Ich will hier nicht alle Leerläufe beschreiben, deshalb hier gleich die hoffentlich richtig Anleitung:
Um auf Ruby 1.9 zu wechseln:
rvm install 1.9 rvm use ruby 1.9Darauf installiert RVM automatisch die aktuelle 1.9 Version.
Danach wenden wir uns gleich Rails selber zu. Die neuste Version 2.3.4 ist leider nicht lauffähig unter Ruby 1.9. Wenn auf die Session zugegriffen wird, erhaltet man folgenden Fehler:
undefined method `^' for "c":String (NoMethodError)Deshalb muss auf 2.3.3 zurückgegriffen werden:
gem install -v='2.3.3' railsMein Projekt nutzt Cucumber und RSpec als Testframeworks. Hier können zwar die neusten Versionen installiert werden, jedoch muss auch Test-Unit mit der Version 1.2.3 und zwar exakt diese mitinstalliert werden:
gem install cucumber rspec rspec-rails webrat gem install -v="1.2.3" test-unitAls nächstes meldete Nokogiri, das von Webrat genutzt wird, einen Konflikt:
dyld: lazy symbol binding failed: Symbol not found: _rb_intern2 Referenced from: /Users/adm/.rvm/gems/ruby/1.9.1/gems/nokogiri-1.3.3/lib/nokogiri/nokogiri.bundle Expected in: flat namespace dyld: Symbol not found: _rb_intern2 Referenced from: /Users/adm/.rvm/gems/ruby/1.9.1/gems/nokogiri-1.3.3/lib/nokogiri/nokogiri.bundle Expected in: flat namespace Trace/BPT trapUm diesen Konflikt zu lösen musste ich über Ports meine libxml Bibliothek aktualisieren und Nokogiri nochmals installieren:
sudo port install libxml2 sudo port install libxslt gem install nokogiriDanach startete mein Projekt endlich unter Ruby 1.9 auf. Meine eignen Konflikte mit 1.9 konnte ich dank meinen Testsuits innerhalb einer halben Stunde lösen. Gute Tests sind wirklich Gold wert.
Mittwoch, 26. August 2009
Nested Synchronize Blocks
In my new simulation project I have different threads accessing objects. The simulation server calculates periodically their states and the tournament server, handling all agents, is accessing them over distributed Ruby. Therefore I need to synchronize the sim objects. My first attempt looked something like this:
But I needed a different behaviour, I want to synchronize the objects from different threads. As far as I remember Java's synchronize behaves the same way.
Using rspec we could specify this behaviour with 2 tests:
For the second test we need two different threads. The first thread locks the object and lunches a second thread. The first one returns immediately after fork, while the second one is launched in the meantime. So while the first is waiting for a second, the second thread is trying to achieve the lock and is blocked until the first one releases it on line 12. Only now the second thread gets access to the object and can set wait_for_me to false.
Of course both tests fail (or get some deadlocks) with the implemention above. The second version of synchronize looks now like this:
class SyncObject
def initialize
@semaphore = Mutex.new
end
def synchronize &block
@semaphore.synchronize &block
end
end
Before changing something in the sim objects, I synchronize them :
object.synchronize do
# change the state of the object
end
But as things were growing, I suddently got some deadlocks. After some research I found out, that a thread was invoking synchronize on the same object multiple times. The semaphore object doesn't care which thread is locking it. As long it's locked it will block all threads until the block is finished. Even if it's the same thread, that locked the semaphore just before.
But I needed a different behaviour, I want to synchronize the objects from different threads. As far as I remember Java's synchronize behaves the same way.
Using rspec we could specify this behaviour with 2 tests:
it "should not block the same thread when synchronizing" do
object = SyncObject.new
object.synchronize do
object.synchronize do
object.synchronize do
true.should be_true
end
end
end
end
it "should block two different threads when synchronizing" do
object = SyncObject.new
wait_for_me = true
object.synchronize do
Thread.fork do
object.synchronize do
wait_for_me = false
end
end
sleep 1
wait_for_me.should be_true
end
wait_for_me.should be_false
end
The first test's pretty straight forward, we want to allow nested synchronize blocks for the same thread.For the second test we need two different threads. The first thread locks the object and lunches a second thread. The first one returns immediately after fork, while the second one is launched in the meantime. So while the first is waiting for a second, the second thread is trying to achieve the lock and is blocked until the first one releases it on line 12. Only now the second thread gets access to the object and can set wait_for_me to false.
Of course both tests fail (or get some deadlocks) with the implemention above. The second version of synchronize looks now like this:
class SyncObject
def initialize
@semaphore = Mutex.new
end
def synchronize
unless @current_thread == Thread.current
@semaphore.synchronize do
@current_thread = Thread.current
yield
@current_thread = nil
end
else
yield
end
end
end
The first time synchronize is accessed, @current_thread is set to the current running thread. The semaphore is locked and the blocked yield. If in the meantime a different thread invokes synchronize, it will be blocked until the first one finishes the block. Else if the same thread access the method in the meantime, it will not try to lock the semaphore again, but can yield its new block immediately.
Labels:
Concurrency,
Java,
Ruby
Donnerstag, 13. August 2009
Migrating to Cucumber
Today I migrated my simulation project to Cucumber. Until now I used rspec's plain text user stories.
The first part, migrating the rails application, was easy thanks to the good documentation in the wiki. The second part, the simulation server, was surprisingly easy as well. All I had to do was creating the same directory structure and following the same steps to move the files from stories to features as for the rails app. Then I removed all rails related lines from env.rb and added my init file, that loads all the classes for the simulation server.
The first part, migrating the rails application, was easy thanks to the good documentation in the wiki. The second part, the simulation server, was surprisingly easy as well. All I had to do was creating the same directory structure and following the same steps to move the files from stories to features as for the rails app. Then I removed all rails related lines from env.rb and added my init file, that loads all the classes for the simulation server.
require File.expand_path(File.dirname(__FILE__)+'/../../init') # Comment out the next line if you don't want Cucumber Unicode support require 'cucumber/formatter/unicode'To run the stories I need to execute cucumber features/ in the corresponding direcotries. Running the rake features doesn't work for me as env.rb is not loaded.
Labels:
Cucumber,
RSpec,
simulation
Abonnieren
Posts (Atom)
