OSDN Git Service

Merge remote-tracking branch 'origin/master' into wdoor-stable
[shogi-server/shogi-server.git] / mk_game_results
1 #!/usr/bin/ruby
2 # $Id$
3 #
4 # Author:: Daigo Moriwaki
5 # Homepage:: http://sourceforge.jp/projects/shogi-server/
6 #
7 #--
8 # Copyright (C) 2009-2012 Daigo Moriwaki <daigo at debian dot org>
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with this program; if not, write to the Free Software
22 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 #++
24 #
25 # == Synopsis
26 #
27 # mk_game_results reads CSA files, then outputs a list of game results that
28 # is used by mk_rate to calcurate players ratings.
29 #
30 # == Usage
31 #
32 # ./mk_rate DIR..
33
34 # == PREREQUIRE
35 #
36 # Sample Command lines that isntall prerequires will work on Debian.
37 #
38 # * Ruby 2.0.0 or later
39 #
40 #   $ sudo aptitude install ruby
41 #
42 # == Run
43 #
44 #   $ ./mk_game_results . > game_results.txt
45 #
46
47 require 'getoptlong'
48
49 # Parse a CSA file. A tab-delimited line format is
50 #   time  state  black_mark  black_id  white_id  white_mark  filepath  moves
51 # time:: YYYY/MM/DD hh:mm:ss
52 # black_mark:: win lose draw
53 # black_id::   black player's id
54 # white_mark:: win lose draw
55 # white_id::   white player's id
56 # filepath::   absolute file path
57 # moves:: number of moves
58 #
59 # @parameter file an absolute path of a csa file
60 #
61 def grep(file)
62   if RUBY_VERSION >= "1.9.1"
63     str = File.open(file, "r:EUC-JP").read
64   else
65     str = File.open(file, "r").read
66   end
67
68     black_name = nil
69     black_mark = nil
70     black_id = nil
71     white_name = nil
72     white_mark = nil
73     white_id = nil
74     state = nil
75     time = nil
76     moves = 0
77     str.each_line do |line|
78         line.strip!
79         case line
80             when /^[\+\-]\d{4}\w{2}.*$/
81                 moves += 1
82       when /^N\+(.*)$/
83                 black_name = $1.strip
84       when /^N\-(.*)$/
85                 white_name = $1.strip
86       when /^'summary:(.*)$/
87         state, p1, p2 = $1.split(":").map {|a| a.strip}
88         p1_name, p1_mark = p1.split(" ")
89         p2_name, p2_mark = p2.split(" ")
90         if p1_name == black_name
91           black_name, black_mark = p1_name, p1_mark
92           white_name, white_mark = p2_name, p2_mark
93         elsif p2_name == black_name
94           black_name, black_mark = p2_name, p2_mark
95           white_name, white_mark = p1_name, p1_mark
96         else
97           raise "Never reach!: #{black_name}, #{p1}, #{p2} in #{file}"
98         end
99       when /^'\$END_TIME:(.*)$/
100         time = $1.strip
101       when /^'rating:(.*)$/
102         black_id, white_id = $1.split(":").map {|a| a.strip}
103     end # case
104     end # do line
105
106   if black_id && white_id && (black_id != white_id) &&
107      black_mark && white_mark && state && time
108     puts [time, state, black_mark, black_id, white_id, white_mark, file, moves].join("\t")
109     $stdout.flush
110   end
111 end
112
113 # Show Usage
114 #
115 def usage(io)
116     io.puts <<EOF
117 USAGE: #{$0} [options] DIR...
118   DIR                where CSA files are looked up recursively
119 OPTOINS:
120   --help, -h         show this message
121 EOF
122 end
123
124 # MAIN 
125 #
126 def main
127   $options = Hash::new
128   parser = GetoptLong.new(
129     ["--help", "-h",        GetoptLong::NO_ARGUMENT])
130   parser.quiet = true
131   begin
132     parser.each_option do |name, arg|
133       name.sub!(/^--/, '')
134       $options[name] = arg.dup
135     end
136   rescue
137     usage($stderr)
138     raise parser.error_message
139   end
140   if $options["help"]
141     usage($stdout) 
142     exit 0
143   end
144
145   if ARGV.empty?
146     while line = $stdin.gets do
147       next unless %r!.*\.csa$! =~ line
148       grep File.expand_path(line.strip)
149     end
150   else
151     while dir = ARGV.shift do
152       Dir.glob( File.join(dir, "**", "*.csa") ) {|f| grep(File.expand_path(f))}
153     end
154   end
155 end
156
157 if __FILE__ == $0
158   main
159 end
160
161 # vim: tabstop=4 shiftwidth=4 expandtab