Project Fx 2.0

怪文書と備忘録を書きます

QiitaのLGTMをエクスポートするツールを作った

Qiita離れの動きが加速している昨今[要出典]、LGTM・ストックしていた良記事が作者のQiita退会に伴い見れなくなってしまうということが増えてきました。

「自分が面白いと思った情報が自分の与り知らない所で自分の視界からフェードアウトしてしまう」というのは私にとってとても腹立たしい事なので、 今のうちに自分が面白いと思った記事を全てアーカイブする準備を進めています。 その一環として、Qiitaで自分がLGTMした記事の情報を取得してCSVに出力するツールを書きました。

最初こそ「ストックがAPIで取れるんだからLGTMも簡単に行けるっしょー」と思っていたのですが、 よく調べたところQiita APIでは自分がLGTMした記事を取得することができないことが判明したため、 puppeteerを使ってスクレイピングしました。

コードはこちらに置いてあります。yarnを叩けば動くはずです。
実行すると「記事タイトル・記事URL・記事著者名・LGTM数・記事の投稿日時」を取得し、CSVに吐き出してくれます。

github.com

なぜpuppeteerなのか

手順

大したことはしていません。
各ユーザのLGTM一覧ページ (https://qiita.com/ユーザー名/lgtms?page=数字) 内の要素を抜き出し、CSVにまとめているだけです。
ユーザー名の部分を変更すれば任意のユーザーのLGTMを取得できるはずです。 記事タイトルや記事作成日時などといった情報の正確な値は記事のURLさえ分かればQiita APIで取得できますが、今回はそこまで正確な情報は不要だったためLGTM一覧ページから直接スクレイピングすることにしました。

なお、ツール内にTwitter連携でQiitaにログインするコードが含まれていますが、 これは「同じクライアントから未ログイン状態で立て続けに10回以上Qiitaにアクセスした場合、Qiitaへのアカウント登録を促すプロンプトが出現する」という仕様を回避するために付けたものです。 その後、プロンプトが出ていても目的のスクレイピングの実行に支障は出ないことが判明し、このログイン機構の存在意義は端から無かったことが分かりました。
もしかしたら、このログイン機構も実は限定公開記事の情報を取得するのに便利だったりするのかもしれません。 限定公開記事を見たことがないので知りませんが。

CSVの出力が地味に一番の難関でした。 自前での実装が厳しかったので、結局papaparseという専用のライブラリを使っています。

www.papaparse.com

所感

  • スクレイピング楽しかったです。欲しい情報を適切に切り出すことに成功した時のエクスタシーは何物にも代えがたいですね。
  • puppeteerは色々と自由度が高いですが、それゆえに適切な調整の仕方を見つけ出すのが中々難しいという事が分かりました。
  • この記事をQiitaに投稿してLGTMが欲しい

追記

2021年2月26日に行われたQiitaの大規模アップデートにより、LGTM一覧ページが改修されました。

qiita.com

これに伴い、puppeteer_qiita.jsに以下の変更を施しました:

  • コード内で使用していたXPathをすべて書き換える
  • 記事の作者・記事の更新日時の情報がLGTM一覧ページに表示されなくなったため、これらを出力する機能を削除

あるいはボドゲでいっぱいの星~ボードゲーム開発・対局用フレームワーク「Dagaz Project」の紹介~

この文章は、Board Gamed Design Advent Calendar 2020の第20日目の記事です(投稿は25日目)。遅刻申し訳ありません。 adventar.org

この記事の目的は、私が開発に携っている(携わろうとしている)ボードゲーム制作ツール「Dagaz Project」を皆さんに布教し、その開発メンバーを可能な限り増やすことです。
私自身はいわゆる「ボドゲ界隈」とは全く無縁の人間であり、ボドゲにおける一般的な用語・概念をほとんど何も知りません。 このため、界隈では良く知られていることの説明に過剰に文字数を割いている箇所があるかもしれません。 また、扱っているネタが一般的なボドゲとややかけ離れているきらいがありますが、これは私が他にちょうど良いアドカレを見つけることができなかったためです。

Dagazについて説明する前に、まずその前提となる概念をいくつか紹介する必要があります。

ゲームAIとGeneral Game Playing

ご存じの方も多いでしょうが、コンピュータ関連の科学技術が発展するにつれて、その応用分野の一つとして人工知能の研究も盛んに行われるようになっていきました。 その中でも、「コンピュータにゲームをプレイさせる」という方面への応用は古くから盛んであり、これまでに数多くのゲームについてそれを上手にプレイするAIが開発されています。 1990年代以降、チェス、オセロ、将棋、囲碁などの数々のアブストラクボードゲームにおいて、AIは人類最強クラスのプレイヤーを破るまでの強さを誇るようになってきています。 そして2010年代にDeepMind社のAlphaGoが、ゲームAIの最後の難関とされた囲碁で人類を完全に上回って以降、ゲームAI開発の潮流はポーカーや麻雀などの不完全(不完備)情報ゲームに移り始めています。
しかし、これらのAIは総じて「特定のゲームのプレイのみに特化しているAI」です。 これに対し、「どんなゲームでも上手にプレイできる汎用的なAI」を作ろうという動きもあります。 それこそが「General Game Playing」(GGP)と呼ばれる分野です。

Zillions of Gamesの誕生

英語版Wikipediaの記述によれば、GGPは1992年頃に誕生した比較的新しい研究分野です。
1998年、「Zillions of Games」(ZoG)という商用GGPソフトウェアが発売されました。 これは「Zillions Rules Files」という独自のDSLを用いてゲームのルールを形式的に記述し、それをソフトウェアに読み込ませると、 内蔵された汎用のゲームAIが自分でルールを解釈してCPU対戦をしてくれるという代物でした。 どうやらこのソフトウェアの反響は、少なくとも海外のボードゲームマニアの間ではかなり物凄いものであったらしく、 多くのユーザーが様々なゲームのルールのZRFファイルを作成し、競って公開しました(発売から20年以上が経った現在でも、ZRF作成をしているユーザーはそこそこいます)。 ZoGは現在でも販売が続けられており、この記事を書いている2020年12月下旬の時点で3055種類ものZRFファイルが公開されています。

しかし、Zillions of Gamesには致命的な欠点がいくつか存在しました。
細かいことを挙げて行けばキリがありませんが、概ね次の2つに集約されます:
1つ目:「ソフトウェア自体の仕様やZRFの機能的な制約により、ZoGでは実装することが難しいボードゲームがある」こと。
2つ目:「商用ソフトである関係上、ソースコードが公開されていない」こと。

1つ目の欠点が重大であることは誰の目にも明らかでしょう。 これについては色々な指摘がされていますが、日本語の情報としてはzillionsofgames @ ウィキに詳しくまとまっているのでそちらを参照してください。
とりあえず具体例を挙げると、ZoGは不完全情報(不完備情報)ゲーム、つまり麻雀などのような対戦相手の手の内が分からないゲームを遊ぶことは基本的にできません。 無理やりそれっぽく実装できないこともないのですが、ディスプレイ上の表示をどうにか隠すことはできても、内部処理の都合でZoGのAIには相手の手の内が丸見えになっているので、実質的にゲームとして成立しなくなってしまいます。
また、「一つの位置に複数の駒が存在する」という状態を考慮していないので、例えばマンカラなどのようなゲームは基本的に実装できません。 ZoGユーザーでボードゲーム愛好家のヴァレンティン・チェルノコフ氏は、「ZoGは基本的にチェッカーやチェスに似たゲームでなければ実装することができない」「それ以外のゲームも実装できないことはないのだが、それには巧妙なハックが必要になるし、よしんば実装できたとしても動作が不安定になる」と総括しています。

2つ目の欠点も、実は割と重大なものなのです。 上で説明した1つ目の問題点を誰かが完璧に解決できたとしても、ZoGがソースコードを公開していない商用ソフトである以上、自分でソースをいじくって再配布するという訳にはいきません。 またZoGはWindows環境にしか対応していないので、MacLinuxといったその他の環境では基本的に動きませんし、スマートフォンタブレットのアプリもありません。 自前で他の環境に移植するというのは至難の業です。 (一応、MacLinuxで動かす方法がないという訳ではないのですが、パソコンに不慣れなユーザーが容易く行えるようなものではありません。)

Dagazの誕生

先ほど発言を紹介したボードゲーム愛好家のヴァレンティン・チェルノコフ氏は、ZoGの欠点の解決を試みたボードゲーム制作・対戦ツール「Dagaz」を開発しました。言語は JavaScript であり、HTMLのcanvas要素に盤駒の画像を表示して動作する仕組みです。

Dagazで実装できるゲームの例については、Dagazの公式サイトを開いて、実際に遊んで体験してみてください。 glukkazan.github.io

Dagazの開発コンセプトについては、チェルノコフ氏本人による文章を翻訳した以下のエントリをぜひご覧ください。

stepney141.hatenablog.com

Dagazのメリット

拡張性の高さ

Dagazのソースコードはモジュール形式になっており、「ゲームのルールを記述するモジュール」「対戦用AIのモジュール」「描画処理のモジュール」といった各コンポーネントを組み合わせて1つのゲームを作る仕組みになっています。 このため、モジュールの追加・削除・書き換え・変更が簡単にできるようになっており、高い拡張性を持っています。

クロスプラットフォーム対応

先にも述べたように、Zillions of GamesはWindows専用に作られていたため、Macなどの環境で実行するのは難しくスマホで使うこともできませんでした。

しかし。DagazはJavaScriptとHTMLのcanvas要素を使って動くように設計されているため、 スマホだろうとパソコンだろうと、インターネットブラウザ1さえ使える環境ならどこでも動きます。 サーバとの通信もしないので例えスマホ機内モードにしていても使えます。

オープンソースである

Zillions of Gamesが完全クローズドソースであったことの反省を踏まえて、Dagazは全てのソースコードがMITライセンスで公開されています。
さらにGitHub上でOSSとして開発されているため、誰でも簡単に開発に参加できます。

こちらは周辺ツールも含めたソースコード本体のリポジトリgithub.com

そしてこちらは色々なゲームが実装されているDagaz公式サイトのレポジトリです。 github.com

Dagazの欠点と問題点

(拡張性が高いとはいえ)万能ではない

Dagazは元々、チェス・囲碁バックギャモンのような戦略的ボードゲームを実装するために作られたものです。 そのためあらゆるメカニクスボードゲームに適している訳ではありません。 より多くのメカニクスに対応できるよう改造することは十分に可能ではあるすが、とりあえず現時点での仕様では、実装できないボードゲームが存在するかもしれません。

パフォーマンスが低い

Dagazは完全なJavaScript製で、ブラウザ上のJavaScriptエンジンによって実行されます。 このためどうしてもパフォーマンスが低くなってしまい、組み込まれている対戦用AIも弱くなってしまっています(思考ルーチンを改良することである程度改善する可能性はあります)。

ドキュメントがない

開発者向けドキュメントはおろか、一般ユーザー向けの使い方説明も全くできていません。 DagazはZillions of Gamesの後継を目指して開発されているので、当然自分でゲームのルールを書いて読み込ませる仕組みがあります。 しかし現在この機構に関してリファクタリング作業をしている真っ最中であり、正直ドキュメントどころではないというのが現状です。

ソースコードが汚い

現在のDagazのソースコードは全てES5で書かれており、モジュールとかいう便利なものは一切使われていません。 ファイル間での変数のやり取りは全てグローバルスコープを介して行われており、当然ながら変数定義も全てvarなので処理を追うのも一苦労です。 ファイル名の命名規則もかなりめちゃくちゃで、ドキュメントはおろかソースのコメントすらほとんどありません。 さらに、ユニットテストやグラフィック部分のE2Eテストも満足に書かれていません。 コードの全容を全て把握しているのは、元開発者のチェルノコフ氏しかいません。

開発者がいない

現在開発に携わっているのは、プロジェクトを立ち上げたチェルノコフ氏と最近参加した私のたった2名のみです。 圧倒的に人手が足りません。 チェルノコフ氏も私もフロントエンド開発に詳しい訳ではないため、ぜひとも人手が欲しいと考えています。

まとめ

Dagazは本当に素晴らしいソフトウェアなのですが、とにかく開発者が足りません。 現在、私とチェルノコフ氏は現在のDagazの欠点を解消したアップデート版の開発を進めています。

github.com

フロントエンド開発に詳しいボードゲーマーの皆さん、ぜひDagazをより良いものとするためにご協力いただけないでしょうか。


  1. ブラウザ側の機能の関係で、Google ChromeFirefox・Edgeでの利用をオススメします。Internet ExplorerSafariは非推奨です。

関数電卓プログラミングの世界:闇の魔術編

この記事は、闇の魔術に対する防衛術Advent Calendar 2020の第23日目の記事です(投稿は24日目)。遅刻本当にすみませんでした。 qiita.com

また、本記事は以下の別記事を読んでいることを前提に書かれています。そんなに長くないのでぜひ併せてご覧ください。 stepney141.hatenablog.com


今年も盛り上がっている闇の魔術に対する防衛術アドカレですが、私には闇の魔術を自ら操ってその成果を解説できるような能力はありません。 なので代わりに、関数電卓(高機能電卓)でのプログラミングの世界で、私が闇の魔術が使われていると感じた技術・出来事をいくつか紹介してみます。

RSA署名鍵リバースエンジニアリング事件

高機能電卓に関する(色んな意味での)闇のレベルを知るにはこの事件について解説するのが一番でしょう。

きっかけは2009年7月、とあるマニアがTexas Instruments (TI) 社製の高機能電卓「TI-83 Plus」のファームウェア(OS)に付けられていたRSA暗号電子署名鍵を素因数分解し、秘密鍵の値をインターネットフォーラムで公開したこと。 当時、TI電卓のOSにはRSA-155による認証鍵が付与されており、これによってOSが確かにTI社公式のものであることを保証し、同時に署名されていないOSの実行を弾いていました。 しかしこれは、電卓に自前のファームウェアを入れて遊びたいマニアにとっては厄介な存在でした。 ところが、秘密鍵さえ分かってしまえば、自前のファームウェアだろうと公式の鍵で署名をしてしまうことが可能になり、「これは正規のファームウェアである」と認識されて何も特別なハックをしなくても電卓にインストールできるようになるのです。 そしてとあるマニアがこの鍵の値を突き止めてしまったという訳です。 ちなみにこのマニア本人が語るところによれば、素因数の特定には「一般数体ふるい法」(GNFS)というアルゴリズムを用い1Athlon 64 (1.9GHz) というCPUを搭載したPCで1745時間(=73日弱)を費やしたとのことです。
さらにこの投稿から約2カ月後、フォーラムのメンバーの共同作業により、OSをアップグレードする機能がある全てのTI電卓について認証鍵が特定されました。 これらの情報はマニアの間で広く知れ渡り、一部のマニアはバックアップ代わりに自身のWebサイトにこれを転載しました。

高機能電卓に自前のファームウェアを入れて何が嬉しいのかというと、公式のOSには搭載されていないがマニアからしたらぜひ欲しいという機能が使えるようになります。 高機能電卓マニアのコミュニティ上では、ゲームや便利系ツールや科学技術計算パッケージなど、電卓上で動く様々な種類のソフトウェアが大量に公開・やり取りされています。例えばticalc.orgはそうしたパッケージの交換プラットフォームの一つです。 こうしたソフトウェアをいくつも電卓に導入して用いる人やその開発者にとっては、多くのパッケージを管理できるファイルマネージャや、プログラムを簡単に書ける便利なエディタなどの機能が必要不可欠です (PCでコードを書く時もターミナルやらエディタやらの使い勝手って大事ですよね?それと似たような感覚だと思えばだいたい合っています)。 しかしメーカーは当然そんなハードコアな使い方を想定していませんから、そういう機能はメーカー公式のOSには搭載されていないのです。

これに対してメーカー側には、ユーザーによる不正な改造を積極的に防がなければならないそれ相応の理由があります。 欧米圏では、高機能電卓は中等教育・高等教育における理数系科目の学習に用いるためのものであり、高機能電卓を使って計算することを前提としているテストも多くあります(アメリカのSATなども確か部分的に電卓を使うらしいですね)。
このため、高機能電卓をハックする技術が下手に出回ると、それを利用してカンニングをする学生が出てくる恐れもあり、メーカーからしたらまあ非常に面倒くさいことになる訳です。 こういう事態を防ぐため、メーカー各社は電卓を不正にハックするような試みを排除しようとする傾向があります(会社ごとにかなりの温度差がありますが、その中でもTIはマニアに対し当たりが強いです)。

さて、フォーラムで公開された例の認証鍵ですが、この事実はほどなくしてTI社の知るところとなります。 当然のことながらTI社はこれを問題視し、認証鍵の情報を掲載しているフォーラムや個人サイトの運営者に対してDMCA通知を送付しました。 そして多くの人がこれを受理し、認証鍵の情報は削除されました。 DMCA通知。最近で言うとyoutube-dlで話題になったアレですね。
しかしこの措置のせいでかえって認証鍵の情報に注目が集まり、マニアの内外から「リバースエンジニアリングの権利を妨げる不法行為だ」という非難も出ました。 この結果、まさかのWikiLeaksにまで認証鍵の情報が掲載されるに至ります。 wikileaks.org

そして9月に入り、電子フロンティア財団(EFF)がこの問題に関与。 EFFはDMCA通知を受け取ったマニア3名を支援し、「TI社は無意味な法的脅しをかけている」などと批判する声明を出しました。 www.eff.org

EFFはTIに対し「このDMCA通知は不当なので削除された投稿を2009年10月26日に復帰する」という通告をしましたが、TIはこれを無視。 このため10月26日に、削除されていた投稿のうち2つが復活しました。 ですがTIはEFFに対して無視を決め込み、なおも他のサイトへ通知を出し続けたため、EFFはこれを非難する追加の声明を出すに至ります。 www.eff.org

結局TIはEFFの声明に終始反応しないまま通知の送付を止め、認証鍵の情報は2020年現在でもインターネット上でそのまま公開され続けています。

この事件については、英語版Wikipediaからの翻訳記事を書いたのでそちらも参照してください。 ja.wikipedia.org

余談ですが、ファームウェア改造の応用として「ある機種Aにうまく調整したファームウェアを書き込むことで、機種Aの筐体に機種BのOSを書き込む」なんてことも可能です。 また、インストールした複数のOSを適宜切り替えて使うためのツールなんてものも存在します。 さらにこの方面の改造の別パターンとして、関数電卓の機種Aの基盤に刺さっている抵抗のうち、特定のものを取り除くことでファームウェアを機種Bに変更できるというものがあります。

さて、この事件を通じて、高機能電卓のユーザーコミュニティには色々と闇でカオスでハードコアな側面がある事がお分かりいただけたことかと思います。

高機能電卓でMathematicaに勝てるのか

高機能電卓と一口に言っても色々な種類がありますが、数式処理システム(CAS)というものを搭載しているか否かによって大雑把に上位機種か下位機種かを分けることができます。 CASというのは、要はMathematicaとかWolfram Alphaとかああいう類のソフトウェアのことです。 CASを積んでいる高機能電卓は、例えば2100みたいな長大な整数の絡む演算を正確に行えたり(多倍長計算)、記号を含む数式を処理したり、方程式を解いたり、不定積分ができたり、グレブナー基底を求めたり、とにかく色々な計算ができます。 要は、高級な高機能電卓は肩にちっちゃいWolfram Alphaを載せているのだと理解していただければそれでだいたい合っています。

いくらちっちゃいWolfram Alphaかて大したことできひんのやろ?と思われるかもしれませんが、実はそうでもないのです。

1997年、数式処理分野の学会が開いたカンファレンス「ISSAC '97」において、一つのベンチマークコンペのようなものが開かれました。 各数式処理ソフトごとに複数の参加チームに分かれて、各チームは自分たちの数式処理ソフトを駆使して計算問題を解き、正答した数と解答の正しさを競うというものです。 参加した数式処理ソフトウェアはMacsyma、Reduce、MuPAD、Mathematica、そしてTexas Instruments社のCAS搭載高機能電卓「TI-92」の5つ。 そして出された問題は以下のようなものでした。

gist.github.com

この10問が現代の数式処理システムや数値計算パッケージで簡単に処理できるかどうかは私には分かりませんが、少なくとも1997年当時のコンピュータには非常に荷の重い問題であっただろうということは想像がつくと思います。


2021-01-04追記:矢吹太朗先生が検証をしてくださり、Mathematica v12.1にて少なくとも8つが処理できる*1ことが判明しました。有難うございました。


最終的に最も正答数を稼いだチームはどこだったのかというと、なんとMathematicaとTI-92が1位タイでした2。 また、カンファレンス出席者の投票により、TI-92チームの解答が最も"interesting"であったとして最優秀賞を獲得しました。

コンペ終了後、各チームは自分たちの解答とその手順を公開しました。

Mathematicaチームによる報告がこれ。 Mathematica solutions to the ISSAC system challenge 1997 | ACM SIGSAM Bulletin

そしてTI-92チームによる報告がこれです。 A TI-92 solution to the ISSAC '97 challenge problem 1 | ACM SIGSAM Bulletin

私は解析学線形代数を中途半端にかじっている程度の数学知識しかない非理工系のB1なので、ここで解説されている解法がいったいどういうものなのか完璧には理解できていないのですが、 しかしそれはそれとしてこの結果は、スペックがものすごくチャチであったTI-92であっても3、数学的能力に長けた人がうまく扱えばMathematica並みのことが可能になるということをこれ以上なく表しています。 筐体は極めてチャチではありますが、その潜在的能力は単なる教育用用途に留まるものではないことが示されていると言っても良いでしょう。

オーバークロック

高機能電卓は、当然ですがCPUを搭載しています。 しかし高機能電卓にいくらスペックの高いCPUを積んだところで使い道がありませんし、また消費電力も多くなってしまいますよね。 そのため特に昔の機種においては、やや性能が低めの組み込み向けチップを採用した上でクロック周波数を下げて販売されていることがあったそうです(昔のポケコンもこういうパターンが多かったらしいですね)。 しかしどこの世界にもオーバークロッカーという人種は存在するもので、彼らは高機能電卓の持つCPUのポテンシャルを最大限に引き上げることを楽しんでいます。 制約が大きい分、普通のパソコンでオーバークロックするよりも面白いところがあるのかもしれませんね。

そうしたオーバークロッカーが開発したオーバークロック用ツールはインターネット上で一般に配布され、誰でも使えるようになっています。 高機能電卓は基本的に動作がかなりトロいので、重い処理をさせたい人にとってはある種必須のツールと言えるかもしれません。 私も以前、高機能電卓でちょっとした数値計算をした際に計算時間短縮のためオーバークロックツールを使ったことがあります。

高機能電卓に積まれているCPUはメーカーによってかなり多種多様なのですが、 大きく分けてHP Saturnのようなメーカー独自の製品とMC68000Z80SuperH・ARMなどのメジャーな製品とに二分されます。 最近の機種ではeZ80とARMが主流ですね。 当然CPUや機種の仕様ごとにオーバークロックのメカニズムは全く異なるので一般的な手順については説明できないのですが、一例として最近出たこちらのエントリを見てみましょう。

www.zephray.me

この記事の作者の方は、TI社の最新機種「TI-Nspire CX II」シリーズのオーバークロックをいち早く成し遂げておられます。

リバースエンジニアリングに厳しいTI社はこの機種についても、認証されていないバイナリの実行が不可能なようにしているのですが、 ユーザーコミュニティではこの機種のOSに存在する脆弱性を突き(一種のゼロデイ攻撃のようなもの)、権限昇格攻撃を仕掛けてTI-Nspireシリーズでバイナリを実行するためのツール「Ndless」が開発されています。

github.com

stepney141.hatenablog.com

上で紹介した記事の作者の方は、オーバークロックを行うにあたってこのツールを利用することで、TI社のセキュリティをかいくぐって高機能電卓でC言語をビルドしたバイナリを実行しています。

高機能電卓でWin10 IoTを動かす

高機能電卓に自前のファームウェアを入れて動かそうという話は上で既に説明しましたが、高機能電卓に「既存のOSを入れてしまおう」というとんでもないことを考える人もそこそこいます。

高機能電卓にLinuxを導入している人がいることは前回の記事で説明しましたが、高機能電卓にWindows 10 IoTを導入してしまった人もいます。

www.imbushuo.net

この人がWin10を入れたのはHewlett Packard社製の「HP Prime」というモデルなのですが、この機種は競合他社のTexas Instruments社製電卓に比べてあまりハックが進んでおらず、これは色々な意味でとても興味深い偉業であると私は思っています。 巨人の肩に乗らずに何かを成し遂げるのって、特にこういう分野ではものすごく大変なことですよね。

まとめ

ここまで、関数電卓の闇の魔術というかマイナーでディープな世界の話をしてみました。 具体的な闇の魔術の話が出てこず興ざめだったかもしれませんがどうかご寛恕ください。 来年の闇の魔術アドカレではもっとディープな関数電卓の技術の話が出来るように、一年間精進しようと思います。


  1. GGNFS及びMsieveの2つの実装を併用したそうです。10年経った現在のCPUなら、73日どころか数時間で素因数分解できてしまいそうな気もします

  2. 参考文献:梅野善雄(2000)『グラフ電卓が切り開く数学教育の新世界』』6ページ、“TI-92 Wins System Challenge at Math Software Conference”

  3. CPU:10MHz の MC68000 / RAM容量:70KB ~ 100KB程度 (モデルごとに差がある)

*1:10問のうち2問はコンペ開始後に別の問題へ差し替えられており、矢吹先生が検証して下さった問題は差し替え前の問題。上で紹介した問題は差し替え後のもの

【WIP】フェアリーチェスのための駒表記ガイド 〜Betza's Funny Notation事始め〜:Part 2

※この記事は、以下の記事の続編であり、書きかけです。 stepney141.hatenablog.com

前回のPart1では、Betza's Funny Notationの基本となる事項を解説した。 今回のPart2では、BFNの拡張記法を解説していく。

Betza's Funny Notationの拡張

Part 1のラストでも述べたように、ここまで説明してきたBFNは、決してあらゆる駒の動きを表せる訳ではない。 また、別格に複雑な動きをする駒はBFNだと記述が過剰に長くなってしまい、読み解くのが大変になるという欠点もある。
BFNが広く使われるようになるにつれてこれらの欠点は徐々に無視できないものとなっていき、 そのうちに「既存のBFNでは不十分だから新しく記号を加えて拡張しよう」という動きが多く見られるようになった。
以下では、そうしたBFNの拡張記法を紹介していく。

留意点として、下で紹介する拡張記法類は原則としてお互いに互換性がなく、 同じアルファベットをお互いに異なる意味で利用しているものもある。 また、Betza氏によるオリジナルの記法と互換性を持つものと、BFNの仕様を独自に進化させて互換性を捨てたものがある。

Ralph Betza本人による拡張記法

これはBetza氏が"Chess on a Really Big Board"というフェアリーチェスを創作した際に導入した記法である。
原作者本人による拡張ということもあって、特に「q」修飾子については拡張ではなくオリジナルのBFNからあったものとして扱われることも少なくない。

円環ライダー

修飾子「q」を追加する。これは「円環ライダー(circular riders)」と呼ばれる種類の駒の動き方を表す。

この「円環ライダー」の概念は、実例を使わなければ説明が難しい。
qK というBFN表記は、フェアリーチェスやチェスプロブレムで用いられる「ローズ(rose)」という駒の動きを表す。

ローズの動き方は筆者の手に余る複雑なものなので、 詳しくはPiececlopediaあーかさか氏の解説記事といった、既存の分かりやすい図解を参照されたい。

go修飾子

修飾子「g」を「強制的に進む(go)」の意味で導入(上書き)する。

Betza氏は、シャンチーの「馬」の駒を例にしてこの記法を解説している。 下の図は馬の動き方を表したものである(XXXが馬の現在位置)。

+---+---+---+---+---+
|   | * |   | * |   |
+---+---+---+---+---+
| * |   | ^ |   | * |
+---+---+---+---+---+
|   | ^ |XXX| ^ |   |
+---+---+---+---+---+
| * |   | ^ |   | * |
+---+---+---+---+---+
|   | * |   | * |   |
+---+---+---+---+---+

馬はチェスのナイトと同じ動き方をする(*印のついたマス目に跳ぶ)が、 大きな相違点として「他の駒を飛び越えることが出来ない」。 より厳密に言うと、図中の^の位置が他の駒でふさがれている場合、 その方向の先にある*印に跳ぶことは出来ない。このルールを「絆馬脚」という。 「まず隣に1マスの^の位置に移動し、そこからさらに斜め1マス先の*の位置に移動する」と考えると理解しやすいかもしれない。

Betza氏は、このような馬の動きを「まず駒を取らずにW(ワズィール)の動きをした後、 さらにその位置から見てF(フェルズ)の動きを行うことが強制される」と解釈した。 そして氏はこれを、'go'の頭文字から取った修飾子「g」を用いて、
g[mWF]
と表記した。

Betza氏は拡張記法の説明で「gは使われていないので'go'の意味を割り振る」としているが、 実際にはオリジナルの記法で既に「グラスホッパー」の意味が割り振られている。 単にBetza氏が勘違いしていたのか、 あるいはグラスホッパーとしてのgが他の人にあまり使われていなかったので意味を変えたということなのかは、全く不明である。 紛らわしいためか、このgo修飾子が実際に使われている事例はあまり見られない。gはグラスホッパー修飾子として使われることが一般的のようだ。

then修飾子

修飾子「t」を追加する。これは「then」から取られたものである。

中世スペインに存在した古チェスに「グランド・アセドレフ(Grand Acedrex)」というものがある。 このチェスには現代にない動きの駒が多数あり、Betza氏はこれを表すためにthen修飾子を導入している。 例えば、「グリフォン(Griffon)」と英語では訳されている駒を見てみよう。 この駒についてはPiececlopediaに詳細な図解があるのでそちらをご覧頂きたいが、 ともかくその動きは
t[FR]
という表記で表せる。 これがどういう意味かと言うと、「最初に駒の現在位置から見てF(フェルズ)の動き方をし、そこからさらに続けて(then)、(盤の外側に向かって)R(ルーク)の動きをする」ということである。

XBetza

XBetzaは、コンピュータチェスエンジンと接続して利用するGUIソフトの一つ「GNU XBoard」(コンピュータ将棋で言うところの将棋所やShogiGUIに相当するソフト)で独自に用いられている記法である。 このソフトウェアは普通のチェスだけでなくフェアリーチェス類にも対応しており、入力されたXBetza表記を参照することで、 駒が利いているマスのハイライト表示や合法手生成などを実現している(らしい)。 そうした都合もあって、このソフトウェアにとってXBetzaはかなり重要な存在であり、色々な将棋・チェス類のルールに包括的に対応しなければならないため、 XBetza独自の色々な拡張記法が導入されている。
英語版Wikipediaでもちょくちょく使われているなど、見かける機会はそれなりに多い。

基本原子の上書きなど

基本原子「J」を「C」に、「Z」を「L」に、それぞれ変更する。
また、XBetzaでは角カッコ [ ] は廃止されている

アンパッサン

修飾子「e」および「i」を追加する。この両方を組み合わせて、チェスのアンパッサン(en passant)に準ずる駒の取り方を表す。

キャスリング

基本原子「O」を追加する。これはチェスのキャスリングに準ずる動き方を表す。

万能リーパー

基本原子「U」を追加する。これは「万能リーパー(Universal leapers)」に準ずる動き方を表す。

この「万能リーパー」というのは、「どんなマス目にでも一手でテレポートできる」という小学生がノリで考えたみたいな動き方をする駒である。 確かに万能というか、もはやチート級である。 しかし驚くべきことにこの分類に該当する駒はちゃんと実在しており、 例としては摩訶大大将棋泰将棋といった一部の古将棋に見られる「自在天王」の駒が挙げられる。

持ち駒

基本原子「@」を追加する。これは「その駒を持ち駒として盤上に打つことができる」という意味を表す。

方向を表す修飾子はこの基本原子につけても無意味なため、代わりにそれぞれ以下の意味でオーバーロードされる。

  • f:同じ種類の駒が既に存在している筋には、持ち駒として打てない(※例:二歩)
  • s:同じ種類の駒が既に存在している斜めのラインの上には、持ち駒として打てない(※二歩の斜めバージョンと考えるとわかりやすい)
  • b:同じ種類の駒が盤上のどこかに一つでも存在していたら、持ち駒として打てない

@の後に自然数nをつけた場合、その数字は「盤上の(自陣から見て)n段目から先には打てない」という意味になる。

上の記法を元に将棋の駒を表すと、二歩・行き所のない駒のルールにより、歩兵はfWf@8香車fR@8、桂馬はfN@7となる。他の駒は全て@9が付く。

again修飾子

修飾子「a」を追加する。これは「一つの手番の中で、一度ある動きをした後、さらにそれに加えて別の動き方をする」という意味を表す。
「a」は'again'から取られている。このagain修飾子があれば、上で述べたBetza氏による拡張記法のうち、go修飾子とthen修飾子は全くの無用の長物になる。
again修飾子とその応用は極めて重要かつ強力な記法なので、特に丁寧に解説する。

基本的な使い方

最初の例として、camKという表記を見てみる。
これは「一つの手番の中で、まず最初にcK(Kと同じ駒の取り方をするが、その方向には動かない)として振る舞った後、さらにmK(Kと同じ動き方をするが、駒は取らない)として振る舞う」という駒を表す。
この例では、aの前にある修飾子cを「最初の振る舞い方を表す引数」として取り、aの後ろにある修飾子mを「二番目の振る舞い方を表す引数」として取っている。 この駒は、例えば「隣にいる敵の駒を現在位置から動かないまま取った後、追加で1マス動く」みたいな振る舞いが可能になる。 しかし、ここで指定している「二番目の振る舞い方」はmK、即ち「キングとして動けるが駒を取ることはできない」ということなので、この駒は立て続けに二つの駒を取ることはできない。

XBetzaのオリジナルの解説では、again修飾子の説明にあたり「多脚(legs)」という概念を導入している。
ある駒がこのように複数の動き方を順々に行う場合において、一連の動き方を構成するひとつひとつの動き方のことを「脚(a leg)」という。
上のcamKの例で言うなら、最初の振る舞い方であるところのcKが「一本目の脚」にあたり、 二番目の振る舞い方であるところのmKが「二本目の脚」ということになる。
again修飾子は、要するにこの「脚」の概念を端的に表すための記法なのだ。

ここで、以降の説明を円滑にするため、XBetzaのオリジナルの解説を元に以下のような用語を導入する。

  • 開始脚(initial legs):n本の脚からなる一連の駒の動きの中における、1本目の"脚"のこと
  • 終端脚(final legs):n本の脚からなる一連の駒の動きの中における、n本目の"脚"のこと
  • 非終端脚(non-final legs):n本の脚からなる一連の駒の動きの中における、1本目からn-1本目までの全ての"脚"のこと
again修飾子の性質

このagain修飾子については、注意しておかなくてはならない性質(ルール)がいくつかある。

  1. again修飾子で指定された「一本目の脚」と「二本目の脚」は、必ず両方とも実行されなければならない(どっちか一方の振る舞い方のみをするという事はできない)。その手番でその駒を動かすことにしたら最後、両方の振る舞い方を完遂させなければならない。
  2. 「二番目の脚」の中で指定される進行方向の修飾子は、「一本目の脚」の動きを完遂した時点にその駒がいる位置が基準となる。駒の初期位置は基準にはならない。
  3. ルークやビショップのような限られた方向にしか進めない基本原子についても、その基本原子では本来進めないはずの方向を表す修飾子を適用できる。
  4. again修飾子は、同時に複数個利用できる。これにより、三本以上の脚がある動きも表現できる。
  5. 非終端脚はデフォルトで m を、終端脚は デフォルトでmc を、暗黙的な修飾子として持っているものとみなす。

これらのルールについて理解を深めるため、別の例をいくつか見てみよう。

masRは、「一本目の脚がmR、二本目の脚がsR」という動き方である。
これを噛み砕いて言うと、「一つの手番の中で二つの異なる振る舞い方をし(a)、一回目の振る舞い方においては駒を取ることはできず(mR)、二回目の振る舞い方においては一回目とは垂直な動き方をせねばならない(sR)が、二回目においては駒を取っても取らなくてもよい」という条件を持つルークを表している。
2.のルールにより、まずルークとして一回動いて止まった後、さらにそのマス目からスタートして、「今までの進路と垂直な方向にしか進めないルーク」としてもう一回振る舞うのである。

mafsRは、「一本目の脚がmR、二本目の脚がfsR」という動き方である。
これを噛み砕いて言うと、「一つの手番の中で二つの異なる振る舞い方をする(a)。駒を取らないルークとして敵の駒のないマスへ一旦動いた後(mR)、斜め45度方向に向きを変えてもう一度動く(fsR)」という動きを表している。
本来、ルークは斜め方向に進むことができない。しかし3.のルールにより、まずルークとして一回動いて止まった後、さらにそのマス目からスタートして、「斜め方向に薦めるルーク」としてもう一回振る舞うのである。

mamaKは、「一本目の脚がmK、二本目の脚がmK、三本目の脚がK」という動き方である。
これを噛み砕いて言うと、「任意の方向へキングの動きを三回行うことができる。三回目の動きの時には相手の駒を取ることができるが、 一回目と二回目の動きにおいては空のマス目にしか行くことができない」ということになる。

3.のルールを用いているのが、上の例のうちのmafsRだ。 このようにagain修飾子と方向修飾子をうまく使うことで、「R(ルーク)とB(ビショップ)」「W(ワズィール)とF(フェルズ)」「D(ダッバーダ)とA(アルフィル)」など、 縦横方向と斜め方向で動きが対になっている基本原子の組を『相互変換』することができる。
一見単にややこしいだけのように思われるかもしれないが、この『相互変換』を使えば、 例えば「一本目の脚が(駒を取れない)ルーク、二本目の脚がビショップ」といった二つの基本原子が絡むようなややこしい動きであっても、 mavRと簡潔に表すことができるようになるのだ。

5.のルールは、Part1で説明した「特殊ルールを表す修飾子」に関連する。
要するに、駒の動き方や取り方について特別に指定しない限りは、非終端脚はmという修飾子を、終端脚はmcという修飾子を、それぞれ暗黙的に持っているものとみなすということだ。
このルールは、例えばpシャンチーの砲のように、進行方向上にある駒を一個だけ飛び越えて着地する)のような修飾子を考える際に重要になってくる。
非終端脚についてmpという修飾子を付けた場合、
これを踏まえた上で、mc以外の特殊ルールを表す修飾子を使った例を見てみよう。

  • pasRは、「一本目の脚がpR、二本目の脚がsR」という動き方である。 これを噛み砕いて言うと、「他の駒を一個飛び越えて着地してからでなければ、直角に方向転換することができないルーク」ということになる。
  • cpasRは、「一本目の脚がcpR、二本目の脚がsR」という動き方である。 これを噛み砕いて言うと、「他の駒を、直角に方向転換することができないルーク」ということになる。
  • mpafsKは、チェスのナイトを基本原子を使わず表したものである。
