npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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]

}

  • 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)は玉が無いことを意味する。

| 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

Author

sandai