Skip to content

Instantly share code, notes, and snippets.

@stepney141
Last active June 6, 2022 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stepney141/9a6446709751f7d9ec1758f47296bc75 to your computer and use it in GitHub Desktop.
Save stepney141/9a6446709751f7d9ec1758f47296bc75 to your computer and use it in GitHub Desktop.
  • universal
  • cross-platform
  • easy to implement games

The current version of Dagaz (v1.3.5) is based on Zillions of Games the general game playing software, but Dagaz has much wider flexibility. Dagaz makes it possible to develop abstract games that it is hard to implement even with Zillions of Games! In order to help your rapid development, we provide a special Java utility named "Z2J". It loads game descriptions written in Zillions Rules File format and converts them into JavaScript/HTML files that Dagaz understands. This transpiling system will be deprecated in future updates so that you will be able to start writing your own games directly in JavaScript.

  • バージョンの振り方を固定化する
    • github.ioの方はバージョン振ってあるけどDagaz本体には振られてない
  • Z2Jはレガシーだが、既存のDSLを変換できるという点で大きなメリットがある
    • 過去の資産を流用できる
    • 他システムとの互換性を持つこと自体がDagazの強みになりうる
    • 変換機構をもっとマシなものにする必要はあるが、「DSLからJSへのトランスパイル」自体はオプションのひとつとして残してもいいのではないか
  • 「ダガズ:XSLTアゲイン」
  • ZRFの内容をXMLで表現する試み
  • XSLTでZRF -> XMLの変換フォーマットを作る
  • XSLTを用いたさらなる応用への展望(GDLやDagazソースへの変換など)
  • 「Dagaz:Factorialは簡単です!」
  • ZRFを変換するためのより汎用的な独自DSL(プログラミング言語)を作る試み
  • 「ダガズ:常識へのキック(パート1)」
  • 汎用システムを作る上で遭遇した、様々なチェス系ゲーム類の特殊で厄介なルールの紹介
  • ZRFとその拡張構文での記述を比較
  • 「ダガズ:常識へのキック(パート2)」
  • 様々なチェス類の変わったルールの紹介
  • 「ダガズ:常識へのキック(パート3)」
  • 主にチェス類での「チェック」「チェックメイト」の概念について
  • ZRF拡張構文による記述例の紹介
  • 「ダガズ:常識へのキック(パート4)」
  • 様々なチェッカー系ゲームでの複合移動と駒取りについて
  • ZRFでの表現の難しさを論じる
  • 「ダガズ:常識へのキック(パート5)」
  • 三次元以上などの特殊な盤や、特殊な性質を持つ駒があるチェス類・チェッカー類の解説
  • 「ダガズ:常識へのキック(パート6)」
  • 駒と駒が相互作用したり、複数の駒が一体となって働いたりするゲームの解説
  • ZRFでの実装の難しさと拡張構文による記述例
  • 「ダガズ:常識へのキック(パート7)」
  • 相手の駒を自分のものにできるチェッカー類についての解説
  • ZRFでの実装例を論じる
  • 「ダガズ:常識へのキック(パート8)」
  • 変則的な(単純な2次元の長方形でない)盤のゲームや、そもそも盤という概念がないゲームの実装について
  • 「ダガズ:途中」
  • 内容がよく分からない
  • ZRFを独自DSL(プログラミング言語)で置換する上で考慮が必要な、種々の属性や構文について考察している?
  • 「ダガズ:表記の荒野で」
  • 駒の動きの統一的表記方法について
  • Betza Notationの紹介
  • より一般的な表記方法の提案
  • 「ダガズ:革命ではなく進化」
  • JoclyをリファクタリングしてDagazを作り始めた際の記録
  • ムーブジェネレータ(着手生成ロジック)の解説
  • ZRFスタックマシンコマンドの挙動の解説
  • MVCモデルの構造や設計プロセスについてのログあり
  • 「ダガズ:建築」
  • 前回の続き
  • ZrfBoard, ZrfDesignについての解説
  • 「Dagaz:単純なものから複雑なものへ」
  • Model部分の Zrf* クラスの役割や挙動の解説
  • Qunitを使ってモデルをどういう風にユニットテストするか
  • 「ダガズ:リハーサル」
  • スライディングパズルの実装について
  • ZRFでスライディングパズルを書くことの解説
    • JSコードのサンプルが入る
  • スライディングパズルのZRFをZ2JでJSに変換することの軽い解説
  • 「ダガズ:先を見据えて」
  • ゲームAIの実装についての解説
  • 種々のAIアルゴリズムについて触れている
  • 「ダガズ:ステップ」
  • Dagazでのチェッカー類の実装について
  • 色々なチェッカー類を例にその特性を解説している
  • 「Dagaz:より速く、より良く、よりスマートに..。」
  • 内容がよく分からない
  • 種々のトリッキーなゲームに対応したAIについて?
  • アポカリプス、天竺大将棋
  • 「ダガズ:才能を探しています」
  • Dagazの内部構造についての簡単な説明
  • 種々のゲームにおける各種AIの解説
  • 「ダガズ:大群」
  • 内容がよく分からない
  • 特殊な移動をするゲームのUI/実装について?
  • 「ダガズ:霧の中から」
  • 情報隠匿ゲームの実装とそれに対応したAIについて
  • 「ダガズ:詳細」
  • 新しく対応したゲームとそれに伴う実装の変更について?
  • 「ダガズ:エラー」
  • 新しいゲームを対応させるにあたって発覚したバグとその修正について?
  • 「ダガズ:エピソード(パート1)」
  • チェッカー類を実装する上で考慮すべき、実装を困難にする性質の解説
  • チェッカー以外のゲームについても触れている
  • 「ダガズ:孤独の終わり」
  • MindSports上にDagazを実装した際の記録
  • ネットワーク対戦への対応
  • 「ダガズ:エピソード(パート2)」
  • チェス類を実装する上で考慮すべき、実装を困難にする性質の解説
  • 「ダガズ:テクノロジーの総和」
  • 今回の主題:強いゲームAIを開発したい
  • Garbochess-JSををDagazに移植 : ソースは汚い、ロジックも未整理
    • 「私にとって最大の問題は、アルゴリズム自体が、位置評価やヒューリスティックなどの純粋なチェスの詳細から決して分離されていないことでした。この理由だけで、コードを完全に書き直す必要がありました。それは大変な作業でした(そしてそれはまだ進行中です)が、今日私が共有できるいくつかの成功がすでにあります」
    • 探索アルゴリズム部分とチェスのドメイン知識ベースの部分を切り離す(Dagazに移植した前者のソース, 後者のソース)
    • 現状のAIはリソース消費が激しい
    • 思考時間はクエリとして与えることが出来るようになっている(ex. ?ai=1000, 単位はミリ秒)
  • ゲームの例:プラットフォームチェス
  • Garbochess=チェックメイト、ステイルメイトになると処理を打ち切る -> フェアリーチェスに応用する場合はこれでは困る
    • ゲームの終了条件を設定し、それに達した場合は合法手生成を打ち切る
  • Garbochessの内部構造
    • 探索にはアルファベータ法を採用 -> 「この点に関して、1つの問題があります。これがすべて機能するためには、どのレベルの深さまで降下するかを事前に知っておく必要があります。移動の検索期間に制限があるため、この数を予測することはかなり問題があります」
    • 探索効率上昇のために反復深化法(Iterative Deepening)を併用
    • 同じ計算を繰り返さないために転置テーブル(Transposition Table)を併用、さらにZobristハッシュを使用
    • これら4つが有機的に結合して1つのソフトウェアとなっている -> 1つでも欠ければ残りは動作しない
  • 移植は出来たが、パフォーマンスに色々と問題がある?(この辺よく分からん)
    • オリジナルのGarbochessのノーマルなチェスの実装よりだいぶ遅くなっているらしい(?); それでも、とりあえず種々のフェアリールールに対応できるようにはなった
    • 以下、チェスの実装サンプルが2つ続く
  • 現在の実装の欠点
    • ある局面に対して指す手が常に固定されている
      • 「私はこれを少し実験しましたが、これまでのところ、ランダム化を試みるとゲームの品質が低下します。最も有望なのは、最初のレベルでの移動リストの予備的なランダムソートです。しかし、ここで成功について話すのは時期尚早です」
      • アルファベータ探索でノードを表示する順序の工夫、Killer Heuristic(この辺よく分からない)
    • Garbochessでやっている最適化が全然実装できてない
    • 評価関数とかもまだ対処出来てない
  • 「ダガズ:永続性のあるストーリー」
  • Dagaz開発はメトロイドヴァニア(ダンジョン攻略系ゲーム)に似ている
    • 問題を解決してアイテムをゲット(?) -> 他のアイテムと組み合わせる -> より重要・複雑な問題を解決するのに使える
  • ex1. common-setupモジュール
    • 単純なデバッグツールを目的としている
    • デバッグのため、特定のゲーム状態を一発で呼び出したい時がある -> 呼び出しには手間がかかる -> 自動化
        1. ゲーム状態をパラメータの列として記述できるようにする
        1. パラメータをURLにクエリとして付けてゲーム状態を再現できるようにする(ex. ?setup=0c3;0a2;0c2;0d2;1a1;4b1;5c1;1d1;-1a4;4b4;5c4;1d4;0a3;0d3;0b2;;&turn=0)
      • 「これは、common-setupが行うことです。モジュールは、すべての中間位置の説明をログに保存し、それらを再現できるようにします。これは完全なメカニズムではありません。」
      • 現在の機構にはいくつか欠点も残っている
  • ex2. 複数ラウンドからなるゲーム
    • プレイヤーが勝つ -> システムが現在のゲーム状態を調べる -> 条件を満たしていたら(=プレイヤーが勝っていたら)次のラウンドへ遷移
    • 以前のラウンドでの状態が後のラウンドに引き継がれるゲームの存在
    • マルチラウンドゲームの概念は例えばローグライクゲームなどにも役立つ(?)
      • 以前のラウンドでの状態によって後のラウンドの展開・結果が変化するゲームの存在
  • ex3. サウンド無効化機能
    • 最初の実装 = cookieを利用 (ページを更新する度に音を無効化するのは面倒なので設定を保存した)
    • 以下、JSコードのサンプルが続く
    • 「ブラウザウィンドウが閉じられるまでクッキーは短命でした。そして、私は「common-setupにcookieでも存続するように教えてみませんか」と思いました。max-ageパラメータを設定する必要がありましたが、それだけの価値がありました。まず、ウィンドウが誤って閉じられたときにゲームの状態が保存されるようになりました。ボーナスとして、AI / AIボットプレイモードを切り替えてもゲームはリセットされませんでした。それはすごかった!」
      • これだけでは解決できない問題を持つゲームもある(この辺の記述がよくわからんかった)
  • ここまで説明してきた状態保存方法が適していないゲームもある
    • ex. ナイン・メンズ・モリス
    • この場合、ゲームが正しく機能するためには、前の動きの履歴を保存する必要がある -> セッションマネージャを応用
      • セッションマネージャ=ゲームの履歴を保存し、プレーヤーが1つ以上の動きに戻って、場合によっては別の動きを行えるようにする
      • ボットでプレイするときに可能な動きをプレーヤーに教える機能にも応用する
    • サーバを使った対人通信対戦への対応 -> セッションマネージャの改良が必要に
      • サーバがゲーム状態の履歴を持っておく必要がある
      • 履歴の保存形式にはSmart Game Formatを採用(Dagazにもパーサを搭載、該当コード)
      • SGFはcookieではなくlocalstorageに保存することに
    • アプローチは2つ。1つはよくわからん、もう1つはセッション永続化(こっちの方が多くの場合ベター)
      • 全てのゲームをセッション永続化できるわけではない(ゲームの性質上不可能なものがある)
  • 「DagazServer:仕組み」
  • Dagazの概要/歴史
    • ZoG/ZRFの欠点(ex. 四則演算/整数値がない)
    • AxiomもZRFを完全にカバーしきれている訳ではない(ZoGのbot用APIを使ったハックのようなもの)
    • Windowsのみ対応、クローズドソース
    • ならその欠点をカバーしたものを作ってしまおう
  • Dagazの始動
    • Joclyの影響 -> Javascriptを採用してブラウザで動作するように
    • Jocly, Zanefisherを参考に
    • ZRFを特製ユーティティでコンパイル(トランスパイル?)する
      • ZRFを直接解釈するのは性能不足で出来なかった
      • 以下、ZRFからJSへの長大なコンパイル例が続く
    • ZoGより色々便利
      • ボード内の移動を算術加算として表現できる
      • ZRFで表現できないルールはDagaz側の拡張機能でカバー
      • JS拡張機能の例が続く
    • ZRFをコンパイルしたコードによって合法手が生成される -> 「複雑なチェックを実行したり、個々の手を禁止したり、追加のアクションでそれらを豊かにしたり、上述の繰延キャプチャの場合のように実行されるアクションの順序を変更したりすることができる接続された拡張機能に渡されます」
      • 「このハイブリッドアプローチは、基本的なZRFメタ言語を複雑にすることなく、システムの記述機能を大幅に拡張します」
    • 最近開発した、新しい描画モジュール
      • 以前は実現不可能だった機能を持つ
      • 「キャンバスを独立した領域に分割したり、ポップアップウィンドウを重ねて描画したり、画像をスクロールさせたり、図形の移動などのアニメーションをより柔軟に操作できるようになりました」
      • 「新しいビューのためのセットでは、コードの読みやすさの点で古いコントローラーとは異なる新しいコントローラを開発しなければなりませんでした」
      • 以下、新しいスタイルでのゲーム記述のサンプルが入る(コンパイル後)
    • 「モデル自体も変わってきます。スタックマシンのコマンドのこれらすべての長くて理解しがたい列は、すぐに過去のものになるかもしれません」
    • 「ゲームの説明文が読みやすくなります」以下、JSコードのサンプルが入る
    • 「さらに、このアプローチは、Z2J(ZRFからJavaScriptへの変換ユーティリティ)とZRF自体の両方を完全に放棄します。ゲームの説明は、JavaScriptですぐに手書きで書くことができます。これにより、以前よりもさらに速く、より複雑なゲームを開発できるようになります」