性質と応用

このため、非終端脚におけるm修飾子・終端脚におけるc修飾子は、これを省略することができる。
この規則に従うと、maK(一本目の脚がmK、二本目の脚がK)という記述は、aKと略記することができる。
同様に、先程のmamaKaaKと省略することが可能である。
しかし、可読性を損ねるのでこの略記を実際に使うのはやめておいたほうがいいだろう。

Betza 2.0

Betza 2.0は、XBetzaをさらに拡張することで既存のBFNの持つ問題点を可能な限り解決しようとしたものである(らしい)。

丸カッコ記法

半角丸括弧 ( )を導入する。これは、特に何か新しい意味を追加するものではなく、 Betza's Funny Notationの「長くなると可読性が極端に下がる」という欠点を解決するためのものである。

連鎖(Chaining)記法

XBetzaでは、一手のうちに複数の異なる動きをする駒を記述するために「脚」の概念が導入されていた。
Betza 2.0では、これをさらに拡張して「連鎖(Chaining)」という概念を導入している。

XBetzaの「脚」の概念に基づいたagain修飾子は、ルールがややこしい上に、2つ以上の基本原子の動きを順番に行うような動きに弱かった。
Betza 2.0では、複数の脚からなる動きのことを「連鎖」と定義し、これを記述するための記法として半角ダッシュ記号 - を導入した。

