改行コードの判別+各行のふるい分け(バージョン/開始局面など)を簡易的に実装してみた。
OS標準の改行コードと、棋譜データ内で使用される改行コードは必ずしも同一ではない、ってことがちょっとやっかいですね。私がコード書いてる環境はLinux(改行=LF)ですが、棋譜データはたいていwindows(改行=CR+LF)上で作成されているため、若干めんどくさいことになっていました。
コードを掲載してみます。csa ver2.0のドキュメントを参照しながらやってます。棋譜データは
からなる、としています。ある行がどのカテゴリに属すのかは、先頭文字を調べていくことで判別可能ですので、それを基に各行をカテゴリごとに分類していく、という流れです。
・・・しかしながら、このコードで定義したデータ格納用クラス"csarecord"を使った場合、カテゴリの異なる2つの行の順番をチェックすることは不可能です。よって"開始局面"の前に"指し手"があってもそれは素通しです。csaの仕様上だとこれはアウトなので、全く仕様に厳密なコードではありません。Pythonのことをある程度知っている人であればすぐに同等のコードは書けてしまうでしょうし、コード自体も全然美しさがありませんので今後改善していきたいとは思いますが、AI部分もやってみたいのでその辺はやるにしてもかなり後手になる気がしています。
#/usr/bin/env/ python # -*- coding: utf-8 -*- import os import sys import curses.ascii class plainrecord: def __init__(self, fname): self.lines = file(fname, "r").readlines() if self.lines[0][-2:] is "\r\n": self.linesep="\r\n" else: # "CR+LPで終わらない場合"は全て、"改行=LF"とみなす。 self.linesep="\n" class csarecord(plainrecord): def todict(self): return { "version" :self.Version, "meta" :self.meta, "start" :self.start, "move" :self.move, "comments" :self.comments, "linesep" :self.linesep } def __init__(self, fname): """ Windowsで生成された棋譜ファイルのみをターゲットとするならば、 改行コードはCR+LFのみを考えれば良い。 """ self.lines = file(fname, "r").readlines() if self.lines[0][-2:] is "\r\n": self.linesep="\r\n" else: # "上記ifにあてはまらないケース"の全てを、改行=LFとみなす。 self.linesep="\n" for line in self.lines: if(line[0]=="'"): continue elif(line[0]!="V"): self.version = 1.0 break else: # 要改善。 self.version = 2.0 break self.Version = list() self.meta = list() self.start = list() self.move = list() self.comments = list() for line in self.lines: if(line[0]=="V"): self.Version.insert(len(self.Version), line) elif(line[0]=="$" or line[0]=="N"): self.meta.insert(len(self.meta), line) elif(line[0]=="P" or (line[0]=="+" and not curses.ascii.isalnum(line[1])) or (line[0]=="-" and not curses.ascii.isalnum(line[1]))): self.start.insert(len(self.start), line) elif(line[0]=="T" or (line[0]=="+" and curses.ascii.isalnum(line[1])) or (line[0]=="-" and curses.ascii.isalnum(line[1]))): self.move.insert(len(self.move), line) elif(line[0]=="'" or line[0]=="#"): self.comments.insert(len(self.comments), line) def test(): r = csarecord("s.csa") print r.version print r.todict()['start']
preタグの中でなんかシングルクオートがおかしなことになってるなぁ...
syntaxhighlighterの都合なのか??ちょっと原因が思いつかない。