import java.util.*; /** * SgfTree クラスは、SGFファイル内の全データから、手順データツリーを抽出します。 * @author Jiro Suzuki */ public class SgfTree{ private static String[] PROPERTY={"AN[","AP[","BH[","BR[","BT[","CP[","DT[","EV[","FF[","GC[","GM[","GN[","HA[","KO[","LKM[","NE[","OM[","ON[","PB[","PC[","PTM[","PW[","RE[","RO[","RU[","SO[","SZ[","TM[","TR[","US[","WH[","WR[","WT[","AB[","AE[","AR[","AW[","B[","BL[","C[","CR[","DD[","MA[","MK[","HL[","NF[","ID[","L[","LB[","LO[","LN[","M[","MA[","RT[","SL[","SQ[","ST[","TL[","TR[","W[","WL["}; private Vector[] levelArray; private int cntParenthesisOpen; /** * 空のインスタンスを生成します。 */ SgfTree(){ cntParenthesisOpen=0; } /** * SGF形式の手順を取得します。 * @param str SGFファイル内の全データ(String形式) * @return SGF形式の手順データツリー(参考図含む) */ public Vector getSgfTree(String str){ //改行コードを消去する str=str.replaceAll("\\n", ""); char[] charData=str.toCharArray(); for(int i=0;i<charData.length;i++){ //小括弧(開)を数えて、データツリーの深さを知る元情報にする if(charData[i]=='('){ cntParenthesisOpen++; } } //char配列をStringに変換 String strAll=new String(charData); //char配列をノード毎のStringに変換してVectorに保管 Vector<Character> node=new Vector<Character>(); boolean isMidParenthesisClosed=true; boolean isOutputChar; int currentLevel=-1; //レベル毎の配列を初期化 levelArray=new Vector[cntParenthesisOpen/2+1]; for(int i=0;i<cntParenthesisOpen/2+1;i++){ levelArray[i]=new Vector(); } for(int i=0;i<charData.length;i++){ isOutputChar=true; //ブレーク処理 if(isMidParenthesisClosed){ //node追加判定 switch(charData[i]){ case '(': case ')': case ';': isOutputChar=false; addNode(currentLevel,node); node.clear(); break; default:break; } //ArrayNode追加処理 switch(charData[i]){ case '(': currentLevel++; clearLevelArray(currentLevel); break; case ')': addArrayNode(currentLevel); currentLevel--; break; default:break; } } //中括弧判定処理 switch(charData[i]){ case '[': isMidParenthesisClosed=false; break; case ']': //コメント内中括弧をClose判定しないための工夫 //ただし、"];"と"]("と"])"がコメント内に出現した時は対処できない。 if(isMatchProperty(strAll.substring(i+1)) | charData[i+1]==';' | charData[i+1]=='(' | charData[i+1]==')' ){ isMidParenthesisClosed=true; } break; default:break; } //入力文字をnodeに追加 if(isOutputChar){ node.add(new Character(charData[i])); } } //最後の1ノードをVectorに追加 addNode(currentLevel,node); return levelArray[0]; } //-------------------------------------------------------------- //Vector(要素はchar)をStringに変換 private String createStrWord(Vector node){ char[] charWord=new char[node.size()]; for(int i=0;i<node.size();i++){ charWord[i]=((Character)node.get(i)).charValue(); } return new String(charWord); } //-------------------------------------------------------------- //プロパティ文字列確認処理 private boolean isMatchProperty(String str){ int match=0; for(int i=0;i<PROPERTY.length;i++){ if(str.startsWith(PROPERTY[i])){ match=1; i=PROPERTY.length; } } if(match==1){ return true; }else{ return false; } } //-------------------------------------------------------------- private void clearLevelArray(int levelNum){ levelArray[levelNum].clear(); } private void addNode(int levelNum,Vector node){ if(node.size()>0){ levelArray[levelNum].add(createStrWord(node)); } } private void addArrayNode(int levelNum){ if(levelNum>0){ levelArray[levelNum-1].add(levelArray[levelNum].clone()); } } }