例として、シャンチーの「象」の駒を見てみよう。 この駒は「斜め方向に2マス進むが、自分の斜め1マス隣に他の駒があればその先に進むことはできない」という動き方をする。 このルールを脚の概念を用いて再解釈すると「一本目の脚はmF、二本目の脚はF」と見ることができる。 Betza 2.0では、これを連鎖記法を用いて mF-F と表す。
同様にシャンチーの「馬」も、同じようにして mW-F と表すことができる。 BFNやXBetzaではnAと表していたものが、連鎖記法を使うことで、脚の概念に基づいて表すことができるようになるのだ。

別の例として、(チェスではないが)チェッカーにおける駒の取り方・動き方を見てみる。 これは連鎖記法と丸カッコ記法を用いることで、fmF(fcF-mF) と表される。 XBetzaでは、同じ動きを fcafmF と表す。Betza 2.0の方が記述は長いが、より分かりやすいものになったと言えるのではないだろうか。

XBetzaのagain修飾子と同じく、Betza 2.0の連鎖記法においても、駒の動き方や取り方について特別に指定しない限り非終端脚はmという修飾子を暗黙的に持っているものとみなされる。

したがって、先ほど例に挙げたシャンチーの馬 mW-F の場合は、m修飾子を省略して W-F と略記できる。

destroy修飾子

修飾子「d」を追加する。これは敵味方関係なく駒を取ることを表す。

test修飾子

修飾子「t」を追加する。これは自分の駒の上しか飛び越えることができないことを表す。

stray-off修飾子

修飾子「o」を追加する。これは盤の左右両端が繋がっている

変則将棋の「反射角」、またはフェアリーチェスのReflecting Bishop

unload修飾子

修飾子「u」を追加する。これは自分の駒を自分で取ることを表す。

変梃記法

「変梃記法(Quirky stuff)」

(W-F)0 は、シャンチーの馬を走り駒化させた「マオライダー」である。
※走り駒化のイメージについては、あーかさか氏の解説記事が分かりやすいと思われる。
これはオリジナルのBFNで言うところの nN0 と全く等価なのだが、Betza 2.0の「変梃記法」を用いた場合、駒が動けなくなる条件がより分かりやすくなるというメリットがある。

Bex Notation

これはフェアリーチェス創作家のDavid Howe氏が2012年に発表したもので、正式には"Proposed Betza Extended Notation"という。 これを略して「Bex Notation」と称しているというわけだ。 XBetzaやBetza 2.0よりも後に考案されたため、両者の記法を部分的に取り込んでいる。

