shogi64

0.0.3 • Public • Published

shogi64.js

将棋の局面をShogi64にエンコード/デコードするライブラリ。

About Shogi64

Shogi64とは局面データをバイナリに変換し、さらにBase64urlに変換するまでを形式化したものである。

Base64url

Base64urlはBase64をURLで利用しやすくしたエンコード方式である。

  • 64文字
    • ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
  • パディング無し
  • 可変長
  • 空白・改行無し
  • 行の最大長はアプリケーション依存

詳しくは以下のURLを参照。

Position Data Format

プログラム上での局面データのフォーマットは以下の通り。

Position {

  • turn[boolean]
  • board[array]
  • hands[object]
    • black[object]
      • FU[number]
      • KY[number]
      • KE[number]
      • GI[number]
      • KI[number]
      • KA[number]
      • HI[number]
    • white[object]
      • FU[number]
      • KY[number]
      • KE[number]
      • GI[number]
      • KI[number]
      • KA[number]
      • HI[number]

}

  • turn[boolean]
    • 手番
    • 先手がtrue、後手がfalse
  • board[array]
    • 盤上の駒
    • 盤面のマスは1次元配列の9×9の81とし、空白と駒は対応する数値で表す
  • hands[object]
    • 持ち駒
    • 先後共に歩から飛まで必ずプロパティに含めて表す

Piece Table

上記のPosition.boardプロパティで扱う駒や空白は数値に変換して扱う。それぞれ対応する数値は以下の通りである。

駒種 先手 後手
空白 0 0
1 -1
2 -2
3 -3
4 -4
5 -5
6 -6
7 -7
8 -8
9 -9
成香 10 -10
成桂 11 -11
成銀 12 -12
13 -13
14 -14

Example Position Data

以上の仕様を用いて書かれた初期局面のコードを紹介する。

var position = {
  'turn': true,
  'board':[-2,-3,-4,-5,-8,-5,-4,-3,-2,
           0,-7,0,0,0,0,0,-6,0,
           -1,-1,-1,-1,-1,-1,-1,-1,-1,
           0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,
           1,1,1,1,1,1,1,1,1,
           0,6,0,0,0,0,0,7,0,
           2,3,4,5,8,5,4,3,2],
  'hands': {'black': {'FU':0, 'KY':0, 'KE': 0, 'GI': 0, 'KI': 0, 'KA': 0, 'HI': 0},
            'white': {'FU':0, 'KY':0, 'KE': 0, 'GI': 0, 'KI': 0, 'KA': 0, 'HI': 0}}
};

Binary Data Format

局面データのコードをハフマン符号で構成されたバイナリに変換する際にShogi64では2通りのエンコードモードがあり、Normal ModeMixed Modeが存在する。

Normal Mode

基本的にはNormal Modeのフォーマットでバイナリに変換される。

手番 モード 先手玉の位置 後手玉の位置 先手歩の位置 先手歩の位置 その他の駒 先手持ち駒 後手持ち駒
1 bit 1 bit 7 bit 7 bit ? bit ? bit ? bit ? bit ? bit

Mixed Mode

Normal Modeのフォーマットで変換できない局面(ルール上問題があるが、玉が複数あったり二歩であるといったケースなど)はこちらのフォーマットで変換される。

手番 モード 全ての駒 先手持ち駒 後手持ち駒
1 bit 1 bit ? bit ? bit ? bit

Turn(手番)

1bit固定長で、手番が先手であれば1、後手であれば0とする。

Mode(モード)

1bit固定長で、Mixed Modeであれば1、Normal Modeであれば0とする。

King Coordinate(玉の位置)

7bit固定長で先手と後手で合計14bitとなる。盤面左上(配列の最初の要素)から右下(配列の最後の要素)までを1〜81として、これを2進数に変換した0000001〜1010001を使って表される。0(0000000)は玉が無いことを意味する。

筋/段
00000001 0000010 .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. 1010000 1010001

Pawn Coordinate(歩の位置)

9筋から1筋にかけて歩が出現する位置(段)を符号化して順に並べられたデータとなる。こうすることで符号の並び順で筋、符号で段を表す仕組みとなっている。歩が存在しない筋も符号化されるが、一段(後手なら九段)は歩が置けないのであらかじめ除かれる。

それぞれ対応する符号は次の表の通りで、0段は歩が存在しないことを意味する。

先手(段) 後手(段) ハフマン符号
0
10
110
1110
11110
111110
1111110
11111110
11111111

Ohter Piece(その他の駒)

玉と歩を除いた全ての駒と空白を盤面左上(配列の最初の要素)から順に符号化して並べられたデータとなる。それぞれ対応する符号は以下の表の通り。

駒種 数値 ハフマン符号
空白 0 0
1 無し
2 100
5 101
3 1100
4 1101
8 無し
7 1110
6 11110
13 1111100
14 1111101
9 1111110
成桂 11 11111110
成銀 12 111111110
成香 10 111111111
  • ※1 変換する際に先手は1、後手は0を符号の末尾に付け加える
  • ※2 ハフマン符号はこちらを参考

All Piece(全ての駒)

全ての駒と空白を盤面左上(配列の最初の要素)から順に符号化して並べられたデータとなる。Mixed Modeではこちらの表を用いて符号化される。

