Just had 10 minutes to look at this, and created a quick test harness to
compare players before I go poking around trying to figure out what kind
of logic to use.

Pass in the list of ruby files containing players, optionally preceeded
with a count for the number of games to play, and also a random seed (to
keep consistent results between runs).

All players will be given the same game to play with (the same set of
random seeds will be used).

Make sure you call "super" in your player's init to get it setup
properly.

Hope this encourages more entries.


require 'lost_cities'
require 'nano/enumerable/each_combination'

class Player
  @@players = []
  def self.inherited( subclass )
    @@players << subclass unless subclass == SocketPlayer
  end
  def self.players
    @@players
  end
end
class Game
    public :score
end

count = 10
count = ARGV.shift.to_i if /^\d*$/=== ARGV[0]
srand(ARGV.shift.to_i) if /^\d*$/=== ARGV[0]

ARGV.each { |file| require file } if ARGV.length > 0

RecordStruct = Struct.new( :type, :wins, :scores )
records = Hash.new { |h,k| h[k] = RecordStruct.new(k.to_s, 0, []) }

seeds = Array.new(count) { rand }

play_proc = lambda do |players|
    p "Playing #{players.inspect}"
    players.map! { |x| x.new }
    seeds.each do |seed|
        srand(seed)
        game = Game.new(*players)
        until game.over?
            game.rotate_player
            game.play
            game.draw
        end
        scores = players.map{ |player| game.score(player.lands)
}.zip(players.map {|player| player.class})
        scores = scores.sort_by { |a,b| a }
        scores.each { |a,b| records[b].scores << a }
        records[scores[-1][1]].wins += 1
    end
end

#~ if(Player.players.size > 1)
    #~ Player.players.each_combination(2, &play_proc)
#~ else
    Player.players.map{ |x| [x,x] }.each(&play_proc)
#~ end

puts
printf("%-30s %4s  %5s  %5s  %5s", "Class", "Wins", "Avg.", "Min.",
"Max.")
puts
records.values.sort_by {|r| -r.wins}.each { |record|
    printf("%-30s %4d  %2.2f  %2.2f  %2.2f", 
        record.type, 
        record.wins, 
        record.scores.inject(0) { |s,x| s + x }
/record.scores.size.to_f,
        record.scores.min,
        record.scores.max)
}
#####################################################################################
This email has been scanned by MailMarshal, an email content filter.
#####################################################################################