この拡張では、アルファベット・数字・角カッコ以外の特殊記号を、「操作子(operator)」として多量に導入しているのが特徴である。
また、Howe氏自身が考案した特殊な駒の動きを表すための記法が多く用意されている。

グルーピング記法

丸括弧 ( )を導入する。これはBetza 2.0の丸括弧と全く同じ役割をし、意味上の区切りを明示するためのものとして使われる。

  • (A)は、普通の基本原子Aと全く同じ意味である。
  • (imfW2)(mfW)(cfF)は、imfW2mfWcfFと全く同じ意味である。※「i」は同じBex Notationのinitial修飾子(後述)

このように、丸括弧で「修飾子+基本原子」の組を一つ一つ囲っていくことで、意味上の区切りをはっきりさせて可読性を上げる働きがある。

継続操作子

半角ダッシュ記号 - を導入する。
これは、XとYを任意の基本原子として、X-Yとすることで「XとYの動きを繋げて実行する。途中で進行方向を変えられない」ことを表す。

これを用いると、上でも説明したシャンチーの「馬」の動きはmW-Fと表される。

Betza 2.0の連鎖記法と同じものである。

連続操作子

半角ダッシュ記号を2つ繋げたもの -- を導入する。
これは、XとYを任意の基本原子として、X--Yとすることで「XとYの動きを繋げて実行する。途中で進行方向を変えられる」ことを表す。

フェアリーチェス類の駒で、「ダブルナイト」というものがある。これは「まず駒を取らずにナイトの動きをし、続けてもう一回ナイトの動きをする(このときは駒を取れる)」という動き方をするものだ。
XBetzaのagain修飾子を使えばmaNとなるが、Bex Notationでは連続操作子を使うことでmN--Nと表す。

XBetzaのagain修飾子が形を変え、先程の継続操作子と役割を分割したものだと考えればよい。

合成操作子

半角プラス記号 + を導入する。
これは、XとYを任意の基本原子として、X+Yとすることで、普通のBFNにおける XY と全く同じ意味を表す。
これも丸括弧と同様、長いBFNの記述に合成操作子を挟むことで可読性を挙げることを目的としている。

imfW2+mfW+cfFは、合成操作子を使わずに書いたimfW2mfWcfFと完全に等価である。
また、これは上で説明したグルーピング記法(丸括弧)と併用でき、この例で言えば(imfW2)+(mfW)+(cfF)とも表すことができる(グルーピング記法の定義上、意味は変わらない)。

ライダー操作子

半角アスタリスク記号 * を導入する。
これは、Xを任意の基本原子として、X* とすることで、普通のBFNにおける XX と全く同じ意味を表す。

フェアリーチェスの中でもメジャーな駒として「ナイトライダー」というものがある。 これは、チェスのナイトの動きを拡張して、ルークやビショップのような「走り駒(ライダー)」に昇華させたものだ。 この駒の動きは文章よりも図で見た方が分かりやすいので、詳しくは丁寧な図解が載っているあーかさか氏の解説記事を参照されたい。
このナイトライダーの動きは、ライダー操作子を用いて N* と表される。

ナイトライダーと同じ要領で他にも色々な駒を走り駒へ拡張することが出来る。 シャンチーの馬を走り駒化させた「マオライダー」は、ライダー操作子を用いることで (mW-F)* と表される。

限定ライダー操作子

「修飾子+基本原子」の組の後ろに、2以上の数字を指定することで、 「最大で指定した数字の回数まで同じ動きを繰り返すライダーになる」という意味になる。

「最大で前に2マスまで進む(1マスだけでも良い)」という動きは mfW2 と表される。

厳密限定ライダー操作子

「修飾子+基本原子」の組の後ろに、2以上の数字を指定して、その数字の前に0を付けることで、 「指定した数字の回数だけ同じ動きを繰り返すライダーになる」という意味になる。

「前に2マス進む」という動きは mfW02 と表される。

Null-Move原子

基本原子「O」を導入する。これは(0,0)-Leaperを表す。

繰り返すが、これは(0,0)-Leaperである。つまり「その場から移動しない(Null-move)」駒である。
その場から動けないことに何の意味があるんだ?と思うかもしれないが、これは「手待ち」に使えるのである。
チェスはルール上パスが出来ず、その上「パスが最善手となる局面」、つまりどう駒を動かしても自分が不利になってしまう局面(これをチェス用語でツークツワンクという)の出現がたまによくある。
ゼロはこれを解消し、合法的にパスをするための手段として、チェスプロブレムやフェアリーチェスで導入されることがあるという。 日本の将棋類でも、ゼロ駒とは本質的に異なるものではあるが、古将棋類の「獅子」などの駒は同じような事が出来る(中将棋ではこの動き方を「じっと」という)。

royalty修飾子

修飾子「y」を導入する。これは「その駒がロイヤル駒である」ということを表す。

ロイヤル駒とは、王将やキングのように「これを詰まされる/取られると負ける」という駒のことである。 古将棋類に見られる「太子」という駒は、ロイヤル駒の一種である。 太子の駒がある古将棋では、王将と太子を両方とも取られたり詰まされたりしない限り負けにはならない。

initial修飾子

修飾子「i」を導入する。これを用いることで、最初にその駒を動かす時のみに適用される特殊な動き方を指定する。

チェスのポーンの「駒を取ることはできないが前に1マス進み、駒を取るときは斜め前に1マス進む。最初に動かすときのみ前に2マス進む」という動きは、
imfW2+mfW+cfF として記述することが出来る。

e修飾子

修飾子「e」を導入する。これは、本来なら駒を飛び越さない動きに付けることで、駒を飛び越える動きをすることを表す。
オリジナルのBFNであれば、同じようなことを「j」修飾子で表す。

将棋の桂馬は、e(mfW-F)と表される。

jump修飾子

修飾子「j」を、オリジナルのBFNで言うところの「p」修飾子の意味で上書きする。
Bex notationでは、「j」修飾子はリーパーに付けるものという前提が定められており、「j」修飾子をリーパーに付けることによってホッパーに変更する仕組みになっている。

Leaper記法

m, nを任意の自然数として、 (m, n) という記法を導入する。これは(m, n)-Leaperを意味し、これ単体で基本原子として扱われる。

成り駒記法

Bex Notationの後ろに「半角イコール記号と成り駒の動き」を付け加えることで、 「イコールの前にある動きの駒が、イコールの後ろにある動きの駒に成る(プロモーションする)」ということを表す。 成り駒が複数ある場合、半角カンマ記号で各成り駒を区切る。

例えばチェスのポーンの場合、クイーン・ルーク・ビショップ・ナイトのどれかに成ることができる。
これは imfW2+mfW+cfF=Q,R,B,N と表される。

なお、この記法は「この駒はこういう駒に成る」という変化の仕方のみを表すものであり、成るための条件を表す記法は用意されていない。
例えばチェスの場合、ポーンは自分から見て一番奥の段まで進まなければ成ることができない。 また摩訶大大将棋などの一部の古将棋では、本将棋などのように「敵陣に入ったら成る(不成も可能)」というルールはなく、代わりに「敵の駒を取ったら強制的に成る」というルールになっている。
Bex Notationでは、このような成りに関しての規定を表す記法は用意されていない。

エキゾチック操作子

フェアリーチェスの世界には、リーパー・ライダー・ホッパーの基本三分類に収まらないトリッキーな駒...Howe氏の言葉を借りれば"異風(Exotic)"な駒が頻出する。 そうした駒の動きは、基本原子と修飾子の枠に縛られるBFNでは表現することが難しい。 またBFNで使われていた角カッコ[ ]は、Bex Notationにおいてはここまで紹介してきた多様な操作子を使えば全くの無用の長物になる。 そこで、Bex Notationでは、基本原子と修飾子では表せないトリッキーな動き方を角カッコを用いて出来る限り表そうと試みている。

以下の説明において、大文字アルファベット M は任意の基本原子を表す。

  • [ca] = アドバンサー(Advancer)のような駒の取り方をする。すなわち、着地したマス目に隣接する位置にある駒を取る。
  • [cw] = ウィズドローワー(Withdrawer)のような駒の取り方をする。すなわち、着地したマス目から見て進行方向と逆側にある駒を取る。
  • [cj] = 駒を飛び越えて、その駒を取る。一手で飛び越えられる/取れる駒は一個だけ。
  • [cl] = 駒を飛び越えて、その駒を取る。一手で飛び越えられる/取れる駒は何個でもよい。
  • [ci] = カメレオン(Chameleon)。すなわち、自分に利きがある全ての駒の動きを模倣する。このタイプの動き方の例については、英語版Wikipediaによるカメレオンの解説が詳しい。
  • [ccM] = 敵の駒を挟み撃ち(custodial capture)する。すなわち、基本原子 M の動き方をし、はさみ将棋の要領で敵の駒一個を他の自分の駒とで挟んで取る。この取り方にはいくつか条件があるが、これについてはPiececlopediaの解説を参照。
  • [cu] = 自分自身を道連れにして、隣接するマスにいる敵の駒を取る。
  • [crM]= 自分から見て基本原子 M の利きに入っている駒を全て取る。
  • [xiM] = イモビライザー(Immobilizer)の効果を持つ。すなわち、自分から見て基本原子 M の利きに入っている敵の駒を全て「凍結(イモビライゼーション)」させ、その場から動けなくする。凍結させられた駒は、イモビライザーが別の場所に行くか取られるかするまで動くことができない。
  • [x!iM] = 自分から見て基本原子 M の利きに入っている敵の駒のうち、イモビライザーによって動けなくなっている駒を全て「解凍(アンイモビライゼーション)」させ、イモビライザーの効果を解除する。
  • [xwM] = 自分から見て基本原子 M の利きに入っている任意の駒(自分の駒も含む)の位置と、自分が現在いる位置を入れ替える。
  • [xo] = 自分が一手前にいたマス目へまた戻る。

エキゾチック操作子を用いて実際の駒の動き方を表したものとして、Howe氏は以下のような例を紹介している。

Modified Betza Notation

結局どれを使えばいいのか

どの拡張記法も一長一短なのだが、個人的には「広く使われている」 「オリジナルのBFNとの互換性をある程度保っており、覚えることが少ない」という理由からXBetzaを推奨したい。 しかし「汎用性が高い」「可読性に配慮している」 という点では、Bex Notationに軍配が上がる。 Betza 2.0も色々と便利な記法は多いのだが、どうも仕様自体が未完成っぽいので推奨はしない。

Bex Notationでは、操作子をいくつも追加するなどの大規模な変更を行うことで、 可読性を上げる・XBetzaのagain修飾子の難解な仕様を分解する・オリジナルのBFNの曖昧な仕様を厳密にするなどの改良を行っている。
しかし、オリジナルとのBFNとの互換性が壊れてしまっている箇所や、改良しようとするあまり仕様がかえって分かりにくくなってしまっている箇所が見られる。

はっきり言ってどの記法も一長一短であり、全てのメリットを取り込んで互いのデメリットを打ち消し合っているような、統合された記法が必要かもしれない。
しかし、マニアの間でのデファクトスタンダードはXBetzaであると断言しても問題はないだろう。

参考文献

BFNの総合的な解説

拡張記法の解説

フェアリー駒の事典や解説など

フェアリーチェスのための駒表記ガイド 〜Betza's Funny Notation事始め〜:Part 1

はじめに

世界には、将棋やチェスの他、インドのチャトランガ・中国のシャンチー・ペルシアのシャトランジ・朝鮮半島チャンギなど、 将棋やチェスに類似したボードゲームが大量に存在する。 また、既存のボードゲームのルールをマニアが独自にアレンジした「変則ルール」とか「フェアリールール」と呼称されるものもある。 さらには、そうした変則ルールを採用した詰将棋チェスプロブレム(※詰将棋のチェス版みたいなもの)も存在する。

これらの将棋系ボードゲームの中には、一般的なボードゲームには登場しないマイナーな駒も多く存在する。 そしてその中には、簡単には理解しにくいトリッキーな動き方をするものも少なくない。 自然言語でそうした複雑の動きを記述しようとすると、当然の帰結として説明自体も長く複雑になってしまいがちであり、 ひいては誤解や誤記が生じることにもつながりかねない。 この問題を解決するため、決まった記号の組み合わせで可能な限り多くの駒の動きを表現しよう!という欲張ったことを考えた人物が歴史上には複数存在した。 現在では、その中の一人であるRalph Bezta氏が考案した記法「Betza's Funny Notation」が、マニアの間で最も広く利用されていると断言してよい。 この記事は、この「Betza's Funny Notation」とその拡張記法の詳細を駒の実例を挙げつつ紹介するものである。

Betza's Funny Notation

1. 概要

Betza's Funny Notationは、世界の将棋類の駒の動きを体系的に表記するための記法である。
チェスのFIDEマスターにしてフェアリーチェス創作家でもある、アメリカのRalph Betza氏によって考案された。

Betza's Funny Notationの特徴は「駒の動き方を細かく分解して、基本的な駒の動きの組み合わせとして表現する」という原則に基づいていることにある。 例えば、将棋をすでに知っている人がチェスの駒の動きを覚える時、その人は「クイーンは飛車と角行を合わせた動きをする」という風に認識するだろうし、 逆にチェスをすでに知っている人が将棋の駒の動きを覚える時は、「香車は前方向にしか進めないルークだ」と認識するかもしれない。 Betza's Funny Notationでは、これと似た表し方をする。 つまり、「この駒はナイトとキングを合わせた動き」「この駒は2マスまでしか動けないルーク」という要領で、 あらゆる駒の動きを一般的な駒の動きの組み合わせに分解して表記していくのである。

知識がなければ一見して分かりにくい表記となるのが欠点ではあるが、 汎用性・柔軟性・拡張性に富んでおり、チェスプロブレムを中心に広く用いられている。 例えば、英語版Wikipediaで古将棋関係のページを開くと、駒の動きを解説するパートにはほぼ必ずその駒のBetza's Funny Notation(の拡張記法)による表記が付されている。
以下、特記しない限り「Betza's Funny Notation」を「BFN」と省略して書く。

BFNは、例えば以下のような英数字の列として記述される:

  • 例1) fhNfrlRK
  • 例2) fsLloRgBK

BFNは決められた規則に従って記述されるものであり、その法則から逸脱することはない。

2. 基本ルール