駒種 数値 ハフマン符号
空白 0 0
1 10
2 1100
5 1101
3 11100
4 11110
8 111010
7 111011
6 111110
13 11111100
14 11111101
9 11111110
成桂 11 111111110
成銀 12 1111111110
成香 10 1111111111
  • ※1 変換する際に先手は1、後手は0を符号の末尾に付け加える
  • ※2 ハフマン符号はこちらを参考

Hands(持ち駒)

持ち駒の数を歩、香、桂、銀、金、角、飛の順に符号化して並べられたデータとなる。

Pawn(歩)
ハフマン符号
0 00
1 01
2 10
3 110
4 1110
5 11110
6 111110
7 1111110
8 11111110
9 111111110
10 1111111110
11 11111111110
12 111111111110
13 1111111111110
14 11111111111110
15 111111111111110
16 1111111111111110
17 11111111111111110
18 11111111111111111
Minor Piece(香、桂、銀、金)
ハフマン符号
0 0
1 10
2 110
3 1110
4 1111
Major Piece(角、飛)
ハフマン符号
0 0
1 10
2 11

Encode Example

エンコードの流れを初期局面を使って大まかに紹介する。

var position = {
  'turn': true,
  'board':[-2,-3,-4,-5,-8,-5,-4,-3,-2,
           0,-7,0,0,0,0,0,-6,0,
           -1,-1,-1,-1,-1,-1,-1,-1,-1,
           0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,
           1,1,1,1,1,1,1,1,1,
           0,6,0,0,0,0,0,7,0,
           2,3,4,5,8,5,4,3,2],
  'hands': {'black': {'FU':0, 'KY':0, 'KE': 0, 'GI': 0, 'KI': 0, 'KA': 0, 'HI': 0},
            'white': {'FU':0, 'KY':0, 'KE': 0, 'GI': 0, 'KI': 0, 'KA': 0, 'HI': 0}}
};

これを手番、モード、玉の位置、歩の位置、その他の駒、持ち駒の順に符号化してバイナリ形式に変換する。

101001101000010100000000000000000010001100011010101010101101011000100
001110000000111100000000000000000000000000000001111010000011101010011
10011101110111011110111100110010000000000000000

このバイナリをわかりやすいよう区分すると、

手番 モード 先手玉 後手玉 先手歩 後手歩 その他の駒 先手持ち駒 後手持ち駒
1 0 1001101 0000101 000000000 000000000 10001100011010101
01010110101100010
00011100000001111
0000000000000000
00000000000000011
1101000001110101
001110011101110111
01111011110011001
00000000 00000000

となる。次に、バイナリをBase64url形式に変換する。変換の方法についてはこちらを参照。

poUAACMaqtYhwHgAAAAPQdTnd3vMgAA

以上の流れで局面データはエンコードされる。デコードについてはこの逆をするだけなので省略する。

Usage

Browser:

<script src="shogi64-x.x.x.min.js"></script>
<script>
var position = {
  'turn': true,
  'board':[-2,-3,-4,-5,-8,-5,-4,-3,-2,
           0,-7,0,0,0,0,0,-6,0,
           -1,-1,-1,-1,-1,-1,-1,-1,-1,
           0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,
           1,1,1,1,1,1,1,1,1,
           0,6,0,0,0,0,0,7,0,
           2,3,4,5,8,5,4,3,2],
  'hands': {'black': {'FU':0, 'KY':0, 'KE': 0, 'GI': 0, 'KI': 0, 'KA': 0, 'HI': 0},
            'white': {'FU':0, 'KY':0, 'KE': 0, 'GI': 0, 'KI': 0, 'KA': 0, 'HI': 0}}
};
 
// encode
// encodeResult => poUAACMaqtYhwHgAAAAPQdTnd3vMgAA
var encodeResult = shogi64.encode(position);
 
// decode
var decodeResult = shogi64.decode('poUAACMaqtYhwHgAAAAPQdTnd3vMgAA');
 
// true
console.log(JSON.stringify(position) === JSON.stringify(decodeResult));
</script> 

Node:

installation

npm install shogi64 --save

example

var shogi64 = require('shogi64');
 
var position = {
  'turn': true,
  'board':[-2,-3,-4,-5,-8,-5,-4,-3,-2,
           0,-7,0,0,0,0,0,-6,0,
           -1,-1,-1,-1,-1,-1,-1,-1,-1,
           0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,
           1,1,1,1,1,1,1,1,1,
           0,6,0,0,0,0,0,7,0,
           2,3,4,5,8,5,4,3,2],
  'hands': {'black': {'FU':0, 'KY':0, 'KE': 0, 'GI': 0, 'KI': 0, 'KA': 0, 'HI': 0},
            'white': {'FU':0, 'KY':0, 'KE': 0, 'GI': 0, 'KI': 0, 'KA': 0, 'HI': 0}}
};
 
// encode
// encodeResult => poUAACMaqtYhwHgAAAAPQdTnd3vMgAA
var encodeResult = shogi64.encode(position);
 
// decode
var decodeResult = shogi64.decode('poUAACMaqtYhwHgAAAAPQdTnd3vMgAA');
 
// true
console.log(JSON.stringify(position) === JSON.stringify(decodeResult));

Licence

MIT

Author

sandai

Package Sidebar

Install

npm i shogi64

Weekly Downloads

1

Version

0.0.3

License

MIT

Last publish

Collaborators

  • sandai