Puzzlinkで新エディタを開発してみる日記<クロクローン編:完>
<前回はこちら>
先ほどいよいよ公式レポジトリにプルリクエストを投げてきましたので、こちらの記事も締めましょうか。すごい緊張した。大丈夫かな。
前回の記事では解答チェック機能まで組みあがり、開発のメイン部分が終わりました。
ここまで来たらあとはウイニングランというか、最後の仕上げ段階、いろいろなファイルにちょこちょこ追記する作業です。
1.テストスクリプトの作成
まずは公式リドミの手順通り、テストスクリプトを作りましょう。
テストスクリプトといっても、まじめなシステム開発でやる単体テストやら結合テストやらみたいなのというよりは、ルールページ用に不正解盤面の例をいくつか作って載せる作業がメイン。
場所は `src/test/script/kuroclone.js`。新たにファイルを作ります。
そして、内容はこんな感じ。
/* kuroclone.js */
ui.debug.addDebugData("kuroclone", {
url: "6/6/44ii000f01u0a32h13u44c",
failcheck: [
[
"cbShade",
"pzprv3/kuroclone/6/6/4/0 0 0 1 1 1 /0 0 0 1 1 1 /2 3 3 3 1 1 /2 3 3 3 1 1 /2 2 2 2 2 2 /2 2 2 2 2 2 /. 3,2 . . . . /. . . . 1,3 . /. . . . . . /. . . . . . /. . . . . . /. . 4,4 . . . /. . . . . . /. . . . . . /. . . . . . /. . . # # . /. . . . . . /. . . . . . /"
],
[
"anUnitNe",
"pzprv3/kuroclone/6/6/4/0 0 0 1 1 1 /0 0 0 1 1 1 /2 3 3 3 1 1 /2 3 3 3 1 1 /2 2 2 2 2 2 /2 2 2 2 2 2 /. 3,2 . . . . /. . . . 1,3 . /. . . . . . /. . . . . . /. . . . . . /. . 4,4 . . . /# . . . # . /# # . . . . /. . . . . . /. . . . . . /. . . . . . /. . . . . . /"
],
[
"bkUnitNe2",
"pzprv3/kuroclone/6/6/4/0 0 0 1 1 1 /0 0 0 1 1 1 /2 3 3 3 1 1 /2 3 3 3 1 1 /2 2 2 2 2 2 /2 2 2 2 2 2 /. 3,2 . . . . /. . . . 1,3 . /. . . . . . /. . . . . . /. . . . . . /. . 4,4 . . . /# . # . # # /# . # . . # /. # . # . . /. . # . . . /. . . # . . /. . . # # # /"
],
[
"bkDifferentShape",
"pzprv3/kuroclone/6/6/4/0 0 0 1 1 1 /0 0 0 1 1 1 /2 3 3 3 1 1 /2 3 3 3 1 1 /2 2 2 2 2 2 /2 2 2 2 2 2 /. 3,2 . . . . /. . . . 1,3 . /. . . . . . /. . . . . . /. . . . . . /. . 4,4 . . . /# . # . # # /# . # . . # /. # . . # . /# . # . # # /# # . # . . /. # . # # # /"
],
[
null,
"pzprv3/kuroclone/6/6/4/0 0 0 1 1 1 /0 0 0 1 1 1 /2 3 3 3 1 1 /2 3 3 3 1 1 /2 2 2 2 2 2 /2 2 2 2 2 2 /. 3,2 . . . . /. . . . 1,3 . /. . . . . . /. . . . . . /. . . . . . /. . 4,4 . . . /# . # . # # /# . # . . # /. # . . # . /# . # . # # /# . . # . . /# # . # # # /"
]
],
// there are no new elements in this puzzle...
inputs: []
});
最初にパズル名と例題用のURLを指定。
その後、本体スクリプトで作ったエラーコードごとに、具体的な不正解パターンの盤面を載せてあげます。この盤面は「ファイル→ファイル保存」で出てくる、改行ではなくスラッシュ区切りで出力される文字列をコピペしてきます。
最後は、エラーコードを「null」に設定し、正解盤面を同様に載せてあげれば完成。プログラムというよりは作業に近いです。
なお、最後の inputs は今回は空っぽですが、ここは何か新しいUI・盤面要素を追加した際のテスト用スクリプトになっています。
例えば、ヤジリンだったらこんな感じで無数のテスト項目が羅列されていますね。
inputs: [
/* 回答入力テスト */
{
input: ["newboard,5,2", "playmode"],
result:
"pzprv3/yajilin/2/5/. . . . . /. . . . . /. . . . . /. . . . . /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /"
},
{
input: ["mouse,left, 1,1"],
result:
"pzprv3/yajilin/2/5/. . . . . /. . . . . /# . . . . /. . . . . /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /"
},
...
]
文字列形式で盤面操作に相当する「コマンド」を順番に並べ、その結果出来上がっているべき盤面状態をresultに置いておくらしい。
コマンドはいろいろあるらしく、盤面生成からモード切替、マウスやキー入力のシミュレーションに至るまで大体揃っている感じなので、一通りの盤面操作が行えるようになっています。つまり、UIを巻き込んだ結合テストができるようになっているわけです。すごい仕組みだ。
今回は既存要素のツギハギで作れたので空白のままですが、次回は手を出さざるを得ないと思います。
ちなみに、入力UI周りの結合テストは上記ファイルでやりますが、パズル固有の単体テストは `src/test/variety/パズル名.js` で記述する様子。複雑な判定アルゴリズムを使う際は書いておくといいかもしれません。今回はやってないけど。
<メモ:単体テストフレームワークは mocha というやつを使っているらしいです。>
2.パズル関連の諸情報を追加
最初に src/pzpr/variety.js にパズル名を宣言しましたが、あれはあくまで「内部で」認識できるようにするための情報だったのでした。
いつも使っているトップページにリンクを張るには、ちゃんとそのページ用のスクリプトにも追記しなければなりません。
そこで、以下のファイル群にそれぞれ追加していってあげます。
・src-ui/list.html:トップページのリンク設定
・今回は「領域黒マス系」の枠に追加します。とりあえず年功序列の理に従うがまま一番下(カクテルランプの下)へ。
・src-ui/js/list.js:パズルの区分情報の設定
・定食、二軍、オモパ、といったパズル区分を設定するファイルなのですが、もはや秩序は崩壊しており、現二軍のチェンブロ・チョコバナナから海外産パズルに至るまで全部 "add" にぶち込まれている様子。でも一応歴史に従い「オモパ」の欄に追加しました。
・src-ui/img/パズル名.img:背景タイル画像
・これは任意なのですが、せっかくなので作っておきます。png形式で、サイズは任意(正方形でなくともOK)。例題以上にセンスが問われる。
・src-ui/js/ui/Misc.js:画像ファイル名の指定
・上で作成した画像のパスを指定する箇所がありますので、そこへ追記。
・src-ui/js/ui/KeyPopup.js:数字入力パネルの設定
・リドミでは言及がないので見落としやすいのですが、ここにも各パズルで一括設定している部分があったのでとりあえず。
・ここを設定すると「パネル入力モード」が有効になり、数字ヒントをパネル経由で入れられます。
// [編集モードでのパネル番号, 解答モードでのパネル番号] で指定。
// 0 : なし
// 10: 0~9まで数字を入れられるパネル
// 他の数字はこのソースの下の方を見てください。
kuroclone: [10, 0]
・res/ ディレクトリ以下:各種日本語・英語データの設定
・history.yaml には出典情報を記述します。ニコリの何号初出とか、それ以外なら原作者は誰々、とか。
・rules.yaml にはルール文を日本語・英語で記述します。
・p.yaml は全パズル共通のUI要素の言語設定なのでいじらない方が良い
まとめ:変更・追加されるファイル一覧
・src/pzpr/variety.js:新規パズル宣言
・src/variety/パズル名.js:新規パズルのメインスクリプト
・src/test/script/パズル名.js:解答例+入力テスト
・src/test/variety/パズル名.js:単体テスト
・src/res/failcode.en.json:失敗コードの文言定義(英語)
・src/res/failcode.ja.json:失敗コードの文言定義(日本語)
・src-ui/list.html:トップページのリンク設定
・src-ui/js/list.js:パズルの区分情報の設定
・src-ui/img/パズル名.img:背景タイル画像
・src-ui/js/ui/Misc.js:画像ファイル名の指定
・src-ui/js/ui/KeyPopup.js:数字入力パネルの設定
・res/history.en.yaml:出典情報(英語)
・res/history.ja.yaml:出典情報(日本語)
・res/rules.en.yaml:ルール文(英語)
・res/rules.ja.yaml:ルール文(日本語)
もちろん、大幅な変更を加える場合(例えば六角盤面や三角盤面を使うみたいなパズル)では、根幹のコア部分へ手を加えることも必要になるでしょう。まあここまでやるとなると管理コミュニティに参加して事前に相談した方がよさそうですけれども。
最後に
ここまできたらあとはgit操作の話になります。
・forkレポジトリを本家と同期し、 git fetch でローカル環境を最新状態へ更新。
・開発時のコミットを git rebase -i で一つにまとめて "Add パズル名" みたいなコミット文にしておき、リモートへpush
・プルリクエストを投げて気長に待つ。
最初ということもありましたが、思っていたよりハードな開発ではなかったなあという印象。やっぱAPIが整っているって大事なんだ。
他にもいろいろ作りたいオモパのエディタがあるので、今後も気が向いたらこれに味を占めて追加していくかもしれないです。
ありがとうございました。