From 4cfe38e9e2077079ee126c5b98b6e52522ee6371 Mon Sep 17 00:00:00 2001 From: beatles Date: Wed, 11 Feb 2009 06:06:24 +0000 Subject: [PATCH] * [utils/csa-filter.rb] - Added a new file. This program filters CSA files. --- changelog | 5 ++ utils/csa-filter.rb | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100755 utils/csa-filter.rb diff --git a/changelog b/changelog index 89dcc32..2661d4c 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,8 @@ +2009-02-11 Daigo Moriwaki + + * [utils/csa-filter.rb] + - Added a new file. This program filters CSA files. + 2009-02-01 Daigo Moriwaki * [shogi-server] diff --git a/utils/csa-filter.rb b/utils/csa-filter.rb new file mode 100755 index 0000000..f575ee2 --- /dev/null +++ b/utils/csa-filter.rb @@ -0,0 +1,161 @@ +#!/usr/bin/ruby +# This program filters CSA files. For example, if you want only CSA files +# played by GPS vs Bonanza, +# $ ./csa-filter.rb --players gps-l,bonanza some_dir +# you will see such files under the some_dir directory. +# +# Author:: Daigo Moriwaki +# Copyright:: Copyright (C) 2006-2008 Daigo Moriwaki +# +# $Id$ +# +#-- +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#++ + +require 'time' +require 'pathname' +require 'getoptlong' + +class CsaFileReader + WIN_MARK = "win" + LOSS_MARK = "lose" + DRAW_MARK = "draw" + + attr_reader :file_name + attr_reader :black_name, :white_name + attr_reader :black_id, :white_id + attr_reader :winner, :loser + attr_reader :start_time, :end_time + + def initialize(file_name) + @file_name = file_name + grep + end + + def grep + str = File.open(@file_name).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 /^\$START_TIME:(.*)$/ =~ str + @start_time = Time.parse($1.strip) + end + if /^'\$END_TIME:(.*)$/ =~ str + @end_time = Time.parse($1.strip) + 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 + if black_mark == WIN_MARK && white_mark == LOSS_MARK + @winner, @loser = @black_id, @white_id + elsif black_mark == LOSS_MARK && white_mark == WIN_MARK + @winner, @loser = @white_id, @black_id + elsif black_mark == DRAW_MARK && white_mark == DRAW_MARK + @winner, @loser = nil, nil + else + raise "Never reached!" + end + end + end + end + + def to_s + return "Summary: #{@file_name}\n" + + "BlackName #{@black_name}, WhiteName #{@white_name}\n" + + "BlackId #{@black_id}, WhiteId #{@white_id}\n" + + "Winner #{@winner}, Loser #{@loser}\n" + + "Start #{@start_time}, End #{@end_time}\n" + end + + def identify_id(id) + if /@NORATE\+/ =~ id # the player having @NORATE in the name should not be rated + return nil + end + id.gsub(/@.*?\+/,"+") + end +end + + +if $0 == __FILE__ + def usage + puts "Usage: #{$0} [OPTIONS] dir [...]" + puts "Options:" + puts " --players player_a,player_b select games of the player_a vs the player_b" + puts " --black player select games of which the player is Black" + puts " --white player select games of which the player is White" + exit 1 + end + + usage if ARGV.empty? + + parser = GetoptLong.new( + ['--black', GetoptLong::REQUIRED_ARGUMENT], + ['--white', GetoptLong::REQUIRED_ARGUMENT], + ['--players', GetoptLong::REQUIRED_ARGUMENT] + ) + begin + parser.each_option do |name, arg| + eval "$OPT_#{name.sub(/^--/, '').gsub(/-/, '_').upcase} = '#{arg}'" + end + rescue + puts "hoge" + usage + end + + while dir = ARGV.shift + Dir.glob(File.join(dir, "**", "*.csa")).each do |file| + csa = CsaFileReader.new(file) + + next unless csa.black_id && csa.white_id + + if $OPT_PLAYERS + players = $OPT_PLAYERS.split(",") + unless (csa.black_id.index(players[0]) == 0 && + csa.white_id.index(players[1]) == 0) || + (csa.black_id.index(players[1]) == 0 && + csa.white_id.index(players[0]) == 0) + next + end + end + + if $OPT_BLACK + next unless csa.black_id.index($OPT_BLACK) == 0 + end + if $OPT_WHITE + next unless csa.white_id.index($OPT_WHITE) == 0 + end + puts csa.file_name + end + end +end -- 2.11.0