0.0.3 • Published 9 years ago

shogi64 v0.0.3

Weekly downloads
4
License
MIT
Repository
github
Last release
9 years ago

shogi64.js

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

About Shogi64

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

Base64url

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

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

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

Position Data Format

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

Position {

}

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

Piece Table

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

駒種先手後手
空白00
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 bit1 bit7 bit7 bit? bit? bit? bit? bit? bit

Mixed Mode

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

手番モード全ての駒先手持ち駒後手持ち駒
1 bit1 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)は玉が無いことを意味する。

筋/段
000000010000010..............
..................
..................
..................
..................
..................
..................
..................
..............10100001010001

Pawn Coordinate(歩の位置)

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

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

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

Ohter Piece(その他の駒)

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

駒種���値ハフマン符号
空白00
1無し
2100
5101
31100
41101
8無し
71110
611110
131111100
141111101
91111110
成桂1111111110
成銀12111111110
成香10111111111
  • ※1 変換する際に先手は1、後手は0を符号の末尾に付け加える
  • ※2 ハフマン符号はこちらを参考

All Piece(全ての駒)

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

駒種数値ハフマン符号
空白00
110
21100
51101
311100
411110
8111010
7111011
6111110
1311111100
1411111101
911111110
成桂11111111110
成銀121111111110
成香101111111111
  • ※1 変換する際に先手は1、後手は0を符号の末尾に付け加える
  • ※2 ハフマン符号はこちらを参考

Hands(持ち駒)

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

Pawn(歩)
ハフマン符号
000
101
210
3110
41110
511110
6111110
71111110
811111110
9111111110
101111111110
1111111111110
12111111111110
131111111111110
1411111111111110
15111111111111110
161111111111111110
1711111111111111110
1811111111111111111
Minor Piece(香、桂、銀、金)
ハフマン符号
00
110
2110
31110
41111
Major Piece(角、飛)
ハフマン符号
00
110
211

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

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

手番モード先手玉後手玉先手歩後手歩その他の駒先手持ち駒後手持ち駒
10100110100001010000000000000000001000110001101010101010110101100010000111000000011110000000000000000000000000000000111101000001110101001110011101110111011110111100110010000000000000000

となる。次に、バイナリを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