Skip to content

Instantly share code, notes, and snippets.

@ainame
Created December 11, 2011 15:36
Show Gist options
  • Save ainame/1461159 to your computer and use it in GitHub Desktop.
Save ainame/1461159 to your computer and use it in GitHub Desktop.
CSA形式の将棋の棋譜の完全一致チェック.kifu_check.rbの最後の部分でパラメーターを適宜編集.lib/csa_reacord.rbとlib/tree.rbを配置して利用.
# -*- coding: utf-8 -*-
# CSA形式の棋譜を表すクラス
class CsaRecord
Sente = true
Gote = false
attr_accessor :file
def initialize( *args )
option = args.pop
case option
when File
@file = option
when String
@file = option
else
raise "This initialize method can accept only File or String obj."
end
@record = Array.new
@sente_time = Array.new
@gote_time = Array.new
@turn = Sente
@ply = 0
@initial_position = "PI"
@description = ""
@result = Hash.new
self.parse()
end
def flip_turn()
@turn = @turn ? Gote : Sente
end
def parse()
(@file.kind_of? File) ?
self.parse_csa_string(@file.read) : self.parse_csa_string(@file)
end
def parse_csa_string(str)
str.each_line do |line|
self.parse_csa_line(line.chomp)
end
@result
end
def [](num)
@record[num]
end
def each()
@record.each do |move|
yield move
end
end
def length
@record.length
end
def parse_csa_line(line)
case line
when /^N\+(.+)/
@sente_name = $1
when /^N-(.+)/
@gote_name = $1
when /^\+$/
@turn = Sente
when /^\-$/
@turn = Gote
when /^([\+-]\d\d\d\d[A-Z][A-Z])/
@record << $1
@ply += 1
flip_turn()
when /^PI/
@initial_position = "PI"
when /^P.*/
# PI以外での初期局面
when /^T.+/
#持ち時間
when /summary/
line =~ /summary:.*:.*\s(.*):.*\s(.*)/
#'summary:toryo:bona1 lose:bona2 win'
@result[:sente] = $1
@result[:gote] = $2
when /^('.*)/
#コメント
@description << $1 + "\n"
when /^%(.+)/
@result[:reason] = $1
end
end
end
# -*- coding: utf-8 -*-
# 棋譜の完全重複チェックツール
#
$: << File.dirname(__FILE__)
require 'lib/csa_record'
require 'lib/tree'
require 'pp'
raise "棋譜を含むディレクトリを指定してください!" if ARGV[0].nil?
$kifu_dir = ARGV[0]
start = Time.now
records = Array.new
Dir.chdir($kifu_dir)
Dir.glob("*.csa") do |csa|
open(csa, "r") do |f|
csa = CsaRecord.new(f)
records << csa
end
end
puts Time.now-start
puts "インスタンス化完了!(#{records.length})"
start = Time.now
tree = CsaRecord::Tree.new
records.each do |csa|
for i in 0..(csa.length)
ptree = tree
for j in 0..i
ptree[csa[j]] = CsaRecord::Tree.new if ptree[csa[j]].nil?
ptree = ptree[csa[j]]
ptree.value << csa.file.path if i == j
end
end
end
proc_print = Proc.new { |node, key, ply|
print "#{ply}:#{key} => "
p node.value
}
tree.traversal do |node, key, ply|
if ply > 30 && node.value.length > 1
puts "棋譜の重複! #{node.value.inspect}"
end
end
puts Time.now-start
puts "棋譜の操作終了"
# -*- coding: utf-8 -*-
#複数のCSA形式の棋譜を木構造として構築するための
class CsaRecord
class Tree
attr_accessor :child, :value
def initialize
@value = Array.new
@child = Hash.new
end
def [](str)
@child[str]
end
def []=(str, val)
@child[str] = val
end
def traversal(key = "root", ply = 0, &func)
unless self.child.nil?
child.each do |key, val|
val.traversal(key, ply + 1, &func)
end
end
func.call(self,key, ply)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment