OSDN Git Service

Merge branch '201303-yamashita_matching' into wdoor-stable
[shogi-server/shogi-server.git] / mk_rate
diff --git a/mk_rate b/mk_rate
index f935acb..3678b45 100755 (executable)
--- a/mk_rate
+++ b/mk_rate
 #
 # == Synopsis
 #
-# mk_rate reads CSA files, calculates rating scores of each player, and then
-# outputs a yaml file (players.yaml) that Shogi-server can recognize.
+# mk_rate reads game results files generated by the mk_game_results command,
+# calculates rating scores of each player, and then outputs a yaml file 
+# (players.yaml) that Shogi-server can recognize.
 #
 # == Usage
 #
-# ./mk_rate [options] DIR..
+# ./mk_rate [options] GAME_RESULTS_FILE [...]
+#
+# ./mk_rate [options]
 # 
-# DIR::
-#   CSA files are recursively looked up the directories.
+# GAME_RESULTS_FILE::
+#   a path to a file listing results of games, which is genrated by the
+#   mk_game_results command.
+#   In the second style above, the file content can be read from the stdin.
 #
 # --base-date::
 #   a base time point for this calicuration (default now). Ex. '2009-10-31'
 #   m [days] (default  7)
 #   after m days, the half-life effect works
 #
+# --ignore::
+#   m [days] (default  365*2)
+#   old results will be ignored
+#
 # --fixed-rate-player::
 #   player whose rate is fixed at the rate
 #
 #
 #   $ sudo gem install rgl
 #
-# == Run
+# == Examples
 #
-#   $ ./mk_rate . > players.yaml
+#   $ ./mk_rate game_results.txt > players.yaml
 #
-# or, if you do not want the file to be update in case of errors, 
+#   $ ./mk_game_results . | ./mk_rate > players.yaml
 #
-#   $ ./mk_rate . && ./mk_rate . > players.yaml
+# If you do not want the file to be update in case of errors, 
+#
+#   $ ./mk_rate game_results.txt && ./mk_rate game_results.txt > players.yaml
 #
 # == How players are rated
 #
@@ -339,6 +350,7 @@ class Rating
       old_f      = f
       old_f_nrm2 = old_f.nrm2
       deaccelrate(1.0, old_rate, a, old_f_nrm2)
+      #@rate -= a # Instead, do not deaccelerate
       @record.set(func_vector.nrm2, @rate)
 
       $stderr.printf "|error| : %5.2e\n", a.nrm2 if $DEBUG
@@ -355,6 +367,7 @@ class Rating
     @rate = @record.get
     $stderr.puts "resolved f: %s -> %f" %
       [func_vector.to_a.inspect, func_vector.nrm2] if $DEBUG
+    $stderr.puts "Count: %d" % [@count] if $DEBUG
 
     @rate *= 1.0/K
     finite!
@@ -432,7 +445,7 @@ class WinLossMatrix
             0
           else
             p2 = keys[j]
-            v = p1_hash[p2] || Vector[0,0]
+            v = p1_hash[p2] || GSL::Vector[0,0]
             v[0]
           end
         end)
@@ -655,6 +668,11 @@ def parse(line)
   return if state == "abnormal"
   time = Time.parse(time)
   return if $options["base-date"] < time
+  how_long_days = ($options["base-date"] - time)/(3600*24)
+  if (how_long_days > $options["ignore"])
+    return
+  end
+
   black_id = identify_id(black_id)
   white_id = identify_id(white_id)
 
@@ -679,13 +697,21 @@ end
 
 def usage(io)
     io.puts <<EOF
-USAGE: #{$0} [options] DIR..
-  DIR                where CSA files are looked up recursively
+USAGE: #{$0} [options] GAME_RESULTS_FILE [...]
+       #{$0} [options]
+       
+GAME_RESULTS_FILE:
+  a path to a file listing results of games, which is genrated by the
+  mk_game_results command.
+  In the second style above, the file content can be read from the stdin.
+
 OPTOINS:
   --base-date         a base time point for this calicuration (default now). Ex. '2009-10-31'
   --half-life         n [days] (default 60)
   --half-life-ignore  m [days] (default  7)
                       after m days, half-life effect works
+  --ignore            n [days] (default 730 [=365*2]).
+                      Results older than n days from the 'base-date' are ignored.
   --fixed-rate-player player whose rate is fixed at the rate
   --fixed-rate        rate 
   --skip-draw-games   skip draw games. [default: draw games are counted in
@@ -701,6 +727,7 @@ def main
     ["--half-life",         GetoptLong::REQUIRED_ARGUMENT],
     ["--half-life-ignore",  GetoptLong::REQUIRED_ARGUMENT],
     ["--help", "-h",        GetoptLong::NO_ARGUMENT],
+    ["--ignore",            GetoptLong::REQUIRED_ARGUMENT],
     ["--fixed-rate-player", GetoptLong::REQUIRED_ARGUMENT],
     ["--fixed-rate",        GetoptLong::REQUIRED_ARGUMENT],
     ["--skip-draw-games",   GetoptLong::NO_ARGUMENT])
@@ -733,6 +760,8 @@ def main
   $options["half-life"] = $options["half-life"].to_i
   $options["half-life-ignore"] ||= 7
   $options["half-life-ignore"] = $options["half-life-ignore"].to_i
+  $options["ignore"] ||= 365*2
+  $options["ignore"] = $options["ignore"].to_i
   $options["fixed-rate"] = $options["fixed-rate"].to_i if $options["fixed-rate"]
 
   if ARGV.empty?