Valentinのメール

  • ZRFの記述をZ2JでJS/HTMLにトランスパイル
  • トランスパイルされたファイルを編集する(※たぶんこのフェーズで参照するAIやアルゴリズムの変更とかをするんだと思う)
  • こうして作られたゲームの記述はzrf-model.jsが合法手を生成するために使用される
  • 複雑なルール(e.g. チェッカーの「着手を完全に終わらせてから取った駒を取り除く」)はZRFだと表現が難しい
  • Z2J製のゲーム記述から生成された合法手に対して、特定の手を合法手から取り除いたり追加でアクションを実行したりする
  • このメカニズムをextensionと呼ぶ(関数名:CheckInvariants)
  • 例えばdeferred-captures.jsはextensionの一つ
  • 各着手(movement)は、原始的なアクション(action)の流れを含むものとして表現される:
    1. あるマス目から他のマス目へと移動する行為(move)
    2. 盤上から駒を除去する行為(capture)
    3. 盤上に駒を追加する行為(drop)
  • 着手(the move)は、複数のアクションからなる配列として表現される
  • 各アクションは4つの要素を持つ配列として表現される:
    • 1番目 [0] 着手(movement)の開始地点:moveとcaptureのアクションで利用される。dropの場合はnullになる
    • 2番目 [1] 着手の終了地点:moveとdropのアクションで利用される。captureの場合はnullになる
    • 3番目 [2] その着手において動く駒の種類:moveとdropのアクションで利用される。駒が成る場合の判定で使う
  • 上記3つのパラメータもまたそれぞれ配列として表現されるが、現在のバージョンではその先頭の要素のみ利用している
  • これは昔の設計が今でもまだ残っているせい
  • 4番目の要素は「partial movesにおいて、複合的な着手(composite moves)を構成する、実行されたアクションの組を示すインデックス」を表す
  • チェッカーで駒を取った時、その動きはmoveアクションとcaptureアクションの2つで表現される。
  • deferred-captures extensionは、captureアクションの4番目の要素を書き換えて、手番(turn)の最後にそれを動かす(※captureアクションを実行する順番を着手の一番最後に持っていくということ?)
  • 駒はthe compound grabsの最初で盤から取り除かれることをやめるので(?)、russian-captures.jsを使って追加のアクションを実行する
  • ここでは、単純に「以前の手番で既にcaptureされた駒をcaptureしない」ようにしている
  • extensionは複数を連鎖させて利用できる(extensions can be chained)
  • ゲームそれ自体は3つの部分からなるアーキテクチャとなっている:
    1. Model(zrf-model.js):合法手の生成、ゲームの状態管理など
    2. View(2d-view-v2.js):canvasにゲームを描画する
    3. Controller(app-v2.js):eventsを管理し全てのmodeを一本に統括する
  • Modelは、ゲームのルールを記述する「design部分」(ZrfDesign)と、ゲームの盤面状態を管理する「store部分」(ZrfBoard)を含んでいる
  • 盤面部分(The board ※おそらくZrfBoardのこと)
    • generateメソッドを用いて合法手のリストを生成することができる
    • applyメソッドを用いて着手を行って新しい盤面状態を生成することができる
  • デザイン(The design)の重要な部分は、盤面のトポロジー(=無数のpositionを繋ぐgraph)の記述
    • navigateメソッドを用いて、あるpositionから別のpositionに動かす(※何を?)
  • デザインは対局の間変化しない。盤面の状態も変化せず、着手を行うと新たな盤面が生成される

  • extensionsのコール