BFNの基本となる要素は、次の2つのみである。

  • 大文字アルファベット:「基本原子(atoms)」
    • 駒のベースとなる動きを表す。
  • 小文字アルファベット:「修飾子(modifiers)」
    • 大文字の基本原子を修飾して、基本原子だけでは表せない様々な動きやルールを補足する。

大文字X, Yと小文字a, bを用いて、BFNの基本的なルールを簡単に示す。
なお、これらのアルファベットはあくまで説明のために便宜上使用しているものであり、以下の例がそのまま実際のBFNの表記というわけではない。

例1: aX
この例では、Xという基本原子の動きをベースとして、その動きをaという修飾子で補足している。
やや乱暴な例えだが、英語の形容詞と名詞の関係に近いかもしれない。形容詞が修飾子、名詞が基本原子にそれぞれ相当すると考えればいいだろう。

修飾子が一つの基本原子に複数付くことも出来る。
例2: abX
この例では、Xに当たる基本原子の動きに基づき、その動きをaとbの2つの修飾子で補足している。
先の比喩で言うと、英語でも2個以上の形容詞で1つの名詞を修飾することがあるが、それと似ている。

異なる基本原子が複数並ぶ場合もある。
例3: XY
この「XY」という表記は、「ひとつの手番でXまたはYの動きが出来る」ということを表す。
「XYZ」であれば、「XまたはYまたはZの動きが出来る」という意味である。
異なる基本原子が複数並んでいる時は、本来なら基本原子の間にあるはずの「or(または)」が省略されていると考えるといい。
例えばXYX or Yを略したものとみなせる。すなわち、「XまたはYの動きをすることが出来る」という意味だ。
ルークの動きを表す基本原子をR、ビショップの動きを表す基本原子をBとすると、 クイーンの動きはRBというBFNで表現できる。
これは「ルークまたはビショップのどちらかの動きを選んで、その動きに従って駒を動かす」という意味である。

同じ基本原子が2つ並ぶ場合もある。
例4 : XX
基本原子Xを2つ連続させた場合、その駒はXの動きを無限にすることが出来ることを表す。

基本原子の後ろに数字を付けた場合、基本原子の動きがその数字の分に制限されることを意味する。
例5 : X5
この例の場合、Xという動きを出来る範囲が5マスであるということを表している。

複数の基本原子を[](角カッコ)で囲んだ場合、それらを基本原子をまとめてひとつの基本原子とみなす。
例6 : [XY]
この例の場合、「まずXの動きに従って駒を動かし、次にYの動きに従って駒を動かす、という操作を1回の手番で行う」という意味になる。
例7 : a[XY]
角カッコで囲んだ基本原子の組にも修飾子を適用できる。

3. 基本原子

まず、実際のBFNで用いられる基本原子(atoms)の一覧を見てみよう。

Fig.01
(Oが駒の現在位置。
基本原子が書いてあるマスが、その基本原子が表す動き)
+---+---+---+---+---+---+---+
| G |   |   | H |   |   | G |
+---+---+---+---+---+---+---+
|   | A |   | D |   | A |   |
+---+---+---+---+---+---+---+
|   |   | F | W | F |   |   |
+---+---+---+---+---+---+---+
| H | D | W | O | W | D | H |
+---+---+---+---+---+---+---+
|   |   | F | W | F |   |   |
+---+---+---+---+---+---+---+
|   | A |   | D |   | A |   |
+---+---+---+---+---+---+---+
| G |   |   | H |   |   | G |
+---+---+---+---+---+---+---+
Fig.02
(Oが駒の現在位置。
基本原子が書いてあるマスが、その基本原子が表す動き)
+---+---+---+---+---+---+---+
|   | J | L |   | L | J |   |
+---+---+---+---+---+---+---+
| J |   | N |   | N |   | J |
+---+---+---+---+---+---+---+
| L | N |   |   |   | N | L |
+---+---+---+---+---+---+---+
|   |   |   | O |   |   |   |
+---+---+---+---+---+---+---+
| L | N |   |   |   | N | L |
+---+---+---+---+---+---+---+
| J |   | N |   | N |   | J |
+---+---+---+---+---+---+---+
|   | J | L |   | L | J |   |
+---+---+---+---+---+---+---+
  • A:シャトランジの「アルフィル」(Alfil, 象)。間にある駒を飛び越えつつナナメ方向の2マス先へ進む。
  • D:タメルラン=チェスの「ダッバーダ」(Dabbaba, 攻城兵器)。間にある駒を飛び越えつつタテかヨコの2マス先へ進む。
  • F:タメルラン=チェスの「フェルズ」(Ferz, 将)。ナナメに1マス進む。
  • G:「トリッパー」。間にある駒を飛び越えつつナナメ方向の3マス先へ進む。
  • H:「スリーリーパー」。間にある駒を飛び越えつつタテかヨコの3マス先へ進む。
  • J:「シマウマ」。間にある駒を飛び越えつつ、3マス直進して、さらに左右のどちらかに2マス進んだ位置に進む。
  • L:「ラクダ」。タメルラン=チェスのズラーファ(Zurafa, キリン)と同じ。間にある駒を飛び越えつつ、3マス直進して、さらに左右のどちらかに1マス進んだ位置に進む。
  • N:チェスのナイト。間にある駒を飛び越えつつ、2マス直進して、さらに左右のどちらかに1マス進んだ位置に進む。
  • W:タメルラン=チェスの「ワズィール」(Wazir, 宰相)。タテヨコに1マス進む。

WとFの2つは言うなれば「単位原子」とでも言うべきもので、この2つさえあればR(ルーク)・B(ビショップ)・Q(クイーン)・K(キング)を全て表すことが出来る。 まずキングは「8方向全てに1マス進める」駒なので、WFというBFNで表すことが出来る。 Wを2つ重ねてWWとすれば、「Wの動きを無限に出来る」という意味になり、これはすなわちルークの動きである。 同様に、FFはビショップの動きを表す。 そしてクイーンはルークとビショップを合わせた動きをするから、WWFFまたはRBと表せる。

糖衣構文

  • R:チェスのルーク。タテヨコ方向にどこまでも動く。WWと同じ。
  • B:チェスのビショップ。ナナメ方向にどこまでも動く。FFと同じ。
  • Q:チェスのクイーン。タテヨコ・ナナメ方向にどこまでも動く。RBまたはWWFFと同じ。
  • K:チェスのキング。全方向に1マス動く。WFと同じ。

4. 修飾子

修飾子(Modifiers)は基本原子を修飾し、基本原子だけでは表現できない動き方や駒の取り方などを補足する。 実際のBFNで用いられる修飾子の一覧を見てみよう。

方向を表す修飾子

  • b:後ろ方向(backwards)
  • bb:後ろ側の中の後ろ(backward-backward)
  • bs:後ろ側の中の横(backward-sideways)
  • bh:後ろ半分(backward-half)
  • f:前方向(forwards)
  • ff:前側の中の前(forward-forward)
  • fs:前側の中の横(forward-sideways)
  • fh:前半分(forward-half)
  • h:半分(half) ※基本的に「f」や「b」とセットで使う
  • l:左方向(left)
  • r:右方向(right)
  • rl:右方向または左方向(right-left) ※「s」と同じ
  • s:右と左(sideways) ※「rl」と同じ
  • v:前と後ろ(vertical) ※「fb」と同じ

特殊ルールを表す修飾子

  • c:その方向に進んで駒を取る。基本的に「m」とセットで用いる
  • g:グラスホッパー(grasshopper)と同じ駒の動き方をする。すなわち、進行方向にある他の駒を1個だけ飛び越えて、その1マス先に着地する
  • j:他の駒を飛び越える(jumping)
  • m:その方向に進むが駒は取らない。基本的に「c」とセットで用いる
  • n:他の駒を飛び越えることができない(non-jumping)
  • o:円筒盤(cylindrical)の動きをする。すなわち、まるで盤が円筒状になっていて両端が繋がっているかのようにして、盤の端っこから反対側の端っこへ1手で動くことが出来る
  • p:シャンチーの炮(pao)と同じ駒の取り方をする。すなわち、進行方向にある別の駒を1つ飛び越えて、その先にある駒を取る
  • z:ジグザグに動く(zig-zag, crooked)

5. Betza's Funny Notationの実例

Betza's Funny Notationを用いると、実に多くの種類の駒の動きが体系的・客観的に表記できる。
以下では様々な駒の動きを例として挙げつつ、BFNの基本原子・修飾子についてより詳しく掘り下げていく。

世界の将棋類の駒の分類

世界の将棋類の駒は、原則としてこれら3つに大別される(例外もある)。

  1. リーパー(Leapers, 飛び駒)
  2. ライダー(Riders, 走り駒)
  3. ホッパー(Hoppers, 跳ね駒)

BFNがこの分類に従って作られているという訳ではないのだが、この分類をイメージすると分かりやすい。

また説明の都合上、次のように将棋/チェスのマスを座標として表したものを導入する。駒の現在位置が原点(0,0)である。

+---------+---------+--------+--------+--------+
| (-2, 2) | (-1, 2) | (0, 2) | (1, 2) | (2, 2) |
+---------+---------+--------+--------+--------+
| (-2, 1) | (-1, 1) | (0, 1) | (1, 1) | (2, 1) |
+---------+---------+--------+--------+--------+
| (-2, 0) | (-1, 0) | (0, 0) | (1, 0) | (2, 0) |
+---------+---------+--------+--------+--------+
| (-2,-1) | (-1,-1) | (0,-1) | (1,-1) | (2,-1) |
+---------+---------+--------+--------+--------+
| (-2,-2) | (-1,-2) | (0,-2) | (1,-2) | (2,-2) |
+---------+---------+--------+--------+--------+
ライダー(Riders)

一つの方向にどこまでも行けるタイプの駒を指す。将棋の飛車や角行や香車、あるいはチェスのルークやビショップやクイーンなどが該当する。

ライダーに該当する基本原子を列挙する。

  • R:チェスのルーク。タテヨコ方向にどこまでも動く。将棋の飛車と同じ。
  • B:チェスのビショップ。ナナメ方向にどこまでも動く。将棋の角行と同じ。
  • Q:チェスのクイーン。この動き自体は「RB」というBFNで表すことが出来る(「Q」は一種の糖衣構文)。
  • K:チェスのキング。前後左右またはナナメ方向に1マス動く。

「1マスずつ進む動きを表す基本原子」も、「1マスしか動かないライダー」と見なすことが出来る。

  • W:タメルラン=チェスのワズィール(Wazir, 宰相)。タテヨコに1マス進む。
  • F:タメルラン=チェスのフェルズ(Ferz, 将)。ナナメに1マス進む。
リーパー(Leapers)

簡単に言うと「桂馬/ナイトのように、他の駒を飛び越して動く駒」を指す。
例えば桂馬は「2マス前に進んで1マス横に動く」ような動きをする訳だが、先述の座標表記を使うとこのような動きを一般化して表せる。

リーパーの動きは、任意の自然数m,nを用いて「(m,n)-Leaper」と一般化して表記される。 「(m,n)-Leaper」というのがどういう意味なのか、チェスのナイトを例にして説明する。
座標の原点(0,0)が今ナイトのいる場所だとすると、ナイトの行けるマスは
(1,2), (-1,2), (-2,1), (-2,-1), (-1,-2), (1,-2), (2,-1), (2,1) の合計8つである。
これを簡略化して、「前方向への動き方、つまり(1,2)と(2,1)の情報だけを記述して、後は(特別な指定がない限り)左右と後ろにも同じ動き方をする」という決まりにしておくのである。 したがって、ナイトは「(1,2)-Leaper」または「(2,1)-Leaper」と表記される。
なお、普通はx座標の数字がより小さい方を採用して「(1,2)-Leaper」と表すようである。

改めて一般化しよう。
(m,n)-Leaperとは、その駒の現在位置を原点(0,0)とした時に、 (m,n), (n,m), (n,-m), (m,-n), (-m,-n), (-n,-m), (-n,m), (-m,n) の8マスに動けるような駒である。

0≦m,n≦3 の場合は特によく出てくるので、BFNでは基本原子として割り振られている。
以下の表は、(m,n)の値ごとにフェアリーチェス界での一般的な名称とBFNの基本原子を示したものである。

m=0 m=1 m=2 m=3
n=0 - Wazir (W) Dabbaba (D) Threeleaper (H)
n=1 Wazir (W) Ferz (F) Knight (N) Camel (L)
n=2 Dabbaba (D) Knight (N) Alfil (A) Zebra (J)
n=3 Threeleaper (H) Camel (L) Zebra (J) Tripper (G)

(m,n)の座標表記を基に、上で紹介した基本原子を改めておさらいしてみよう。

  • A:「アルフィル」。(2,2)-Leaper。
  • D:「ダッバーダ」。(0,2)-Leaper。
  • G:「トリッパー」。(3,3)-Leaper。
  • H:「スリーリーパー」。(0,3)-Leaper。
  • J:「シマウマ」。(2,3)-Leaper。
  • L:「ラクダ」。(1,3)-Leaper。
  • N:チェスのナイト。(1,2)-Leaper。

ライダーの項で紹介した「W(ワズィール)」と「F(フェルズ)」が上の表に含まれていることから分かるように、歩兵や王将のような「1マスだけ進む駒」は広義のリーパーとみなすことが出来る。
また、ルーク・ビショップ・クイーンなどのライダーもWとFの組み合わせで表現出来る。すなわち、任意のライダーは広義においてリーパーとみなすことが出来るのである。

ホッパー(Hoppers)

「進行方向に別の駒(ハードル)がある時のみその駒を飛び越えて、その先に着地する」駒を指す。着地先に敵の駒があれば取れる。 代表例として、中国のシャンチーの「炮」がある。 BFNにおいては、基本原子だけでホッパーを表すことは出来ない。必ず修飾子を用いる必要がある。

BFNの実例

チェスの「ポーン」

まず、チェスのポーンの動きをBFNで表すと次のようになる。
fcFfmW
これはどのようにして読み解けばいいのだろうか。
大前提として、BFNでは「修飾子+基本原子」の組をいくつも繋げていくことで1つの駒の動きを表現する。 つまり、fcFfmWという動きはfcFという動きとfmWという動きを組み合わせたものだ。

