--- /dev/null
+#!/usr/bin/ruby
+# $Id$
+#
+# Author:: Daigo Moriwaki
+# Homepage:: http://sourceforge.jp/projects/shogi-server/
+#
+#--
+# Copyright (C) 2009 Daigo Moriwaki <daigo at debian dot org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#++
+#
+# == Synopsis
+#
+# mk_game_results reads CSA files, then outputs a list of game results that
+# is used by mk_rate to calcurate players ratings.
+#
+# == Usage
+#
+# ./mk_rate DIR..
+#
+# == PREREQUIRE
+#
+# Sample Command lines that isntall prerequires will work on Debian.
+#
+# * Ruby 1.8.7
+#
+# $ sudo aptitude install ruby1.8
+#
+# == Run
+#
+# $ ./mk_game_results . > game_results.txt
+#
+
+require 'getoptlong'
+
+# Parse a CSA file. A tab-delimited line format is
+# time state black_mark black_id white_id white_mark filepath
+# time:: YYYY/MM/DD hh:mm:ss
+# black_mark:: win lose draw
+# black_id:: black player's id
+# white_mark:: win lose draw
+# white_id:: white player's id
+# filepath:: absolute file path
+#
+# @parameter file an absolute path of a csa file
+#
+def grep(file)
+ str = File.open(file).read
+
+ if /^N\+(.*)$/ =~ str then black_name = $1.strip end
+ if /^N\-(.*)$/ =~ str then white_name = $1.strip end
+
+ if /^'summary:(.*)$/ =~ str
+ state, p1, p2 = $1.split(":").map {|a| a.strip}
+ p1_name, p1_mark = p1.split(" ")
+ p2_name, p2_mark = p2.split(" ")
+ if p1_name == black_name
+ black_name, black_mark = p1_name, p1_mark
+ white_name, white_mark = p2_name, p2_mark
+ elsif p2_name == black_name
+ black_name, black_mark = p2_name, p2_mark
+ white_name, white_mark = p1_name, p1_mark
+ else
+ raise "Never reach!: #{black} #{white} #{p3} #{p2}"
+ end
+ end
+
+ if /^'\$END_TIME:(.*)$/ =~ str
+ time = $1.strip
+ end
+
+ if /^'rating:(.*)$/ =~ str
+ black_id, white_id = $1.split(":").map {|a| a.strip}
+ if black_id && white_id && (black_id != white_id) &&
+ black_mark && white_mark && state && time
+ puts [time, state, black_mark, black_id, white_id, white_mark, file].join("\t")
+ end
+ end
+end
+
+# Show Usage
+#
+def usage(io)
+ io.puts <<EOF
+USAGE: #{$0} [options] DIR...
+ DIR where CSA files are looked up recursively
+OPTOINS:
+ --help, -h show this message
+EOF
+end
+
+# MAIN
+#
+def main
+ $options = Hash::new
+ parser = GetoptLong.new(
+ ["--help", "-h", GetoptLong::NO_ARGUMENT])
+ parser.quiet = true
+ begin
+ parser.each_option do |name, arg|
+ name.sub!(/^--/, '')
+ $options[name] = arg.dup
+ end
+ rescue
+ usage($stderr)
+ raise parser.error_message
+ end
+ if $options["help"]
+ usage($stdout)
+ exit 0
+ end
+
+ if ARGV.empty?
+ while line = $stdin.gets do
+ next unless %r!.*\.csa$! =~ line
+ grep File.expand_path(line.strip)
+ end
+ else
+ while dir = ARGV.shift do
+ Dir.glob( File.join(dir, "**", "*.csa") ) {|f| grep(File.expand_path(f))}
+ end
+ end
+end
+
+if __FILE__ == $0
+ main
+end
+
+# vim: ts=2 sw=2 sts=0
# Homepage:: http://sourceforge.jp/projects/shogi-server/
#
#--
-# Copyright (C) 2006-2008 Daigo Moriwaki <daigo at debian dot org>
+# Copyright (C) 2006-2009 Daigo Moriwaki <daigo at debian dot org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
id.gsub(/@.*?\+/,"+")
end
-def grep(file)
- str = File.open(file).read
-
- if /^N\+(.*)$/ =~ str then black_name = $1.strip end
- if /^N\-(.*)$/ =~ str then white_name = $1.strip end
-
- if /^'summary:(.*)$/ =~ str
- state, p1, p2 = $1.split(":").map {|a| a.strip}
- return if state == "abnormal"
- p1_name, p1_mark = p1.split(" ")
- p2_name, p2_mark = p2.split(" ")
- if p1_name == black_name
- black_name, black_mark = p1_name, p1_mark
- white_name, white_mark = p2_name, p2_mark
- elsif p2_name == black_name
- black_name, black_mark = p2_name, p2_mark
- white_name, white_mark = p1_name, p1_mark
- else
- raise "Never reach!: #{black} #{white} #{p3} #{p2}"
- end
- end
- if /^'\$END_TIME:(.*)$/ =~ str
- time = Time.parse($1.strip)
+# Parse a game result line
+#
+def parse(line)
+ time, state, black_mark, black_id, white_id, white_mark, file = line.split("\t")
+ unless time && state && black_mark && black_id &&
+ white_id && white_mark && file
+ $stderr.puts "Failed to parse the line : #{line}"
+ return
end
- if /^'rating:(.*)$/ =~ str
- black_id, white_id = $1.split(":").map {|a| a.strip}
- black_id = identify_id(black_id)
- white_id = identify_id(white_id)
- if black_id && white_id && (black_id != white_id) &&
- black_mark && white_mark
- add(black_mark, black_id, white_id, white_mark, time)
- end
+
+ return if state == "abnormal"
+ time = Time.parse(time)
+ black_id = identify_id(black_id)
+ white_id = identify_id(white_id)
+
+ if black_id && white_id && (black_id != white_id) &&
+ black_mark && white_mark
+ add(black_mark, black_id, white_id, white_mark, time)
end
end
if ARGV.empty?
while line = $stdin.gets do
- next unless %r!.*\.csa$! =~ line
- grep line.strip
+ parse line.strip
end
else
- while dir = ARGV.shift do
- Dir.glob( File.join(dir, "**", "*.csa") ) {|f| grep(f)}
+ while file = ARGV.shift do
+ File.open(file) do |f|
+ f.each_line do |line|
+ parse line.strip
+ end
+ end
end
end