// dagaz.js
var Dagaz = {
  Model: {},
  View: {},
  AI: {},
  KPI: {},
  Controller: {}
};

// some exception
var CheckInvariants = Dagaz.Model.CheckInvariants;
Dagaz.Model.CheckInvariants = function(board) {
  var design = Dagaz.Model.design;
  /* ... */
  CheckInvariants(board);
}

// zrf-model.js
ZrfBoard.prototype.generateInternal = function(callback, cont, cover, serial) {
  /* ... */
  if (cont) {
    Dagaz.Model.CheckInvariants(this);
    Dagaz.Model.PostActions(this);
    /* ... */
  }
}

  • Z2Jの設計はあまりよくできていない

  • 生成されたファイルを手動で編集する必要がある

  • 可能ならZ2Jを使わない方向でに移行したい

  • XSLTでJS・HTMLに変換している

  • cf. https://github.com/GlukKazan/Dagaz/tree/master/utils/z2j/src/main/resources/xslt

  • Z2Jの設計は込み入っており、非常に手間なので自分は改修したくない

  • 興味が有るなら、以下の手順でZ2Jを動かせる:

    1. Java SEをインストール
    2. z2j.cmd内のJavaへのpathを修正するなり何なりして、実行するためのスクリプトを整える
    3. z2j.cmd example.zrf
  • うまく行ったら、変換されたファイルが生成されているはず

  • 同時に生成されるXMLは昔デバッグ用に使ってたやつがそのままになってる

  • Dagaz.KPIはパフォーマンス向上のために使っていたが、効果がなかった。今では使っていない(deprecated)

  • 今では代わりにstandard profiling toolsを使っている

  • ゲームの準備が行われる手順

  • ゲームの準備はDagaz.Model.BuildDesign() の中で行われ、盤面の準備と駒の準備という2つの部分に分けて行われる

  • 盤面は、「方向(direction)」addDirectionと「位置(position)」addPositionによって定義されるグラフである

  • 各位置では、各方向に対する位置を含んだ1次元配列内のオフセットを指定するベクトルが定義されている(?)

  • Zero valueが代入されていたら、それは接続が存在しないことを示す

  • こうすることで、盤上の移動が簡単な算術加算に単純化される

  • この操作は頻繁に行われるので高速でないといけない

