忍者ブログ
趣味と実益を兼ねて将棋のプログラムを作ってみたいなと思っている私の試行錯誤や勉強したことを綴ってゆく予定です。 一番の目的はソフトウェア設計やオブジェクト指向に慣れること ・・・だったのですが、元々の興味や電王戦に触発されたこともあり、AI製作も目指してみたいと今は考えています。 ※はてなに移転しました。
カレンダー
12 2025/01 02
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
プロフィール
HN:
cwron
性別:
男性
自己紹介:
将棋の腕前はムラがあるのでなんとも言えませんが、将棋ウォーズや81Dojo基準だと約三段てことになってます。リアルで指す機会が希少です。
Share
ブログ内検索
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

改行コードの判別+各行のふるい分け(バージョン/開始局面など)を簡易的に実装してみた。

OS標準の改行コードと、棋譜データ内で使用される改行コードは必ずしも同一ではない、ってことがちょっとやっかいですね。私がコード書いてる環境はLinux(改行=LF)ですが、棋譜データはたいていwindows(改行=CR+LF)上で作成されているため、若干めんどくさいことになっていました。


拍手[0回]

コードを掲載してみます。csa ver2.0のドキュメントを参照しながらやってます。棋譜データは

    1. バージョン
    2. 棋譜情報(=メタデータ?)
    3. 開始局面+手番
    4. 指し手+消費時間
    5. コメント

    からなる、としています。ある行がどのカテゴリに属すのかは、先頭文字を調べていくことで判別可能ですので、それを基に各行をカテゴリごとに分類していく、という流れです。

    ・・・しかしながら、このコードで定義したデータ格納用クラス"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']
    

    P.S.

    preタグの中でなんかシングルクオートがおかしなことになってるなぁ...
    syntaxhighlighterの都合なのか??ちょっと原因が思いつかない。

    PR
    お名前
    タイトル
    文字色
    URL
    コメント
    パスワード
    Vodafone絵文字 i-mode絵文字 Ezweb絵文字
    Copyright © nounai.output(spaghetiThinking); All Rights Reserved
    Powered by ニンジャブログ  Designed by ピンキー・ローン・ピッグ
    忍者ブログ / [PR]