では、まずfcFとはどのような意味なのだろうか。 各記号を分解すると、fcは小文字アルファベットなので修飾子、そしてFは大文字なので基本原子であることがそれぞれ分かる。 fは「forward(前方に)」、cは「capture(取る)」、Fは「Ferz(フェルズ)」(=ナナメ方向に1マス進む)を表している。 つまりfcFとは「前方にフェルズの動きで駒を取る」という意味となる。 「前方にフェルズの動き」とは、すなわちナナメ前方に1マス進むということだ。 それに修飾子「c」が加わる訳だから、 まとめると「ナナメ前方1マスの範囲にある駒を取る(が、その方向には進まない)」ということを表現しているということになる。

次はfmWを分解してみよう。 fは「forward(前方に)」、mは「move(動く)」、Wは「Wazir(ワズィール)」(=タテヨコ方向に1マス進む)の意味である。 つまりfmWとは「前方にワズィールの動きで移動する」という意味だ。 「前方にワズィールの動き」とは、すなわち前方向に1マス直進するということ。 それに修飾子「m」が加わる訳だから、 まとめると「前方向に1マス直進する(が、その方向には駒を取らない)」ということを表現している。

すなわち、fcFfmWというBFNは「ナナメ前方1マスの範囲にある駒を取り、前方向に1マス直進する駒」ということだ。 これはまさしくチェスのポーンである。

禽将棋の「鵰(くまたか)」

変則将棋の1つに「禽将棋(とりしょうぎ)」というものがある。名前の通り、駒の名前が全て鳥の名前なのが特徴である。
その中に「鵰(くまたか)」という駒があり、その動きは次のようになる。
fBfsWbB2bR
次は、このBFN表記を読み解いてみよう。

上でも述べたが、大前提としてBFNでは「修飾子+基本原子」の組み合わせをいくつも繋げることで、1つの駒の動きを表現する。 すなわち、上のBFN表記はfB or fsW or bB2 or bRを略したものと解釈できる。これら4つの「修飾子+基本原子」の意味を個別に見てみよう。

  • fB:「f(前方に)」と「B(ビショップ)」の組。つまり「前方にビショップの動き」=「ナナメ前方向にどこまでも進む」。
  • fsW:「f(前方に)」と「s(横方向に)」と「W(ワズィール)」の組。つまり「前方と横方向にワズィールの動き」=「前方か左右方向に1マス進む」。
  • bB2:「b(後ろに)」と「B(ビショップ)」と「2(2マス)」の組。つまり「後方2マスにビショップの動き」=「ナナメ後方に最大2マスまで下がる」。
  • bR:「b(後ろに)」と「R(ルーク)」の組。つまり「後方にルークの動き」=「後方にどこまでも直進する」。

これを可視化すると、次のようになる。

+---+---+---+---+---+---+---+
| * |   |   |   |   |   | * |
+---+---+---+---+---+---+---+
|   | * |   |   |   | * |   |
+---+---+---+---+---+---+---+
|   |   | * | * | * |   |   |
+---+---+---+---+---+---+---+
|   |   | * |XXX| * |   |   |
+---+---+---+---+---+---+---+
|   |   | * | * | * |   |   |
+---+---+---+---+---+---+---+
|   | * |   | * |   | * |   |
+---+---+---+---+---+---+---+
|   |   |   | * |   |   |   |
+---+---+---+---+---+---+---+

記事冒頭で挙げたfhNfrlRKfsLloRgBKも、BFN表記として正しい文字列である。 ここではその解答は載せないが、ここまで述べてきたBFNの解説を見れば、いずれも完璧に読み解けるはずである。

さて、鋭い方なら既にお気付きかもしれないが、ここまで説明してきたBFNは、決してあらゆる駒の動きを表せる訳ではない。 また、別格に複雑な動きをする駒はBFNだと記述が過剰に長くなってしまい、読み解くのが大変になるという欠点もある。
BFNが広く使われるようになるにつれてこれらの欠点は徐々に無視できないものとなっていき、 そのうちに「既存のBFNでは不十分だから新しく記号を加えて拡張しよう」という動きが多く見られるようになった。
次回となるPart2では、そうしたBFNの拡張記法を見ていく。

参考文献

BFNの総合的な解説

関数電卓プログラミングの世界

この記事は、上智大学エレラボAdvent Calendar第1日目の記事です。 qiita.com

1日目ということで本来なら基調講演的なものをすべきなのかもしれませんが、一度もサークルとしての活動に参加したことがない人間にそんなもん書けるはずがありませんね。なので私個人の趣味の話をします。

私は「関数電卓でプログラミングをすること」が好きです。 しかしこの話を人にすると「関数電卓でプログラミングをするとは一体どういうことなのか」「関数電卓で一体何ができるのか」について不思議に思われることが多いので、今回はこの2つの話題について書きたいと思います。

関数電卓とは

理工学系の学生には馴染み深いと思いますが、関数電卓とは普通の四則演算に加え、 三角関数・指数関数・対数関数などに代表される高度な計算が可能な電卓のことです。

fx-jp500
一般的な関数電卓の一例

しかし関数電卓というのはこの写真のような種類の物だけではありません。 上位互換として複雑な計算を自動で行えるようにプログラミング機能を搭載した「プログラム電卓」や、 さらにその上位互換として、関数のグラフを表示する機能などが付いた「グラフ電卓」なんて代物も存在します (以下、こういった普通の関数電卓よりハイスペックな機種をまとめて「高機能電卓」と呼称することにします)。 私は数ある関数電卓の中でも、こうした高機能電卓でプログラミングをして遊ぶのが好きなんです。

fx-5800p
一般的な高機能電卓の例

注釈

関数電卓」や、よりハイスペックな「プログラム電卓」「グラフ電卓」の定義についてはマニアの間で議論の対象になっていますが、 この記事では実際に販売されている機種の特徴を鑑みて

  • プログラム電卓 := プログラミング機能がある関数電卓
  • グラフ電卓 := グラフ描画機能があるプログラム電卓
  • "グラフ電卓 ⊂ プログラム電卓 ⊂ 関数電卓" の関係が成立

と定義することにします。
本来の字義通りならば

  • プログラム電卓 := プログラミング機能がある電卓
  • グラフ電卓 := グラフ描画機能がある電卓
  • "(グラフ電卓 ∩ 関数電卓 ≠ ∅) ∧ (プログラム電卓 ∩ 関数電卓 ≠ ∅) ∧ (グラフ電卓 ∩ プログラム電卓 ≠ ∅)" の関係が成立

とすべきなのは確かです。 しかし現実に「グラフ電卓」として販売されている機種はほとんどが両者の積集合であり、 かつメーカー側はある機種が両者の機能を兼ね備えている場合「グラフ電卓」の呼称を優先する傾向があるため、 グラフ電卓はプログラム電卓の部分集合と見なして問題ないと私は考えています。
カシオなんかは「プログラム関数電卓」「グラフ関数電卓」として、あくまで関数電卓の上位機種として売り出していますね。

実際の機種

さて、高機能電卓が具体的にどのようなものなのか、実例とそのスペックを挙げながら探ってみましょう。

HP50g
HP 50g(画像出典:Wikimedia Commons

これはヒューレット・パッカード社製のHP50gという高機能電卓です。 既に廃盤済みのモデルですが、今でもコアなファンから根強い支持を得ている製品でもあります。 以下、スペックを見てみましょう。

はい、ぶっちゃけ超絶ちゃっちいですね。 しかしこれは2006年に販売開始されたモデルであることに注意が必要です。 当時のマシンスペックを考えれば、PDAとしてはそこそこのスペックだったのではないでしょうか。

プログラミングの観点から見たこの機種の特徴は、低レイヤまでアクセスする方法が多様に存在することだと思います。 この機種は RPL(Reverse Polish Lisp) というForthとLispを合体させたような独自のスクリプト言語をベースに、 スタックベースのREPL環境で操作をする仕組みがデフォルトで搭載されています。 しかし公式の開発環境を導入することでアセンブリ言語や「System RPL」という独自のコンパイル言語が利用可能になり、 さらにはマニアが開発した特殊なツールを利用してC言語でコードを書くことが可能です。 またこの機種は「従来機種で使われていたCPUをARM上でエミュレートする」という特殊な手法で動作するため、 使えるアセンブリ言語が2種類存在します(従来CPUのアセンブリとARMアセンブリ)。

2つ目に移ります。

NspireII
TI-Nspire CX II CAS (画像出典:Wikimedia Commons)

これはテキサス・インスツルメンツ社のTI-Nspire CX II CASという機種で、2019年から販売されている最新の現行モデルです。 このスペックは以下の通りです。

  • CPU:ARMコア (396MHz)
  • RAM:64MB (SDRAM)
  • ROM:128MB (ユーザー用NANDメモリ), 512KB (ファームウェア格納用NOR ROM)
  • ディスプレイ画素数:320 x 240

HP50gの時代から10年以上が経ち、ハードウェアのスペックも向上していることが分かります。

このモデルはデフォルトでTI-BASIC, Python, Luaの3つのスクリプト言語に対応しており、 さらにマニアが開発した特殊なツールを使うことで「脱獄」を行い、C++などのコンパイル言語を用いることが出来るようになります。 この「脱獄」はいわば電卓のOSにゼロデイ攻撃を仕掛けて任意コード実行を行っているようなもので、 抜け道を塞ごうとしてOSにパッチを当てるメーカー側と電卓をハックしたいマニア側との間でいたちごっこが続いています。

脱獄ツールではありませんが、過去には別の電卓のOSについてマニアがRSA電子署名鍵を破り、 その鍵の情報がインターネットに投稿されたことで法的措置に発展したことまであります(参考)。

3つ目に行きましょう。

Numworks
(画像出典:Wikimedia Commons)

これはNumworks社の高機能電卓、Numworksです(社名と同じ機種名)。2017年から発売されている機種です。 ハードウェアのバージョンはありますが、モデル名とは異なる概念なので割愛します。 このメーカーは基本的にこの電卓の製造・販売・サポートのみを行っている小さなメーカーで、 そこからして既存の巨大メーカーが製造している電卓とは大きく異なっています。 MicroPythonを搭載し、Pythonでプログラミングが出来るようになっています。

この機種には普通の高機能電卓と異なる点が多々ありますが、まず目につく特徴はキーアサインです。 一般に高機能電卓では、2乗・累乗・平方根・指数・対数などの普通の関数電卓ではよく使われるはずの機能が表側になく、 シフトキーを使わないと入力できない場合が多いですが、 この電卓ではこれら全ての機能が単独のキーとして割り振られています。

虚数単位 i にまで単独のキーがある関数電卓は、NumWorksの他はおそらくCASIO fx-5800p系統くらいだと思います。 しかしNumworksは多くの日本製モデルとは異なり、三角関数・指数関数・対数関数が複素数を引数に取れるようになっています。 このため、虚数単位の単独キーにちゃんと使いどころが用意されており、「こんなんにキーを1個割くくらいならもっとよく使う別の機能を割り振ればよかったのに...」というもどかしさを感じることがありません。 「出来る限り少ないキー入力で迅速に計算したい」という人にはこれ以上無い機種だと言えるでしょう。

ですがNumWorksの最大の特徴は、何と言っても「ハード・ソフトが両方ともオープンソースである」ということに尽きます。 ハードウェア・ファームウェアの両方ともの技術仕様が公式サイト上で公開されており、特に後者はOSSとしてGitHub上で開発されています。 www.numworks.com github.com この特徴は、市販されている関数電卓(グラフ電卓)としておそらく史上初のものだと思われます。 こうしたオープン性もあって、NumWorksは新興機種でありながらマニアから人気を集めています。

実際にできること

ここまでは高機能電卓がどういうものなのかイメージを掴んで頂くため、実際の機種について解説してきました。 ここからは実際の例を見て、高機能電卓のマニアがどのような遊び方をしているかを紹介します。

多様なユーザーコミュニティ

実例について紹介する前に、前提知識として(海外の)高機能電卓マニアのユーザー層やコミュニティについて説明を挟む必要があります。 まず、アメリカを始めとする一部の外国では、中等教育の数学の授業や大学入試にて高機能電卓が利用されることが一般的です1。 そうした教育を受けた中高生にとっては、高機能電卓はいわばありふれた学用品の一つです(多分)。 さらに近年ではSTEM教育のブームなどによるプログラミング教育の需要の高まりにより、 各メーカーからPythonを搭載した高機能電卓がいくつも登場するほどになっています。

このように、海外では高機能電卓を使う人間の母数が多いことから必然的にマニアの数も多く、 インターネット上には主に英語圏・フランス語圏の高機能電卓のマニアが情報交換を行うフォーラムがいくつも存在します (中国語圏については、フォーラムは分かりませんがマニア自体の存在は確認しています)。

日本人の高機能電卓のマニアがどんな人物なのかについては、私にはほとんど知見がないので説明を避けます。 ですが(高機能電卓ではない)普通の関数電卓のマニアの代表格は、やはり東海大学の遠藤雅守教授でしょう。 氏は物理学科教員としての立場から、実験系物理学の学習・研究において使いやすい関数電卓を求め、レビューや考察を『関数電卓マニアの部屋』というウェブサイトにまとめられています。 しかし氏は「関数電卓は高機能である必要はない」というポリシーを表明されており、 その視点は国内外のギーク的な高機能電卓マニアとは大きく一線を画しています。 ただ一つ間違いなく言えるのは、日本人の高機能電卓マニアは海外のそれよりも明らかに数が少ないという事です。

さて、実際にそうしたマニア達がどのような遊び方をしているのかを見ていきます。

物理演算

まずはこちらの動画をご覧ください(90度左に傾いているので注意)。 drive.google.com

これは私が3年ほど前に撮影した物です。 高機能電卓のデフォルトの機能を使って物理演算エンジンを呼び出し、電卓のUIから操作しています(元はユーザーマニュアル記載の動作デモであり、私がゼロから考えて作ったものではありません)。 ディスプレイ右側の目盛りをいじることで、跳ねるボールの数を増減しています。

有名ゲームの移植

スマッシュブラザーズを高機能電卓に移植した猛者もいます。 gigazine.net

フルカラー表示のモデルではMinecraftの移植もあります。 www.youtube.com

なお、高機能電卓へのゲーム移植は割とメジャーな分野で、Doomなどの他の有名ゲームの移植版もたくさんありますし、 新しい高機能電卓が出るたびにファミコンエミュレータが移植されていたりもします。 そもそも高機能電卓は学生が使うものでしたから、電卓でゲームをしたいという欲求を育む土壌がそもそも存在したのでしょうね。

Linux起動

Linuxの起動も割とメジャーに行われています。

下の動画では、Linuxの起動をしつつ元々の電卓のOSも起動できるようにするというデュアルブートを実現しています。 www.youtube.com

気象数値予報

また手前味噌で恐縮ですが、私は上で挙げたHP50gを使って「気象の数値シミュレーションをやる」という試みをやったことがあります。 気象学も数値計算もよく分からないままFORTRANのコードをRPLに移植しただけの代物なので挙動は全くもってガッタガタですが、 高機能電卓の可能性を示すという点ではそれなりに面白いことが出来たと思います。

詳細は下記事からPDFファイルをご覧ください。 stepney141.hatenablog.com


時間不足のため浅い内容になってしまったのが悔やまれますが、まあざっとこのような感じです。 高機能電卓は枯れた技術のようにも一見思われますが、実はそのディープな世界では今日も日進月歩で技術革新が行われ、 沢山の種類のソフトウェアが開発・配布され、さらに様々な試みがなされています。 皆さんも関数電卓プログラミングにチャレンジしてみてはいかがでしょうか?

12月中旬 1月以降をメドに、実際の関数電卓プログラミング入門手順について書いた記事を出す予定なので、記事が出たらそちらもぜひお読みいただければ幸いです。

※高機能電卓のよりディープな世界の話を書きました stepney141.hatenablog.com


  1. 上で触れたようなメーカーとマニアのいたちごっこの背景には、ハックされた電卓を使って入試で不正が行われたら困るというメーカーの思惑もあります。

【翻訳】Meet the Dagaz ! 〜汎用ボードゲームソフトウェアの開発〜

この文章について

ITエンジニア・ボードゲーム愛好家のヴァレンティン・チェルノコフ(Валентин Челноков)氏は、様々な種類のボードゲームをコンピュータ上で簡単に実装するためのフレームワークの開発に取り組んでおられ、これを "Dagaz(ダガズ) Project" と名付けています。

同様のものとして1998年に開発された "Zillions of Games" というソフトウェアが極めて有名ですが、その仕様には問題点や限界が多く見られます。 チェルノコフ氏は ZoG の問題点を解決した新たなソフトウェアを開発すべく、これまでに5年以上の歳月をかけて本体・デモを合わせて総計数十万行に及ぶコードベースを実装し、極めて汎用的で利便性の高いフレームワークを構築してきました。

しかしそれにもかかわらず、その知名度フレームワークの完成度に見合ったものとなっていないのが現状です。 その一因としては、ボードゲームマニアのコミュニティの間でDagazの存在が十分に周知されていないことが大きいと言えるでしょう。 氏が行っている宣伝活動は氏自身の母語であるロシア語での解説記事執筆が主であり、英語圏のコミュニティにDagazのインパクトが未だ届いていないのです。

今回チェルノコフ氏がボードゲームのオンラインマガジン "Abstract Games" 誌に執筆した記事 "Meet the Dagaz!" は、氏が Dagaz に関して執筆した2番目の英文記事であり、Dagazプロジェクトの概要・歴史・コンセプトを簡潔に説明したものとなっています。 本稿はチェルノコフ氏の許諾を得て、その記事を日本語に翻訳したものです。 特に補足が必要と思われる箇所については、注釈として訳注を付けています。併せてご覧下さい。 私の英語力は大変拙いものであるため、本稿には少なからぬ数の誤訳が含まれている可能性があります。 また意訳しているため、文の構成が原文と一致していない箇所があります。 誤りがありましたら訳者まで厳しくご指摘頂ければ幸いです。

なお、DagazプロジェクトはGitHub上で公開・配布がなされています(公式サイト(動作デモ有り)本体リポジトリ公式サイトのリポジトリ)。 ぜひ、公式サイト上のデモに実装されているゲームを色々と試してみて下さい。

※2022-12-09:誤訳や日本語としておかしい文章を修正

訳本文

Dagaz

私が名付けた "Dagaz" というプロジェクト名は、全23個の古代ルーン文字のひとつ"ᛞ"に由来しています。この文字が持つ意味の解釈の一つは「復活(revival)」です。 このルーン文字の形に私はボードゲームの駒を連想しますし、さらには「ゲームを遊ぶ人・ゲームを作る人双方のための汎用的なゲームソフトウェアを作り、これを用いてアブストラクト・ゲームにより興味を持ってもらいたい」――私のそのような考えが、文字の意味ともぴったり対応しているように思われるのです。

2つの出来事がきっかけで、私はボードゲームにのめり込むようになりました。 1つ目は、ドミトリー・スキュルーク氏(彼はロシアの作家で、囲碁・チェッカー・マンカラ系ゲーム(中でもアフリカに分布する系統のもの)の偉大な愛好家です)にお会いしたこと。 2つ目は、それと同時期に "Zillions of Games"(訳注:以下、"ZoG"と表記1)という汎用ボードゲームソフトウェアに出会ったことです。 運の悪いことに、私がこのソフトを知った頃には既に、ZoGに対する界隈の関心は衰え始めていました2。 ですが私はそんな状況を尻目に、ZoG上にいくつものゲームを実装しては、 ZoGについての解説記事を大量に執筆するという活動を続けました。 ZoGでゲームを実装する際には、 "Zillions Rules File"(以下、省略して "ZRF" と表記します)という独自のスクリプト言語を使用してゲームのルールを記述するのですが、 ZRF の強力さにはまさしく心を揺さぶられるものがありました。 ルールも見かけも全く異なる別々のゲームをこんなにも沢山作れるなんて、それ以前の私にはまるで想像もつかないことだったのです。

しかし、 ZRF の扱いに習熟すればするほど私はその欠点にもだんだんと気付いていくこととなりました。 その欠点とは「ZRF で簡単に実装することが出来るのは、極めて単純な――特にチェッカーやチェスに類似している――ルールのゲームのみである」ということです。 マンカラなどをはじめとしたより複雑なゲームを ZRF で実装しようとすると、ルールの記述は巨大で漠然としたものになり、動作も低速かつ信頼性に欠けるものになってしまいます。 この問題に直面した私は解決策を求めて、"Axiom Development Kit" を活用するようになりました。 これはグレッグ・シュミット氏が開発した ZoG の拡張プラグインで、DLLファイルとして ZoG に読み込ませることで動作します。 Axiom を用いることでリスモマチア(Rithmomachia)AG15を参照)などの比較的複雑なゲームも実装できるようにはなったのですが、これを使っても実装はやはり難解で時間を食うものになってしまうのです。 まだこの他にも欠点があります。というのは、Axiom と ZoG はいずれも Windows 上でしか動作しないのです。しかし私が求めていたのは、クロスプラットフォーム対応でどこでも動く、何ならスマートフォン上でも動作するソフトウェアでした。

