基本情報のデータベースを拡大する為に、既存のVASSALモジュールから
基本情報を作成することにした。以下に方法を記載する。
1.前提条件
(1)入力するデータは、VASSALモジュールを解凍したbuildとする。
(2)出力するデータは、効率化検討で使った基本情報(集積用)と
同じフォーマットとする。
(3)プログラムは、Anaconda+Jupyter NoteBook+Pythonの
開発環境で作成・動作する。
2.プログラムソース
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import xml.etree.ElementTree as ET | |
import xml.dom.minidom as md | |
import re | |
import csv | |
# XMLファイルを解析 | |
tree = ET.parse(r'D:\DATA2\game\Bataille\Bataille_set\VASSAL\schoengrabern\schoengrabern_V1R2ext\buildFile') | |
# ツリーを取得 | |
root = tree.getroot() | |
#要素を文字列に変換 | |
strxml=ET.tostring(root, 'utf-8').decode() | |
#改行で文字列を分離 | |
elems_list= strxml.split('\n') | |
#初期値設定 | |
deck_name='' | |
unit_num=0 | |
#基本情報初期化 | |
unit_table=[[]] | |
head_name=['ユニット名','射撃値','白兵戦値','士気値','射程', '戦力','表画像名称','裏画像名称','デッキ名称','ユニット種別','0',';書き込みポインタ'] | |
unit_table.append(head_name) | |
del unit_table[0] #先頭の空リストを削除 | |
#基本情報の作成 | |
for i in elems_list: | |
#デッキの開始検出 | |
pattern_deckbegin='<VA.*DrawPile.*name=(.*)ow(.*)>' | |
deck_is = re.search(pattern_deckbegin, i) | |
if deck_is is not None: | |
deck_name=re.sub('\"',"",deck_is.group(1)) | |
#ユニット名と区分の検出 | |
pattern_unit1st='<VA.*Name=(.*)gp(.*)/propertysheet;0(.*)~0(.*)>' | |
card_1st = re.search(pattern_unit1st, i) | |
if card_1st is not None: | |
unit_num +=1 | |
unit_inform=['']*10 | |
unit_name=card_1st.group(1) | |
unit_inform[0]=re.sub('\"',"",unit_name) #" "の文字を削除 | |
char_g=card_1st.group(3) | |
char_g3=char_g[0:3] #ユニット種別の判定用 | |
if char_g3 =='Str': | |
#砲兵のユニット情報検出用 | |
pattern_art='<VA.*false;0;0;(.*)\.jpg(.*)piece;;;(.*)\.jpg;(.*)/(.)~(.*)>' | |
card_art = re.search(pattern_art, i) | |
unit_inform[5]=card_art.group(5) #戦力 | |
unit_inform[6]=card_art.group(3) #表画像 | |
unit_inform[7]=card_art.group(1) #裏画像 | |
unit_inform[8]=deck_name #デッキ名 | |
unit_inform[9]='2art' #ユニット種別 | |
elif char_g3 =='Inf': | |
#指揮官のユニット情報検出用 | |
pattern_cmd='<VA.*piece;;;(.*)\.jpg;(.*)/(.*)false(.*)>' | |
card_cmd = re.search(pattern_cmd, i) | |
cmd_str=card_cmd.group(3) | |
cmd_list=cmd_str.split("~") | |
#歩兵ボーナスから士気ボーナスまで設定 | |
for j in range(4): | |
unit_inform[j+1]=cmd_list[j] | |
unit_inform[6]=card_cmd.group(1) #表画像 | |
unit_inform[8]=deck_name #デッキ名 | |
unit_inform[9]='1cmd' #ユニット種別 | |
elif char_g3=='Fir': | |
#歩兵、騎兵のユニット情報検出用(裏画像あり) | |
pattern_infcav='<VA.*false;0;0;(.*)\.jpg(.*)piece;;;(.*)\.jpg;(.*)/(.*)false(.*)>' | |
card_infcav = re.search(pattern_infcav, i) | |
if card_infcav is not None: | |
infcav_str=card_infcav.group(5) | |
infcav_div=infcav_str.split('\t') | |
infcav_list=['']*2 | |
for j in range(2): | |
infcav_data=infcav_div[j] | |
infcav_list[j]=infcav_data.split("~") | |
#歩兵ボーナスから士気ボーナスまで設定 | |
fire=infcav_list[0][0] | |
unit_inform[1]=re.sub('\(|\)',"",fire) #"騎兵の( )の文字を削除 | |
for j in range(1,4): | |
unit_inform[j+1]=infcav_list[0][j] | |
unit_inform[5]=infcav_list[1][0] #戦力設定 | |
unit_inform[6]=card_infcav.group(3) #表画像 | |
unit_inform[7]=card_infcav.group(1) #裏画像 | |
unit_inform[8]=deck_name #デッキ名 | |
#ユニット種別設定 | |
backimage=unit_inform[7] | |
back3=backimage[0:3] | |
if back3 == 'SKC': | |
unit_inform[9]='3cav' | |
elif back3 == 'ski': | |
if fire == 'SK' or fire == 'Sk' or fire == 'sk': | |
unit_inform[9]='3cav' | |
else: | |
unit_inform[9]='4inf' | |
#歩兵、騎兵のユニット情報検出用(裏画像なし) | |
else: | |
pattern_infcav='<VA.*piece;;;(.*)\.jpg;(.*)/(.*)false(.*)>' | |
card_infcav = re.search(pattern_infcav, i) | |
if card_infcav is not None: | |
infcav_str=card_infcav.group(3) | |
infcav_div=infcav_str.split('\t') | |
infcav_list=['']*2 | |
for j in range(2): | |
infcav_data=infcav_div[j] | |
infcav_list[j]=infcav_data.split("~") | |
#歩兵ボーナスから士気ボーナスまで設定 | |
for j in range(4): | |
unit_inform[j+1]=infcav_list[0][j] | |
unit_inform[5]=infcav_list[1][0] #戦力設定 | |
unit_inform[6]=card_infcav.group(1) #表画像 | |
unit_inform[8]=deck_name #デッキ名 | |
#ユニット種別設定 | |
fire=unit_inform[1] | |
if fire is '': | |
unit_inform[9]='3cav' | |
else: | |
unit_inform[9]='4inf' | |
unit_table.append(unit_inform) #基本情報に追加 | |
unit_table[0][10]=unit_num+2 #書き込みポインタ設定 | |
#cvsファイル出力 | |
write_file=open('unit_table.csv', 'w', newline='') | |
writer=csv.writer(write_file) | |
for i in unit_table: | |
writer.writerow(i) | |
write_file.close() |
(補足)
(1)基本情報を記憶するリストは、長さを特定できないので、可変データに
対応できるものにする。具体的には、初期値で[[]]を指定する。その後、
データは追加(append)形式で登録する。但し、1つのデータを登録後に、
初期値で指定した先頭の空リスト[[]]を削除する。
(2)buildデータは、下記のようにデッキ情報の次にユニット情報が続くので、
初めにデッキ名称を検索し記憶する。その後、ユニット情報を検索して登録する時に、
このデッキ名称を使う。
・デッキ情報
・ユニット情報 *nケ
・デッキ情報
・ユニット情報 *nケ
3.テスト結果
(1)入力データは、シェンカーバンの戦いV1R2(自作)である。
(2)出力データは、下図のように109ケのユニット基本情報である。
<個人的な感想>
思ったよりも苦戦しないでプログラムを作成できた。正規表現モジュール(re)を
使うことで比較的簡単にデータを検索・抽出できた。これが無ければ、とても完成
出来なかったと思っている。