shogi64
v0.0.3
Published
Shogi64 encoding/decoding for The Shogi(Japanese Chess) board.
Downloads
3
Readme
shogi64.js
将棋の局面をShogi64にエンコード/デコードするライブラリ。
About Shogi64
Shogi64とは局面データをバイナリに変換し、さらにBase64urlに変換するまでを形式化したものである。
Base64url
Base64urlはBase64をURLで利用しやすくしたエンコード方式である。
- 64文字
- ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
- パディング無し
- 可変長
- 空白・改行無し
- 行の最大長はアプリケーション依存
詳しくは以下のURLを参照。
- https://ja.wikipedia.org/wiki/Base64
- http://wiki.suikawiki.org/n/base64url
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]
- black[object]
}
- 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 ModeとMixed 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)は玉が無いことを意味する。
| 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 筋/段 | |----------|----------|----|----|----|----|----|---------|---------|-------| | 00000001 | 0000010 | .. | .. | .. | .. | .. | .. | .. | 一 | | .. | .. | .. | .. | .. | .. | .. | .. | .. | 二 | | .. | .. | .. | .. | .. | .. | .. | .. | .. | 三 | | .. | .. | .. | .. | .. | .. | .. | .. | .. | 四 | | .. | .. | .. | .. | .. | .. | .. | .. | .. | 五 | | .. | .. | .. | .. | .. | .. | .. | .. | .. | 六 | | .. | .. | .. | .. | .. | .. | .. | .. | .. | 七 | | .. | .. | .. | .. | .. | .. | .. | .. | .. | 八 | | .. | .. | .. | .. | .. | .. | .. | 1010000 | 1010001 | 九 |
Pawn Coordinate(歩の位置)
9筋から1筋にかけて歩が出現する位置(段)を符号化して順に並べられたデータとなる。こうすることで符号の並び順で筋、符号で段を表す仕組みとなっている。歩が存在しない筋も符号化されるが、一段(後手なら九段)は歩が置けないのであらかじめ除かれる。
それぞれ対応する符号は次の表の通りで、0段は歩が存在しないことを意味する。
| 先手(段) | 後手(段) | ハフマン符号 | |----------|----------|--------------| | 七 | 三 | 0 | | 六 | 四 | 10 | | 0 | 0 | 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 | 100011000110101010101011010110001000011100000001111000000000000000000000000000000011110100000111010100111001110111011101111011110011001 | 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