以上のような欠点を解消したいという視点で考えると、開発に利用できる技術は自ずと限られてきます。 ほとんどあらゆるモダンなWebブラウザがネイティブにサポートしているプログラミング言語と言えばただひとつ、それは JavaScript です。 Javaアプレットを触るという選択肢は取りたくありませんでした。何しろ、今や時代遅れで不便な技術ですからね。 Web Assemblyもまた、別の理由から私にとっては適しませんでした。 というのも、私の目標は「あらゆるユーザーが自由にオープンソースのコードを参照でき、ソフトの仕組みを理解して、ZoG 同様にしかしずっと簡単に自分でゲームが作れるようにする」ことだったからです。

もちろん完璧なアプローチというものは存在しない訳ですから、当然JavaScriptという案にも欠点はあります。C++Javaといったプログラミング言語と比較して、JavaScriptでシステムを書くと、ユーザーが改造しやすくなる代わりにパフォーマンスが比較的低くなってしまうのです。 幾度も失敗を重ねた後、私は、ゲームを動かしながら ZRF を直接読み込んで解釈するというのは動作速度の問題から不可能らしいということに気付きました。 結局、私は ZRF を JavaScript に変換する "Z2J" というユーティリティを作ることでこれを解決しました。 Z2J で変換されたルール記述のコードは「自動生成臭」が強く、人間が直接編集するには不向きな難しいものですが、それでも ZRF のようにルール記述として解釈可能なようになっています。

Russian-Checkers
図1:ロシアン・チェッカー

私はまず、ロシアン・チェッカー(ルールはこちらを参照)から実装を始めました。 個人的に、この系統のゲームはあまりに過小評価されているという思いを常に持っていたからです。 このゲームの複雑なルールをきちんと理解できなくては、これ以上のあらゆる開発は無意味でしょう。

このゲームの注目すべきルールとして、まず「着手の複数性」があります。 これは「一回の着手において、立て続けに複数回連続して駒を動かすことが出来る」という大変重要な決まりです。 チェッカー類に関して他に重要なこととして、「着手の優先順位」というルールの実装をしたことが挙げられます。 このルールは、もしも取ることが出来る相手の駒があるならば必ず取らなくてはいけない、というものです(例え相手の駒を取ることで自分が不利になるような状況であってもです)。 このゲームのために私が最初に考えた「着手の優先性」の実装は、後に他のゲームの実装に移った際に根本から再考・修正をしなくてはならなくなったのですが、ともあれこのメカニズムがDagazプロジェクトの基礎をしっかりと形作ることになりました。

チェスにおいては、「複数の駒が一回の着手で一度に移動する場合がある」(例:キャスリング)ということに私は気付かされました。 さらに、「駒が動けるからと言って必ずしもその駒を動かしていいとは限らない」という性質もあります――例えば、キングがチェックをかけられてしまうような場所に自分からキングを動かすことは決してやってはいけないことになっています。 このため、私はチェックメイトを判定するアルゴリズムを実装する必要がありました。 チェックメイト判定(禁止手排除)はチェッカーの「着手の優先性」よりも困難です。何故なら、禁止手排除は「駒を取る手」と「駒を取らない手」の両方に適用されるからです。 また、チェッカー系ゲームでは禁止手について様々な判定基準が存在しうるため、これも単純とは程遠いと言えます。 可能な限り多く相手の駒を取らなければならないというゲームもある一方、例えばフリジア・チェッカーAG10を参照)などのゲームではそれに加え、「成った(昇格した)」駒を先に取るという優先順位が設けられています。

これらのとても複雑な概念をZRFの判定ロジックで記述することに貴重な時間を割き、さらにそれをJavaScriptに翻訳するなんて、例えそのやり方を知っていたとしてもそんなことをしている余裕は私にはありませんでした。 とにかく、そのようにしてZ2Jで得られるコードはまるで非効率だったため、直接JavaScriptで判定を書いてやる方がよっぽど理に適っていました。 というわけで、私はDagazにおいてあくまで駒の動きの基本的なルールを書くことにのみZRFを使い、複雑な判定は拡張機能として直接JavaScriptで書くことにしました。 ZRFで記述された基本的なルールに従って大まかな合法手の一覧を生成した後、ZRFでの表現が難しい処理を拡張機能で合法手に施してから、盤・駒の画面表示を更新します。 拡張機能では、複雑な判定や着手のフィルタリングなどといった様々な追加的処理を効率的にこなすことが出来ます。