ZrfDesign.prototype.navigate = function(player, pos, dir) {
    if (this.positions[pos][dir] != 0) {
        return + pos + this.positions[pos][dir];
    } else {
        return null;
    }
}
  • Z2Jの主な役割の一つは、盤面のグラフを構築すること
  • しかしこの方式からの移行を始めている
  • ZrfGridを用いることで簡単に盤面を記述できるようになっている(Z2Jは不要)
var g = design.addGrid();
g.addScale("A/B/C/D/E/F/G/H");
g.addScale("8/7/6/5/4/3/2/1");
g.addDirection("n",[ 0, -1]);
g.addDirection("nw",[-1, -1]);
g.addDirection("e",[ 1,  0]);
g.addDirection("ne",[ 1, -1]);
g.addDirection("w",[-1,  0]);
g.addDirection("sw",[-1,  1]);
g.addDirection("s",[ 0,  1]);
g.addDirection("se",[ 1,  1]);
design.addPlayer("White", [6, 7, 4, 5, 2, 3, 0, 1]);
design.addPlayer("Black", [6, 5, 2, 7, 4, 1, 0, 3]);
g.addPositions();
  • 描画準備の部分(Dagaz.View.configure())は以下のように記述できる:
var b = view.root.addRegion(70, 0, 540, 540);
b.addBoard("WhiteBoard", [0]);
b.addBoard("BlackBoard", [1]);
var g = b.addGrid(31, 31, 89, 89);
g.addScale("A/B/C/D/E/F/G/H", 60, 0);
g.addScale("8/7/6/5/4/3/2/1", 0, 60);
g.addTurns(0, [0]);
g.addTurns(1, [1]);
  • ここでは実際に、ターン0とターン1のフィールドの順番が逆になっている2つの異なるボードが記述されている

  • ただしゲームは未完成

  • https://github.com/GlukKazan/Dagaz/blob/master/src/debug/games/chess/dtc.js

  • Z2Jを使わないといけない他の理由は、形状(shape)の記述をするため。ここが一番厄介

  • 以下の断片は、カーネルスタックマシン(kernel stack machine)を利用して記述された駒の動きの定義:

