#!/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)