CGOS "rotation" script II

[Posted by Urban Hafner on 01 Dec 2007]

Here’s the updated cgos.rb script. The main change is that the bots are chosen at random (instead of in the order specified).

#!/usr/bin/env ruby
#
# Run bots one after the other on CGOS. The BOTS variable is an array
# if directories of the bots. In each of these directory there has to
# be an executable file called 'cgos.sh' that connects the bot to CGOS.
# This executable is also required to set the sentinel file name to the
# one given in the TERM variable below.

require 'optparse'

# :bot    :: The directory containing you cgos connection script
# :script :: The name of the script (defaults to cgos.sh)
# :games  :: The number of games the bot should play in a row
BOTS = [
  {:bot => "libEGO-AMAF-3"},
  {:bot => "libEGO-AMAF-2"},
  {:bot => "erlygo"},
  {:bot => "libEGO-AMAF-2", :script => "cgos19.sh"},
  {:bot => "libEGO-AMAF-3", :script => "cgos19.sh"},
  {:bot => "erlygo",        :script => "cgos19.sh"}
]
# Sentinel filename to be used by CGOS
TERM     = "stop.txt"
$verbose = false

round       = 0
total_games = 0
games       = Hash.new {|h,k| h[k] = 0}

opts = OptionParser.new
opts.on("-v", "--verbose") { $verbose = true }
opts.on("-s", "--stop") do
  File.new(TERM, "w")
  exit
end

opts.parse(ARGV)

def time
  Time.now.strftime("%H:%M:%S")
end

# Clean up (if script wasn't terminated correctly)
(BOTS+[{:bot => "."}]).each do |bot|
  bot[:games]  = 1         unless bot[:games]
  bot[:script] = "cgos.sh" unless bot[:script]
  Dir.chdir(bot[:bot]) do
    File.delete(TERM) if File.exists?(TERM)
  end
end

until(File.exists?(TERM))
  round += 1
  if (round % 5).zero?
    games.each do |k,v|
      puts "#{sprintf("%03d", v)} games for '#{k}'"
    end
  end
  bot = BOTS[rand(BOTS.length)]
  msg = "[#{time}] Running '#{bot[:bot]}' (#{bot[:script]})"
  msg += " for #{bot[:games]} games" 
  puts msg
  last_was_print = false
  Dir.chdir(bot[:bot]) do
    IO.popen("./#{bot[:script]} 2>/dev/null") do |pipe|
      until(pipe.eof?)
        line = pipe.gets
        if $verbose
          puts line
          STDOUT.flush
        end
        case line
        when /gameover/
          line =~ /gameover\s+\d\d\d\d-\d\d-\d\d\s+(\S+)/
          print "\n" if last_was_print
          puts "[#{time}] #{$1}"
          last_was_print = false
        when /setup/
          File.new(TERM, "w") if games[bot[:bot]] >= (bot[:games]-1)
          games[bot[:bot]] += 1
          total_games      += 1
          line =~ /setup\s+.*?(\S+\(.*\)\s+\S+\(.*\))/
          print "\n" if last_was_print
          stats = "(game #{games[bot[:bot]]} of #{bot[:games]},"
          stats += "#{total_games} games in total)"
          puts "[#{time}] #{$1} #{stats}"
          last_was_print = false
        when /info/
          unless $verbose
            print "."
            STDOUT.flush
            last_was_print = true
          end
        end
      end
    end
    File.delete(TERM) if File.exists?(TERM)
  end
  round += 1
end
File.delete(TERM)

Tags cgos, go, ai, game, computer, computer go, ruby, computer-go, baduk, weiqi

CGOS "rotation" script

[Posted by Urban Hafner on 10 Oct 2007]

While playing around with libEGO and trying to see how far I can get with a simple “all-moves-as-first” Monte Carlo bot. I wrote many (well, three) different versions of the same bot and tested them against each other. Of course for a real test I had to use CGOS. But as I only have one computer that I also use for work I had to run the different bots one after the other. To automate that I wrote a small script that lets you run any number of bots in rotation on CGOS.

It’s a very simple script written in Ruby, so you’ll need to have that installed. For the rest see the comments at the beginning of the file.

#!/usr/bin/env ruby
#
# Run bots one after the other on CGOS. The BOTS variable is an array
# if directories of the bots. In each of these directory there has to
# be an executable file called 'cgos.sh' that connects the bot to CGOS.
# This executable is also required to set the sentinel file name to the
# one given in the TERM variable below.

# Number of games for each bot
GAMES = 1
# The bots that should play
BOTS = ["libEGO-AMAF", "libEGO-AMAF-2", "libEGO-AMAF-3"]
# Sentinel filename to be used by CGOS
TERM  = "stop.txt"

round = 0

if ARGV.length > 0 and ARGV.first == "stop"
  File.new(TERM, "w")
  exit
end

# Clean up (if script wasn't terminated correctly)
(BOTS+["."]).each do |dir|
  Dir.chdir do
    File.delete(TERM) if File.exists?(TERM)
  end
end

