2017年7月23日日曜日

コンピュータ将棋における、SFEN文字列の最大長について

※ネタ記事です。

※SFEN文字列 の詳細については、
将棋所:USIプロトコルとは」 の 「SFENによる盤面と指し手の表記について」
と、Tord Romstad氏 の USI原案 (現在リンク切れ) を参考にしました。


ぼくのかんがえた さいちょうの えすえふいーえぬ

SFEN文字列 の最大長は、おそらく130文字。
※Move count (「次が何手目か」を表す数字) は、含めず

なお、この記事をこれ以降読んでも、とくにオチはありません。


長さ130文字のSFEN文字列 具体例

1+N1+S1+S1+N1/1+L1+R1+B1+L1/1+P1+P1+P1+P1/1+P1+P1+p1+p1/1+P1K1k1+p1/1+P1+P1+p1+p1/1+p1+p1+p1+p1/1+l1+b1+r1+l1/1+n1+s1+s1+n1 b 2G2g

上記の具体例の BOD形式 表現

後手の持駒:金二 
  9 8 7 6 5 4 3 2 1
+---------------------------+
| ・ 圭 ・ 全 ・ 全 ・ 圭 ・|一
| ・ 杏 ・ 龍 ・ 馬 ・ 杏 ・|二
| ・ と ・ と ・ と ・ と ・|三
| ・ と ・ と ・vと ・vと ・|四
| ・ と ・ 玉 ・v玉 ・vと ・|五
| ・ と ・ と ・vと ・vと ・|六
| ・vと ・vと ・vと ・vと ・|七
| ・v杏 ・v馬 ・v龍 ・v杏 ・|八
| ・v圭 ・v全 ・v全 ・v圭 ・|九
+---------------------------+
先手の持駒:金二 
手数=0    まで

上記の具体例の 局面図 (画像)


「最長」のレギュレーション

  • 平手の初期配置から、合法手で到達できる局面のみを対象とする。


参考リンク

参照したWebページ

使用させていただいたソフトウェア

2017年7月9日日曜日

Javaでの、2次元配列 (多次元配列) の作成方法の違いによるバイトコード差異について

Q. Javaでの2次元配列の作成において、「多次元配列風の作法」と「ジャグ配列風の作法」とでは、バイトコードに違いは出るのか?

多次元配列風の作法 ※正式な用語ではない
int[][] a = new int[3][4];
ジャグ配列風の作法 ※正式な用語ではない
int[][] a = new int[3][];
a[0] = new int[4];
a[1] = new int[4];
a[2] = new int[4];
ジャグ配列風の作法 その2
int[][] a = new int[][] {
  new int[4], 
  new int[4], 
  new int[4]};

A. バイトコードに差異は出る。

Javaの仮想マシンは、「多次元配列作成専用のオペコード」(multianewarray)を持っている。

したがって、「多次元配列風の作法」の方が、バイトコードがコンパクトになる。

調査で使用したJavaコンパイラ
javac 1.8.0_25 (Oracle)
Javaソースコードバイトコード
// 多次元配列風
int[][] a = new int[3][4];
ICONST_3
ICONST_4
MULTIANEWARRAY [[I 2
ASTORE 1
// ジャグ配列風
int[][] a = new int[3][];
a[0] = new int[4];
a[1] = new int[4];
a[2] = new int[4];
ICONST_3
ANEWARRAY [I
ASTORE 1

ALOAD 1
ICONST_0
ICONST_4
NEWARRAY T_INT
AASTORE

ALOAD 1
ICONST_1
ICONST_4
NEWARRAY T_INT
AASTORE

ALOAD 1
ICONST_2
ICONST_4
NEWARRAY T_INT
AASTORE
// ジャグ配列風 その2
int[][] a = new int[][] {
  new int[4], 
  new int[4], 
  new int[4]};
ICONST_3
ANEWARRAY [I

DUP
ICONST_0
ICONST_4
NEWARRAY T_INT
AASTORE

DUP
ICONST_1
ICONST_4
NEWARRAY T_INT
AASTORE

DUP
ICONST_2
ICONST_4
NEWARRAY T_INT
AASTORE

ASTORE 1

参考リンク

2017年7月3日月曜日

Javaにおける、フィールド修飾子 (final や transient 等) の記述順序について

結論

文法上は自由だが、慣習としては下記の順序で記述する。(推奨)

  1. アクセス修飾子 (publicprotectedprivate、もしくは、何も書かない)
  2. static
  3. final
  4. transient
  5. volatile

根拠

  • Java 言語仕様」の「8.3.1. Field Modifiers」に、下記の記述あり。

    If two or more (distinct) field modifiers appear in a field declaration, it is customary, though not required, that they appear in the order consistent with that shown above in the production for FieldModifier.

    (日本語訳) フィールド宣言中にフィールド修飾子を複数記述する場合、必須ではないものの、慣習としては 上記の FieldModifier 生成規則に記述された順序で指定する。

  • java.lang.reflect.Modifier」の「toString(int mod)」に、下記の記述あり。

    修飾子名は、『Java(tm)言語仕様』のセクション8.1.1、8.3.1、8.4.3、8.8.3、および9.1.1で指定されている推奨修飾子順序に適合する順序で返されます。

補足

final」と「transient」の組み合わせは、ほとんどの場合でナンセンス。
transient」だとデシリアライズ時に null になるが、「final」ならば再代入ができない。
(当該フィールドの値は、デシリアライズ後は 常にnull になる)

例外として、シングルトンなどで、デシリアライズ時に readResolve() でインスタンス自体を読み替えてしまう場合だけは、「final transient」が意味を成す。