design.addCommand(6, ZRF.FUNCTION, 24); // from
design.addCommand(6, ZRF.PARAM, 0); // $1
design.addCommand(6, ZRF.FUNCTION, 22); // navigate
design.addCommand(6, ZRF.FUNCTION, 3); // friend?
design.addCommand(6, ZRF.FUNCTION, 0); // not
design.addCommand(6, ZRF.FUNCTION, 20); // verify
design.addCommand(6, ZRF.FUNCTION, 25); // to
design.addCommand(6, ZRF.FUNCTION, 28); // end

design.addPiece("King", 5, 20000);
design.addMove(5, 6, [4], 0);
design.addMove(5, 6, [2], 0);
design.addMove(5, 6, [0], 0);
design.addMove(5, 6, [1], 0);
design.addMove(5, 6, [7], 0);
design.addMove(5, 6, [6], 0);
design.addMove(5, 6, [3], 0);
design.addMove(5, 6, [5], 0);
  • この現状をどうにかしたい、よりヒューマンリーダブルな書き方にしたい
var step = function(ctx, params) {
    if (ctx.go(params, 0) && !ctx.isFriend()) {
        ctx.end();
    }
};

design.addPiece("King", 5, 1000);
design.addMove(5, step, [4], 0);
design.addMove(5, step, [2], 0);
design.addMove(5, step, [0], 0);
design.addMove(5, step, [1], 0);
design.addMove(5, step, [7], 0);
design.addMove(5, step, [6], 0);
design.addMove(5, step, [3], 0);
design.addMove(5, step, [5], 0);

  • russian-checkers.jsで定義されているもの:
  1. design.checkVersion (options modifying the game)
  2. design.addDirection (directions on the board)
  3. design.addPlayer (players and direction conversion rules)
  4. design.addTurn (turn order - not used in this game, because it corresponds to theorder in which the players are defined)
  5. design.addPosition (positions on the board and offsets for directions between them)
  6. design.addZone (special areas on the board)
  7. design.addCommand (description of moves of pieces by commands of the stackmachine - this part is obsolete)
  8. design.addPriority (priority on the mode of moves - captures in checkers are priority)
  9. design.addPiece (pieces and their cost)
  10. design.addMove (possible movement of pieces)
  11. design.setup (initial arrangement of pieces)
  12. view.defBoard, view.defPiece (graphic resources used)
  13. view.defPosition (screen coordinates of positions)
  • モジュール類
  1. underscore (a library that I use often)
  2. dagaz.js (creates a global name Dagaz that is used to communicate betweenmodules)
  3. zrf-model (universal game model)
  4. zobrist.js (Zobrist hashing)
  5. common-setup-v2.js (saving and reproducing the arrangement of pieces)
  6. 2d-view-v2.js (universal view)
  7. move-list-v1.js (converts a sequence of clicks into composite moves)
  8. session-manager.js (undo and redo)
  9. sound-manager-v2.js (sound effects)
  10. random-ai.js, uct-ai-v4.js, forced-ai.js, sgf-parser.js, russian.js, sgf-ai-v2.js, russian-checkers-extension.js (AI)
  11. deferred-captures.js (pieces are removed from the board only at the end of the move)
  12. russian-captures.js (small bugfix)
  13. russian-checkers.js (game configuration)
  14. app-v2.js (universal controller)
  • Dagazにおけるmoveの表現(以下の要素から成る配列):
    • 0番目:配列(大抵は要素1つだけ)。着手の開始位置を表す。囲碁のようなdrop-moveの場合はnull
    • 1番目:配列(大抵は要素1つだけ)。着手の終了位置を表す。capture-moveの場合はnull
    • 2番目:成る駒の配列(nullになることはない)
    • 3番目:move execution phase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment