CGOS "rotation" script II

[ Posted by Urban Hafner Sat, 01 Dec 2007 14:29:26 GMT ]

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)]
  puts "[#{time}] Running '#{bot[:bot]}' (#{bot[:script]}) for #{bot[:games]} games"
  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]}, #{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 , , , , , , , , ,  | no comments | no trackbacks

CGOS "rotation" script

[ Posted by Urban Hafner Wed, 10 Oct 2007 14:18:38 GMT ]

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 , , , , , ,  | no comments | no trackbacks

Euruko 2007

[ Posted by Urban Hafner Tue, 18 Sep 2007 08:46:38 GMT ]

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 , , , ,  | no comments | no trackbacks

Fico 0.1.1

[ Posted by urban Mon, 11 Apr 2005 19:29:58 GMT ]

This release is just a point release that makes the following changes:

  • Added script to run tournaments of AIs
  • Fixed bug that prevented the Board class from recognizing certain finished board positions.
  • Added support for draws

As before the tarball can be gotten from bettong.net/fico/ and the latest development version from the darcs repository at http://www.cip.ifi.lmu.de/~hafner/darcs/fico .

Tags , , , , ,

Fico Version 0.1.0

[ Posted by urban Sun, 10 Apr 2005 14:17:54 GMT ]

Fico is an implementation of the board game Havannah. It is completley written in Ruby.

The aim is to write a fairly strong AI for the game. At the moment the only features are that the program can play according to the rules and that a random player exists.

How to get it

There are two ways to get the program.

  1. Get fico-0.1.0.tar.bz2, the latest release tarball (generally new releases can be found at bettong.net/fico/)
  1. Get the latest development from the darcs repository: darcs get http://www.cip.ifi.lmu.de/~hafner/darcs/fico.

How to run it

To run fico against itself on a board of size 10 run the command ./fico in the toplevel directory. Run ./fico -h to see all possible command line options.

If you want to play against the program use the -b or -w switch to select your colour. You will then be asked to enter your moves in the terminal. Be sure to enter them in the form <char><number> (e.g. a1 or c4).

Hacking

You are of course welcome to write your own AI. But don’t expect to much (yet :)) from the framework that binds your bot into the rest of the application.

How to build your own AI

Look at src/player/RandomPlayer.rb for a simple AI. The necessary steps to get your own bot running are:

  • create a sublcass of ComputerPlayer
  • include TermComputerPlayer
  • define the method internal_generate_move. This method should return the next move of your AI.
  • patch src/fico.rb so that it uses your AI instead of RandomPlayer or Simple1Ply

Contact

You can contact me at urban@bettong.net. Watch this place for announcements of new versions.

Tags , , , , ,