Files
glicko2/rb/xmlrate.rb
T
swaits f88f2d020b added minor unit test
finished implementation of xmlrate.rb
2005-05-11 23:32:34 +00:00

108 lines
2.5 KiB
Ruby

#!/usr/bin/env ruby
require "rexml/document"
require "glicko2"
# sort & output the player array
def output_players(playerhash,title="")
puts title
sorted_players = playerhash.sort { |a,b| a[1] <=> b[1] }
i = 0
sorted_players.reverse.each { |k,v| puts sprintf("%3d%30s: %6.1f +/- %5.1f %0.05f\n",i += 1,k,v.rating,v.deviation,v.volatility) }
puts
end
# handle one file
def parse_file(filename)
# load & parse XML
file = File.new(filename)
doc = REXML::Document.new(file)
# each rating doc
doc.elements.each("ratingdoc") do |root|
# new/empty player hash
players = Hash.new
# each player
root.elements.each("player") do |player|
# setup defaults
name = player.elements["name"].text
rating = 1500.0
deviation = 350.0
variance = 0.06
# TODO: find better "Ruby-esqe" way of doing these
if player.elements["rating"]
rating = player.elements["rating"].text
end
if player.elements["deviation"]
deviation = player.elements["deviation"].text
end
if player.elements["variance"]
variance = player.elements["variance"].text
end
# create player + glicko2 object
players[name] = Glicko2.new(rating.to_f,deviation.to_f,variance.to_f)
end
# dump initial player ratings
output_players(players,"initial ratings")
# each rating period
period_id = 0
root.elements.each("period") do |period|
# each regular game
period.elements.each("game") do |game|
home = game.elements["home"].text
away = game.elements["away"].text
result = game.elements["result"].text
result_val = Glicko2::WIN if result == "win"
result_val = Glicko2::LOSS if result == "loss"
result_val = Glicko2::DRAW if result == "draw"
players[home].add_result( players[away], result_val )
players[away].add_result( players[home], 1.0 - result_val )
end
# each race
racelist = []
period.elements.each("race") do |race|
race.elements.each("competitor") do |c|
# make this competitor lose to everyone already in our list
racelist.each do |otherc|
players[otherc].add_win(players[c.text])
players[c.text].add_loss(players[otherc])
end
# add this competitor to our list
racelist.push(c.text)
end
end
# update all players
players.each_value { |p| p.update }
# output players
output_players(players,sprintf("after rating period %d",period_id += 1))
end
end
end
# main program
ARGV.each { |a| parse_file(a) }