until(File.exists?(TERM))
  dir = BOTS[round % BOTS.length]
  puts "[#{Time.now}] Round #{round+1}"
  puts "[#{Time.now}] Running '#{dir}' for #{GAMES} games"
  last_was_print = false
  Dir.chdir(dir) do
    games = 0
    IO.popen('./cgos.sh 2>/dev/null') do |pipe|
      until(pipe.eof?)
        line = pipe.gets
        if line =~ /setup/
          games += 1
          File.new(TERM, "w") if games >= (GAMES-1)
        end
        case line
        when /gameover/
          line =~ /gameover\s+\d\d\d\d-\d\d-\d\d\s+(\S+)/
          print "\n" if last_was_print
          puts "[#{Time.now}] #{$1}"
          last_was_print = false
        when /setup/
          line =~ /setup\s+.*?(\S+\(.*\)\s+\S+\(.*\))/
          print "\n" if last_was_print
          puts "[#{Time.now}] #{$1}"
          last_was_print = false
        when /info/
          print "."
          STDOUT.flush
          last_was_print = true
        end
      end
    end
    File.delete(TERM)
  end
  round += 1
end
File.delete(TERM)

Tags go, computer, computer go, ruby, computer-go, baduk, weiqi

Euruko 2007

[Posted by Urban Hafner on 18 Sep 2007]

As Stephan Kämper already announced on his blog the European Ruby Konferenz will be held in Vienna, Austria on Saturday & Sunday 10th and 11th November 2007.

If you want to attend just add yourself to the wiki!

Hope to see many of you there!

Tags ruby, conferenz, euruko, vienna, austria

How To Give A Great Man To Man Hug

[Posted by Urban Hafner on 31 Aug 2007]


VideoJug: How To Give A Great Man To Man Hug

Tags fun, video

The end of a mountain

[Posted by Urban Hafner on 25 Aug 2007]



The end of a mountain, originally uploaded by AntonisP.


That’s what’s happening all over Greece right now :(

Tags greece, fire, burn, death, destruction

Ein Grundgesetz für Schäuble

[Posted by Urban Hafner on 14 Aug 2007]

Ein Grundgesetz für Schäuble (klein)

Vielleicht etwas spät, aber besser als nie. Ich bin gerade auf ein Blog Post von Frank Wettert gestoßen, der dazu auffordert ein Exemplar des Grundgesetzes an Wolfgang Schäuble zu schicken. Recht hat er. Meine Exemplare (3 Exemplare kostenlos vom Deutschen Bundestag zu erhalten) sind schon unterwegs. Sobald eure Exemplare bei euch angekommen sind bitte eines der Exemplare (vielleicht mit einem erklärenden Brief dazu) an folgende Adresse schicken:

Herr Dr. Wolfgang Schäuble
Bundesministerium des Innern
Alt-Moabit 101
D-10559 Berlin

Vielleicht hilft es ja seinen Überwachungswahn zu stoppen. Einen Versuch ist es zumindest wert.

Tags german, democracy, grundgesetz

Lighttpd gotchas

[Posted by Urban Hafner on 06 Jun 2007]

I just tried to setup lighttpd (1.4.13) to run several sites side by side and run one of them on a different port. The following things should be noted:

server.prot

You can’t just set server.port. It’s a global variable a overwrites the previous ones.

$SERVER[“socket”] and $HTTP[“host”]

Using $SERVER["socket"] and $HTTP["host"] together doesn’t work. I tried to do the following:

$SERVER["socket"] == "0.0.0.0:5005" {
  $HTTP["host"] == "example.com" {
    server.errorlog    = "/error.log"
    accesslog.filename = "/access.log"
    proxy.balance = "fair"
    proxy.server = ( "/" =>
                     (("host" => "127.0.0.1", "port" => 5001))
                   )
  }
}

But that doesn’t work! I ended up removing the $HTTP["host"] part. Which is not that nice as you can now access the site on port 5005 using all the other URLs defined in the config file!

Are there any solutions to this problem?

Tags lighttpd, port, webserver

Better recommendations for IT Conversations

[Posted by Urban Hafner on 10 May 2007]

I’m a regular listener of IT Conversations. But of course I don’t have the time to listen to all podcasts. And anyway there are many that I don’t even want to listen to. So, IT Conversations has a rating system and can give you recommendations. But for that to work you have to remember to go to their website to rate the shows you have listened to. Very cumbersome if you listen to the shows on your iPod somewhere in the wild. But it seems things might change as Phil Windley is asking if You Would Let IT Conversations See Your Podcast Ratings in iTunes?. Seems like a great idea to get some more out of the recommendation system.

Tags podcast, ITConversations, ratings

The new Web 2.0 car

[Posted by Urban Hafner on 08 May 2007]



Our new car, originally uploaded by Mélisande*.

Tags flickr, photo, web 2.0, fun

Programming Erlang

[Posted by Urban Hafner on 02 Mar 2007]

The last weeks I’ve heard some podcasts with Dave Thomas and in passing he mentioned that Joe Armstrong is writing a book on Erlang for them.

I’ve been interested in Erlang for quite a while but didn’t find time to look into it. But now that Dave Thomas (nearly) announced the beta release of their book I’m really exited. Once I find the money for the book I’ll definitely give it a try.

Oh, in case you’re wondering where to find the book just go to Dave’s blog post where he mentions how to find the book. It’s not that hard!

Update (one hour later): Well, I couldn’t wait and ordered it anyway. I just had to capitalize on the strong Euro ;)

Update (14 hours later): As Dave announced it already on the ruby-talk mailing list, here’s the link to the book page: http://www.pragmaticprogrammer.com/titles/jaerlang/

Tags pragmatic programmers, erlang, book