3-gram

将棋は、統計処理を進めようと思います。
まずはcsa形式の棋譜を読んで、3-gramを出力するプログラムを作ってみた

CSA将棋を作ってる都万さんが、平成7年に今の森内名人と対戦されたときの棋譜
http://www2.ttcn.ne.jp/~tsuma/moriuchi.csa
の3-gram出力結果


7776FU 8384FU 7968GI
8384FU 7968GI 3334FU
7968GI 3334FU 6766FU
3334FU 6766FU 7162GI
6766FU 7162GI 5756FU
7162GI 5756FU 5354FU
5756FU 5354FU 3948GI
5354FU 3948GI 3142GI
3948GI 3142GI 4958KI
3142GI 4958KI 4132KI
4958KI 4132KI 6978KI
4132KI 6978KI 5141OU
6978KI 5141OU 5969OU
5141OU 5969OU 6152KI
5969OU 6152KI 5867KI
6152KI 5867KI 4233GI
5867KI 4233GI 6877GI
4233GI 6877GI 2231KA
6877GI 2231KA 8879KA
2231KA 8879KA 4344FU
8879KA 4344FU 3736FU
4344FU 3736FU 7374FU
3736FU 7374FU 4837GI
7374FU 4837GI 8485FU
4837GI 8485FU 3746GI
8485FU 3746GI 5243KI
3746GI 5243KI 2937KE
5243KI 2937KE 6364FU
2937KE 6364FU 2838HI
6364FU 2838HI 6263GI
2838HI 6263GI 2726FU
6263GI 2726FU 3324GI
2726FU 3324GI 1716FU
3324GI 1716FU 3153KA
1716FU 3153KA 7968KA
3153KA 7968KA 8173KE
7968KA 8173KE 3725KE
8173KE 3725KE 4131OU
3725KE 4131OU 1615FU
4131OU 1615FU 4445FU
1615FU 4445FU 4637GI
4445FU 4637GI 6465FU
4637GI 6465FU 6665FU
6465FU 6665FU 7365KE
6665FU 7365KE 7766GI
7365KE 7766GI 6364GI
7766GI 6364GI 4746FU
6364GI 4746FU 4546FU
4746FU 4546FU 6846KA
4546FU 6846KA 0045FU
6846KA 0045FU 4668KA
0045FU 4668KA 8586FU
4668KA 8586FU 8786FU
8586FU 8786FU 7475FU
8786FU 7475FU 3848HI
7475FU 3848HI 2425GI
3848HI 2425GI 2625FU
2425GI 2625FU 0074KE
2625FU 0074KE 6665GI
0074KE 6665GI 6465GI
6665GI 6465GI 4845HI
6465GI 4845HI 6566GI
4845HI 6566GI 0058KE
6566GI 0058KE 6667NG
0058KE 6667NG 7867KI
6667NG 7867KI 7486KE
7867KI 7486KE 6846KA
7486KE 6846KA 8678NK
6846KA 8678NK 6978OU
8678NK 6978OU 0069GI
6978OU 0069GI 7869OU
0069GI 7869OU 8289RY
7869OU 8289RY 6968OU
8289RY 6968OU 0066FU
6968OU 0066FU 5866KE
0066FU 5866KE 8988RY
5866KE 8988RY 0078GI
8988RY 0078GI 0086KE
0078GI 0086KE 0079GI
0086KE 0079GI 8678NK
0079GI 8678NK 7978GI
8678NK 7978GI 0079GI
7978GI 0079GI 6857OU
0079GI 6857OU 8878RY
6857OU 8878RY 0068FU
8878RY 0068FU 0077KI

これをたくさんの棋譜に対して行って
同じ行を一つにまとめつつ、同じ行があった回数を左側に記述すれば、

256 nnnn駒 nnnn駒 nnnn駒
128 nnnn駒 nnnn駒 nnnn駒
 ‥‥
002 nnnn駒 nnnn駒 nnnn駒

という感じで、よく出現する3-gramの手筋の順に並んだリストが得られるはず




#include
#include
#include

void main( int argc, char *argv[])
{


FILE *fp;

char buf[200];
char gbuf[3][50];

if(argc>1) {
fp=fopen( argv[1] ,"r");
int c=0;
for(;;) {
if(!fgets(buf,200,fp)) break;
char c0=buf[0];
char c1=buf[1]-'0';
if( (c0=='+' || c0=='-') && (c1>=0 && c1<=9) ) {
buf[7]=' ';

strcat(gbuf[0],&buf[1]);
if((c%3)==2) { printf("%s\n",gbuf[0]);gbuf[0][0]=0; }

if(c>=1) {
strcat(gbuf[1],&buf[1]);
if((c%3)==0) { printf("%s\n",gbuf[1]);gbuf[1][0]=0; }
}
if(c>=2) {
strcat(gbuf[2],&buf[1]);
if((c%3)==1) { printf("%s\n",gbuf[2]);gbuf[2][0]=0; }
}
c++;
}
}
fclose(fp);
}

}

3-gramだと、相手の手に関係なしに進める序盤の定跡は判らないな‥‥
一つ飛ばしで、自分の手筋だけで3-gramを抽出すればいいかも