Atari-Go
図2:アタリ碁(ポン抜き囲碁

アタリ碁3(ルールはこちらを参照)は、私が上で述べた仕組みの実例としてぴったりのゲームです。 囲碁の基本的な着手の仕方は大変シンプルで、石を盤上の空いた場所(交点)に置くだけです。 しかし、あらゆる場所に石を置けるという訳ではありません。自分の石の呼吸点がなくなるような手を自分から打つのは「自殺手」であり、そのような着手は禁止されています。 プレイヤーは、自分が石を置くと自分の石の呼吸点(石の上下左右方向に隣接する空白の点)が無くなってしまうような場所には、自分で石を置いてはいけません。また、石の一団が活きているためには、最低一つの呼吸点を持っていなければなりません4。 ゲームは次のように進行します――以上の原則を踏まえ、プレイヤーが着手した際、自分が置いた石によって対戦相手の石の呼吸点が全て潰されているかどうかを判定します。もしも相手の呼吸点がなくなっていたならば、相手プレイヤーの石を取り、盤上から取り除きます(アタリ碁では、一度でも相手の石を取った時点で自分の勝利となります)。 これらの判定と確認はZRFで記述するにはあまりに困難かつ厖大であり、ここで拡張機能の出番となるわけです。

Zillions of Gamesの動作を色々と試していた頃、私はZoGでの囲碁系ゲームの実装に関して他にも問題を見つけました。 大量の石を一度に取ると(このような状況が起こることは稀ですが、起こり得ない訳ではありません)、バッファオーバーフローが発生してソフトがクラッシュするのです。 ZoGは、各着手とそれによって発生する盤上のあらゆる変更を(ZSG棋譜という形式の)テキストとして保存します。 履歴には「この場所に石を置いた」という着手それ自体の情報のみならず、置かれた石とそれに隣接する石についてのあらゆる属性情報――どちらのプレイヤーの石か、石の位置はどこか、石は取られたか否か、など――も保存されるのです。 しかし囲碁においては、現在の盤面にたった一個でも石を置くだけで次に取られる石が完全に決定されるので、石がどこに置かれたのかさえ分かっていればそれで事足りるわけです。 囲碁やチェッカーなどのゲームでは、石を捕獲する際に石を盤上から除去する操作が伴う場合があります。Dagazではこのような捕獲を、着手の情報からゲームのルールに従って直ちに情報が求まる「副次的現象」としてみなしています。 プログラムのコア部分は、与えられたゲームのルールに則り、全ての変更と副次的現象をいつでも復元して自動で単一の変更の形に調整することが出来るようになっています。したがって、あらゆる情報を棋譜のテキスト内に詰め込む必要はありません。 結果、保存される着手の履歴は簡潔でスッキリとしたものになっています。

まだ他に1つ、Dagazが解決策を提示している既存の問題があります。それは、盤上の駒の位置をどうやって決定して画面に描画するかです。 ZoGでは「駒の属性を"Yes = 1"や"No = 0"のような感じで記述したビットフラグを複数持っておき、それらを各々の駒に割り当てる」という方法を取っていました。 これをチェスのキャスリング(ゲーム開始から今まで動いたことがないキング・ルークを一手で入れ替える操作)を例に解説しましょう。 ZoGのプログラムは駒に関するビットフラグを内部的に持っており、その中には「これらの駒は、キャスリング可能な条件から外れるような動きをしたか」というフラグも含まれています。キングやルークの駒が動くと、このキャスリング判定用のフラグがNoからYesに切り替わり、プログラムはこれを参照して「キャスリングは出来ない」と判断するというわけです。 Dagazは、ZRFが抱えていたデータ型に関する制限を回避しています。 真偽値以外にも、他のあらゆる種類の属性とそれに適する型の値を内部に持っておくことが出来るのです。 例として、穴(house)の中に入れる石(seeds)の数を表示するために整数型の値を使用しなければならない、マンカラ系ゲームの実装を見てみましょう。

オワレ
図3:オワレ

オワレ(ルールはこちらを参照)はアフリカのマンカラ系ゲームの中でも最も有名なものです。 ゲームは穴(house)1つにつき各4個ずつ石(seeds)を入れた状態でスタートします。 各手番では、まずプレイヤーは自分の陣地である6つの穴(両サイドの一回り大きな穴は「スコアリング・ハウス」といいます)の中から1つを選びます。 次に、その穴の中にある石を全て取り出し、その1つ右隣の穴を起点にして半時計回りの順番で、取り出した石を各穴に1個ずつ落としていきます――このプロセスを「石撒き(sowing)」と言います。 ただし、スコアリング・ハウスには石を撒きません。またスコアリング・ハウスが石撒きの起点になることもありません。 「最後に石を撒いた穴が対戦相手の陣地にある」なおかつ「石を撒いた結果その穴に2個または3個の石が入っている」場合、自プレイヤーはその穴の中の石を全て捕獲します。捕獲した石は穴から取り除き、自分のスコアリング・ハウスの中に移します。 加えて、最後から1つ前の穴も上の条件を満たしていた場合は同じように石を捕獲し、さらにその1つ前も条件を満たしていればまた同様に...という具合で、条件を満たさない穴にぶつかるまで時計回りに遡って捕獲を続けます。 以上のルールに従い、より多くの石を捕獲して自分のスコアリング・ハウスに移すことを目指すのがこのゲームの目的です。

Zillions of Gamesでマンカラ系ゲームのロジックを実装するのは、様々な理由から困難です。 まず最初のハードルは、このゲームで使う石の画像がたった1種類・1枚だけであるということです。 ZoGでは、「一つの穴に同じ種類の石や駒が複数個存在している」という状態を描画することができません。しかも描画処理をユーザーがプログラミング言語で拡張することも出来ないため、ZoGにおいてこの問題を直接どうにかすることは不可能です。 このためZoGでは、異なる数の石が穴に入っているという情報は、それぞれ別の種類の駒が存在する状態として記述してやる必要があります。言い換えると、石が1個あるという情報は内部的には駒1個が存在する状態として、石が2個以上という情報は内部的にはまた別の種類の駒が1個存在する状態として、それぞれ符号化します。 この方法では、対応する個数の石の組を記述するために必要な画像の数が増える問題が生まれます。 ZRFには整数値や整数の演算に関する機能もないので、この方法においても通常の加算と減算をエミュレートするためにビットフラグを利用しなくてはならず、実装は依然として複雑になります。 Axiom Development Kitでは整数演算が追加されていますが、それを使ってもなおマンカラ系ゲームの実装は難しいままです。 Dagazでは、このようなゲームの構造をもっとずっと単純に記述出来るようにしました。 しかも、この方が動作がより効率的になる傾向まであるのです。

Column-Checkers
図4:カラム・チェッカー

ロシアン・カラム・チェッカー(詳しくはAG1などの号を参照)――バシュネ(Bashne)という名前でも知られています――もマンカラ系のゲームとよく類似していますが、ひとつだけ相違点があります。 それは、このチェッカーではマンカラのように石を一つの穴の中にただまとめておく訳ではなく、石を一つにまとめる順番も重要な要素になっているということです5。 特定の順序で配置された要素を持つ"列(column)"を表現するのは整数値だけでは不十分なため、私はDagazが内部で保存している属性により多くの種類のデータ型を追加しました。 一つの列の中に石がどのような順番で積み重なっているのかを記述するため、Dagazでは属性情報として文字列を利用しています。 実際の所、Dagazでは配列でも他のどのようなデータ構造でも利用可能なようにはなっているのすが、外部ファイルへの保存のしやすさを考えて、文字列を使うのがベターかと個人的には思っています。 ソフトウェアレンダリングを用いて駒や石を表示するというのは、駒や石をプログラムで制御する上で非常に強力な機能でもあります。 このオプションをどう利用するかの例を解説しましょう。 囲碁には「スーパーコウ(超コウ)」というルールがあります6。これは、以前の盤面の状態が再び出現するような手を打ってはならないというものです。 このルールに従った禁止手を可視化するために、「禁止手になるからこの交点には石を置けない」という意味として盤上の交点の上に四角形を描画します。この正方形は駒や石として扱われる訳ではなく、単に画像として盤上に表示されます。 連珠AG5AG6を参照)では局面に応じて禁止手も変化しますが、禁止手の可視化には囲碁と同じく、ソフトウェア側で描画される四角形の仕組みを採用しています。

renju
図5:連珠

局面を前の状態に戻すことを禁止するゲームは、かなり複雑になりえます。 モラバラバ(Morabaraba)(ルールはこちらを参照)というゲームは、盤上の空いている場所に自分の駒(このゲームでは"牛"と呼びます)を並べ、自分の"牛"を3匹並べた列(このゲームでは"ミル(mill)"と呼びます)を作ることを目指すものです。 プレイヤーはミルを1つ作ったら敵の牛を1匹「撃ち」、その牛を盤上から取り除きます。撃たれた牛はその時点で二度と盤上に置くことが出来なくなります。 ミルを構成している牛は、相手の牛が全てミルになっていない限り撃たれることはありません。 別の新しいミルを作るために分解されたミルは、次の手番で再びミルになることは出来ません。 図6には赤いバツ印が描かれていますが、これは直前の局面で壊されたミルの位置を表すものです。 しかし、バツ印が付けられた場所であっても、この手番でミルを再び作り直さないならば、次の手番以降でそこに牛を置くことが出来ます。

Morabaraba
図6:モラバラバ

この「盤上に駒や石とは関係ない画像を表示する」という機能は、反復同形を禁止する以外の用途にも利用することが出来ます。 ゲームの中には、ゲームに関する何らかの情報がプレイヤーに隠されたまま進行する種類のものがあります。 普通、そのような種類のゲームと言えばカードゲームなどが代表的ですが、チェス系のボードゲームでも同じ類のものがあります。 暗闇チェス(Dark chess)というゲームでは、プレイヤーは自分の駒が利いているマス以外のマス目の情報を把握することが出来ません。 同じアイデアを他のチェス系ゲームに持ち込むことも可能です。

dark-yonin-shogi
図7:暗闇四人将棋

暗闇四人将棋四人将棋の変種です。 四人将棋は、日本の有名な7四人向けゲームです。 小型・中型の盤で遊ばれる他の伝統的な将棋類と同じく8、四人将棋は「持ち駒」のルールがあります。これは、「獲得した相手の駒を自分が保有し、自分の駒として使用することが出来る」というものです。 盤上にある駒を動かす代わりに、プレイヤーは自分の持ち駒を盤上に新しく置くことが出来るのです。 四人将棋の場合プレイヤーは4人いるので、4枚ある王将が1枚取られてもゲームは依然として進行し続けます。 獲得した駒は王将も含めて全て自分の持ち駒となり、王将を持たないプレイヤーはそれ以上ゲームを続けることは出来ません9。 そして、四人将棋は「暗闇で指す」バリエーションもあります。つまり暗闇チェスと同じように、「戦場の霧」という概念――ここではすなわち「自分の駒が利いていないマスの情報を隠す」ということ――を導入したのが、暗闇四人将棋という訳です。

これらの「暗闇のゲーム」が持つ構造的な特殊性を発展させて、Dagazでは空のマス目・駒があるマス目の両方を隠すための2つの特別な機能が利用できるようになっています。駒を「半透明」の状態にできる上、必要に応じて、マス目が空かどうかに関わらず、新しいレイヤーを追加するようにしてマス目の上にさらに画像を被せることができます。 個々の駒の表示は、他の駒の利きに入っているか否かによって制御されます。 もしも敵の駒が自分の駒の利きに入っていないならばその駒は表示されませんし、自分の駒についても同じようなチェックが行われ、敵の駒の利きに入っていない自分の駒は半透明になって表示されます。 原則的には、このようなチェックをするだけで隠す必要のある駒は全て隠すことが出来るはずです。 しかし、マス目が空なのかそれとも半透明の敵駒があるのかまでも明らかになるわけではありません。 このため、私はあるユーザーから「自分の駒が利いていない空のマス目にも目印を付けて欲しい」という要望を受けることになりました。 その解決策として、盤上に「雲(clouds)」を描画するようにしました(図7参照)。 「雲」は、そのマス目が自分の攻撃の範囲外にあることを示すためにソフトウェア側で描画された画像です。 プレイヤーは、現在の手番で「雲」がかかったマス目の中に半透明の敵駒が存在する可能性があり、そのマス目が空であるかどうかは分からないことに留意します。 ですが、「雲」も駒も存在しないマス目が正真正銘の空っぽであることは明らかです。

surakarta
図8:スラカルタ

このような抜本的な変更は、ゲームの表現をより良くすることのみに貢献している訳ではありません。 ガラ(Gala)("農民のチェス(Farmer's Chess)"としても知られています)のようなゲームでは、駒が移動中に行き先を変えることがあります。 スラカルタ(Surakarta)AG13を参照)というインドネシアのゲームでは、より興味深い状況が見られます。 このゲームにおける「相手の石の捕獲」の概念は、盤に描かれている合計8つのコーナーループのうち少なくとも1つに沿って自分の駒を動かし、相手の駒の上に着地してそれを取るという動作からなっています。 「捕獲」「非捕獲」のどちらの移動も、空のマス目を対象とした任意の方向への単一ステップとして実行されます。 このため、Zillions of Gamesのように「捕獲」の着手を開始位置から終了位置までの直線的な移動として表示すると、「捕獲」の移動が「非捕獲」の移動と混同されてしまう可能性があり、プレイヤーを混乱させるだけになってしまいます。 Dagazにおいては、駒の動きのアニメーション表示が可能なようにしました。 駒や石を動かすと、直線移動・斜め移動・曲線移動のいずれであろうと、駒や石が複数の地点を順番に通過するような動きをしても、その軌道全体がアニメーションとして表示されます。 スラカルタなどの一部のゲームでは、この機能は特に重要です。 また実用的な意味以外でも、この表示は視覚的に優れたグラフィックエフェクトとして機能します。

the-royal-game-of-ur
図9:ウル王朝のゲーム

最後に、ウル王朝のゲーム(Royal Game of Ur)について触れておきましょう10。 このゲームは長い年月の中でルールが完全に失われてしまい、発掘された当初は誰もその遊び方を知りませんでした。 歴史的見地から再現を試みたルールがいくつか提案されていますが、中でも私はこのルールが特に好きなのです。これは私の友人であり、作家でボードゲーム普及家のドミトリー・スキュルーク氏が考案したものでもあります。 当然ですが、Dagazプロジェクトではこのゲームを見逃さずに実装しているんですよ!

総括すると、私はボードゲームをより手早く実装するための便利なツールを皆さんにご提案したいと思っています。 DagazはZillions of Gamesプロジェクトのベースとなるアイデアを受け継いでいます。しかしZoGとは異なり、DagazはMITライセンスで公開されている完全オープンソースで無料のソフトウェアです。 現時点では、どのようなボードゲームでも遊べる汎用AIを搭載してはいませんが、思考エンジンをいくつか組み込んであり、必要に応じてそれらを全く別々のルール向けに改造することが可能です。 私は数年間もこのプロジェクトに取り組んでいまして、この短い記事でその全貌をお伝えするのは難しく、説明を端折った部分もあります。 もしも私のプロジェクトにご興味がお有りでしたら、お気軽にメールでご連絡下さい。 私のメールアドレスはDagazプロジェクトのGitHub Pagesをご覧下さい。


  1. これ以降の原文では、Zillions of Gamesは単に"Zillions"と略称されていますが、訳文では分かりやすさのため"ZoG"に統一しました。 略していない箇所はそのままにしてあります。また、原文では"ZRF"というドメイン固有言語の構文の制限を"ZoG"というソフトウェア自体の機能の限界として説明している箇所が多いことにも注意して下さい。
  2. 原文"Unfortunately, I got acquainted with this project quite late, when the main excitement around it had already begun to wane." ここでは"the main excitement"を「ZoGで色々なゲームを作ること」と解釈した上で意訳を試みました。
  3. Wikipediaの言語間リンクを見る限り、アタリ碁(Atari Go)は日本では「ポン抜き囲碁」と呼ばれているそうです。日本においては主に初心者の教育用であり、石を取る感覚を掴んだら卒業するものとされているようですが、個人的には9路盤でやると中々楽しいように思います(訳者が囲碁初心者だからかもしれませんが)。
  4. 訳者は囲碁のルールをほとんど知らないため、日本棋院Wikipedia のルール解説を基にかなり強引に訳しています。誤りがありましたらご指摘頂ければ幸いです。
  5. ロシアン・カラム・チェッカーでは、取った石を自分の石の下へ順番に積み重ねていき、石の "列(column)" を作っていきます。実際にDagazのデモ実装で遊んでみるとどういうことかよく分かると思います。
  6. 『一般的なコウのルールと違い、1つ前の自分の着手時の盤面とだけではなく、対局開始からのすべての盤面との同形反復を禁止したルールのこと。三コウの問題が発生しない。』(参考:囲碁用語辞典) 中国や欧米で使われるルールのようです。
  7. 原文では"a famous Japanese games for four players." 言うほど有名か?変則将棋マニアしか知らんだろ、という気もしますが、日本語版ウィキペディアによればこち亀で紹介されたこともあったらしいので全く無名ということもなさそうですね。
  8. 原文:"As with the other classical Shogi games which are played on small and middle size boards, Yonin Shogi saved the 'drop rule,'..." 古将棋の場合、持ち駒を使えるものはむしろ少数派に近いというのは明らかですが、原著者は将棋のマニアではないので仕方ないと思います。
  9. 原文"All captured Kings as well as other pieces are sent to the hand reserve, and the player left without a King cannot move his pieces." ただし日本版Wikipediaでは「詰められた王将はその場から動けず障害物とする」というような事が書いてあります。原著者がルールを誤解している可能性があります。
  10. このゲームの詳細については、英語版 Wikipedia の該当記事を参照することをオススメします。