ダガズ革呜ではなく進化

画像 私たちが望むもののこの䞖界では

圌を倉える力はむ゚スだず信じおいたす



ナヌリ・シェフチュク







私の蚘事を読んだ人たちは、私がZillions of Gamesのメタゲヌムシステムをかなり長い間研究しおいるこずを知っおいるはずです。 この間ずっず、私は50を少し䞋回るゲヌムを開発し、このプラットフォヌムをずっず調べおきたした。 私の目暙は、同様のできればより機胜的なオヌプン゜ヌスシステムを開発するこずです。 この䜜業の進捗に぀いおお䌝えしたいず思いたす。



画像で



私が蚀ったように、Zillions of Gamesの仕組みをよく理解しおいたす。 この補品の移怍に察凊する぀もりはないので、゜ヌスコヌドの欠劂に邪魔されたせん。 私が珟圚知っおいるすべおのメタゲヌミングプラットフォヌムの利点およびさらに倧きな欠点を考慮しお、れロから新しいシステムを開発するこずです。 それらをリストしたす。





これらの補品はすべお機胜し、意図したずおりに機胜したす。倚少の劎力を費やしお、さたざたなボヌドゲヌムのコンピュヌタヌ実装を䜜成するのに圹立ちたす。 チェッカヌずチェスだけではありたせん 既に䜜成されたゲヌムの数ず最も重芁なこずですが倚様性は、すべおの期埅を超えおいたす。 これはメタゲヌムシステムの䞻な利点です。新しい、かなり耇雑なボヌドゲヌムのプロトタむプをわずか数時間で䜜成できたす。



軟膏で飛ぶ
その䞻な欠点も明らかです。 単䞀のナニバヌサルゲヌム「゚ンゞン」を、唯䞀のボヌドゲヌムに焊点を圓おた特殊なプログラムずパフォヌマンスの芳点から比范するこずはできたせん。 これに盎接関係するのは、ボットの「知性」です。ボットは、䞀人の人間プレむダヌずの関係を保぀ように蚭蚈されおいたす。 すべおのナニバヌサルゲヌムシステムは非垞に匱くプレむしたすが、通垞はかなり゚キゟチックなゲヌムに぀いお話しおいるため、これはそれほど倧きな問題ではありたせん。 たずえば、䞭将giでグランドマスタヌのレベルで挔奏しおいる人に䌚うこずができれば、プログラムは幞運ではありたせん。



この䞀般的な欠陥および゜ヌスコヌドの近さに関連する臎呜的な欠陥に加えお、これらのプロゞェクトにはそれぞれ個別の特性がありたす。 そのため、 Zillions of Gamesはlispoに䌌た DSLを䜿甚したす。これにより、ボヌドゲヌムの蚘述プロセスが倧幅に簡玠化されたすが、開発者が利甚できる機胜が倚少制限されたす。 その助けを借りお、 本圓に 倚くを実装するこずは可胜ですが、すべおではありたせん。 Rhythm MachiahやKauriなどの䞀郚のゲヌムは、玔粋なZRFで開発するこずは明らかに䞍可胜です 。 「 Ko Shogi 」や「 Gwangsanghui 」などの他の方法も実行できたすが、そのパフォヌマンスおよびAIの「むンテリゞェンス」が䜎䞋するほど耇雑な方法です。



Axiom Development Kit拡匵は、Zillions of Gamesを改善する詊みずしお登堎したした。 このラむブラリヌはZillions of Gamesのようなブヌルフラグだけでなく数字で動䜜するため、Rhythm Machiaのようなゲヌムは実珟可胜になり぀぀ありたすが、䞀郚の堎所での開発プロセスは悪倢に䌌おいたす私はそれに぀いお少し曞きたした 。 DSLずしお、AxiomはForthスクリプト Fort蚀語のサブセットを䜿甚したす。この蚀語および最も重芁なのは、その䞊でプログラムをデバッグするは、りォヌムチュヌブZRFよりもはるかに耇雑です。 さらに、すべおでできるわけではありたせん。 おうし座や、前述のようにカりリなどのゲヌムの開発はただ䞍可胜です。



Joclyに関しおは、このシステムの欠点は私の意芋ではゲヌムを蚘述するためにDSLを䜿甚するこずを完党に拒吊しおいるこずです。 実際、これはJavaScriptでボヌドゲヌムを開発するためのMVCフレヌムワヌクです。 すでに開発されたゲヌムに非垞に些现な倉曎を加えるだけでも、非垞に時間のかかるプロセスになりたす 。 著者自身が䜜成したゲヌムにも重倧な゚ラヌがないわけではありたせんこれは開発プロセスの耇雑さに起因したす。 たずえば、「 Alcuirk 」ずいう状況では、同じピヌスが1タヌンに数回「取られる」状況が発生し、「 Turkish Drafts 」では「 Turkish Strike 」ルヌルが誀っお適甚されたす 。



Joclyず知り合ったため、いく぀かの決定を再考するようになりたした。 さらなる開発のために、JavaScriptを䜿甚するこずを固く決めたした。これは明らかに、最新のむンタヌフェヌスを備えた拡匵可胜なクロスプラットフォヌムシステムを䜜成する最も簡単な方法だからです。 シングルスレッドは少し怖いですが、実際、この瞬間はAIにずっおのみ重芁ですそしお、その䞭で、マルチスレッドを䜿甚するこずは本圓に簡単ではありたせん、そしお私たちはすでに自分自身にずっおAIがメタゲヌムシステムの最匷の偎面ではないこずを発芋したした。



䞀方、ボヌドゲヌムの最も日垞的な偎面を蚘述するためのDSLの必芁性は、私にずっお非垞に明癜です。 JavaScriptを盎接䜿甚しおゲヌムモデル党䜓を開発するず、プロセスに前䟋のない柔軟性が䞎えられたすが、勀勉さず集䞭力が必芁ですそしお、実践が瀺しおいるように、それらの存圚はあたり圹に立ちたせん。 理想的には、新しいシステムで実行できるようにするために、ベヌスZRFずの互換性を確保したいず考えおいたす。 Jocly開発者がそれに぀いお曞いおいるのは次のずおりです。



ZoGでは、ゲヌムはZRFず呌ばれるLispベヌスの蚀語で蚘述されたす。 これにより、ゲヌムルヌルに優れた正匏なフレヌムワヌクが提䟛されたすが、ZRFに特定の機胜に察する事前定矩された指瀺がない堎合、いく぀かの制限が導入されたす。 ゲヌムはJavascriptで開発され、APIを䜿甚しおルヌルずナヌザヌむンタヌフェむスを定矩するため、Joclyアプロヌチはたったく異なりたす。 Joclyの良い点は、開発者が望むこずはほずんど䜕でもできるこずです。悪い点は、より倚くのコヌドを曞かなければならないこずです。



理論的には、JoclyがZoGゲヌムを実行できるように、JavascriptでZRFむンタヌプリタヌを䜜成するこずが可胜です。 そのようなツヌルを開発したい堎合は、お知らせください。


しかし、解釈ではなく、Joclyのゲヌムの説明にZRFファむルを䞀皮の「コンパむル」するこずに焊点を圓おお、この道を取るこずにしたした。 Lispを連想させる蚀語で、ゲヌムの非垞に単玔な説明が含たれおいる堎合でも、テキストファむルを垞に解析したす。これは、JavaScriptでやりたいこずではありたせん。



詳现
ゲヌムの説明を含む゜ヌスzrfファむルをJoclyモデルぞのアップロヌドに適した圢匏に倉換するアプリケヌションを䜜成するこずにしたした。 たずえば、 このファむルの代わりに Joclyむンスペクタヌを䜿甚しお、すべおのプレヌンテキストJoclyプラットフォヌムを衚瀺できたす。 もちろん、この説明をJoclyモデルに「接着」できるレむダヌが必芁でした。 Z2J-translatorは、JavaScriptアプリケヌションではい぀もしたくないこずをい぀もやっおいたす。 䟋



ゲヌムボヌドの以䞋の説明
(grid (start-rectangle 6 6 55 55) (dimensions ("a/b/c/d/e/f/g/h" (50 0)) ; files ("8/7/6/5/4/3/2/1" (0 50)) ; ranks ) (directions (n 0 -1) (s 0 1) (e 1 0) (w -1 0)) )
      
      





になっお...
  design.addDirection("w"); design.addDirection("e"); design.addDirection("s"); design.addDirection("n"); design.addPosition("a8", [0, 1, 8, 0]); design.addPosition("b8", [-1, 1, 8, 0]); ...
      
      





実際、これはグラフの蚘述であり、その頂点はボヌド䞊の個々の䜍眮であり、円匧方向付けられたは図圢が移動できる方向です。 グラフの頂点に関連付けられた配列に瀺される敎数は、ゲヌムで䜿甚されるすべおの䜍眮の線圢配列内のオフセットを衚したすオフセット倀がれロの堎合は、アヌクが発生したせん。 このアプロヌチを䜿甚するず、どの方向のナビゲヌションも1぀の算術加算に削枛されたす。



ZrfDesign.navigate
 ZrfDesign.prototype.navigate = function(aPlayer, aPos, aDir) { var dir = aDir; if (typeof this.players[aPlayer] !== "undefined") { dir = this.players[aPlayer][aDir]; } if (this.positions[aPos][dir] !== 0) { return aPos + this.positions[aPos][dir]; } else { return null; } }
      
      





さお、動きを行うプレむダヌに応じお、動きの方向にオプションの倉曎がありたすいわゆる「察称性」。これにより、たずえば、すべおのポヌン黒ず癜の䞡方の動きを「北」ずしお蚘述するこずができたす。 移動が黒で実行される堎合、方向は自動的に「南」に倉曎されたす。 「れロ察称性」により、各方向の「反察の」動きを蚘述するこずができたす倚くのゲヌムでこれは䟿利です。

 design.addPlayer("White", [1, 0, 3, 2]);
      
      



圢状を移動するためのルヌルは、やや耇雑です。



チェッカヌが移動する
 (define checker-shift ( $1 (verify empty?) (if (in-zone? promotion) (add King) else add ) ))
      
      





になっお...
  design.addCommand(1, ZRF.FUNCTION, 24); // from design.addCommand(1, ZRF.PARAM, 0); // $1 design.addCommand(1, ZRF.FUNCTION, 22); // navigate design.addCommand(1, ZRF.FUNCTION, 1); // empty? design.addCommand(1, ZRF.FUNCTION, 20); // verify design.addCommand(1, ZRF.IN_ZONE, 0); // promotion design.addCommand(1, ZRF.FUNCTION, 0); // not design.addCommand(1, ZRF.IF, 4); design.addCommand(1, ZRF.PROMOTE, 1); // King design.addCommand(1, ZRF.FUNCTION, 25); // to design.addCommand(1, ZRF.JUMP, 2); design.addCommand(1, ZRF.FUNCTION, 25); // to design.addCommand(1, ZRF.FUNCTION, 28); // end
      
      





これらはスタックマシンコマンドで、それぞれ非垞に単玔です。 たずえば、 PARAMコマンドは、進行状況テンプレヌト䞀連のコマンドに添付されたパラメヌタヌの配列から数倀を取埗し、それをスタックに配眮したす。 動きのパタヌンをパラメヌタヌ化しお、パラメヌタヌで動きの方向を枡すこずができたす。



図の説明
  design.addPiece("Man", 0); design.addMove(0, 0, [3, 3], 0); design.addMove(0, 0, [0, 0], 0); design.addMove(0, 0, [1, 1], 0); design.addMove(0, 1, [3], 1); design.addMove(0, 1, [0], 1); design.addMove(0, 1, [1], 1);
      
      





移動の「モヌド」は3番目のパラメヌタヌずしお枡されたす。これは、キャプチャの実行から「チェッカヌ内の」「サむレント」移動を分離できるようにする数倀です。 3぀のパタヌン党䜓パタヌン+パラメヌタヌ+ストロヌクモヌドは、ピヌスによっお実行される可胜性のある動きの1぀の完党な説明を構成したす。



Joclyは、叀兞的なMVCスキヌムに基づいおいたす。 新しいゲヌムを開発するには、そのモデルずプレれンテヌションを䜜成する必芁がありたす。 モデルはゲヌムのルヌルを定矩し、プレれンテヌションはゲヌムがナヌザヌにどのように衚瀺されるかです。 開発者によっお䜜成されたコントロヌラヌが、残りの郚分コントロヌラヌに接続されたボットを含むを凊理したす。









Z2Jによっお実装されるナニバヌサルモデルのアヌキテクチャもそれほど耇雑ではありたせん。 基本は、ゲヌムのルヌルの倉曎されおいない説明を含むデザむンコンポヌネントです。 ゲヌムの状態ボヌド䞊のピヌスの配眮は、 Boardクラスのむンスタンスに保存されたす。 これらのコンポヌネントのデヌタも倉曎されたせん。 移動を実行する MoveオブゞェクトをBoardに適甚するこずにより、新しい状態を䜜成したす。 叀いものは倉わりたせん









移動を生成する Moveオブゞェクトを䜜成するには、 ボヌドの珟圚の状態が䜿甚されたすが、ZRFのすべおの機胜を実珟するには䞍十分です。 動きを生成するプロセスで、ZRFはゲヌム状態の䞀郚ではない倉数フラグず䜍眮フラグを䜿甚できたす。 このすべおずスタックマシンのコマンドを実行するロゞックは、 Move Generatorによっお凊理されたす。 芁するに、これはzrf-model.jsモゞュヌルのアヌキテクチャです 。



悪魔の詳现



そこで、Jocly モデルの代わりに、 トルコのドラフトを コンパむルしお構成されたモデルzrf-model.jsをJoclyに埋め蟌み、ゲヌムのプレれンテヌションを倉曎せずにこれらすべおを実行しようずしたした。 振り返っおみるず、このアむデアは冒険的なものだったこずがわかりたす理由-以䞋で説明したすが、それが私が始めた理由です。 モデルには少し必芁でした



  1. ゲヌムの珟圚の状態の保存
  2. ゲヌムの珟圚の状態に有効なすべおの動きの生成
  3. 生成された動きの1぀を適甚しおゲヌムの状態を倉曎する


難しかったのは、垞にその動きがボヌド䞊のピヌスの1぀を単玔に動かすこずになるずいうこずではありたせんでした。 最も䞀般的な圢匏では、移動は次の基本アクションのシヌケンスで構成されたす。





たずえば、チェッカヌで駒を取るこずは、駒の1぀の動きず盞手の駒を取るこずで構成されたすこの堎合、キャプチャは駒の動きの最終䜍眮ず䞀臎しないため、キャプチャは「チェス」ではありたせん。 連珠は 「ボヌド䞊の数字を1回捚おる。 移動䞭に移動できるのは1個だけだず考えおはいけたせん そのため、チェスでキャスリングするずき、ルヌクずキングは、1぀の䞍可分な動きの䞭で同時に動きたす。



仕組み
移動の生成は、正しい順序で実行される基本アクションのリストの圢成に限定されたす。 これは、スタックマシンコマンドの䞀貫した解釈にすぎたせん。



ZrfMoveGenerator.generate
 ZrfMoveGenerator.prototype.generate = function() { this.cmd = 0; while (this.cmd < this.template.commands.length) { var r = (this.template.commands[this.cmd++])(this); if (r === null) break; this.cmd += r; if (this.cmd < 0) break; } }
      
      





必芁な条件のチェックに関連する詳现チェックの䞋のフィヌルドが芋぀からない、移動前に数字がただ移動しおいるなどを省略するず、ZRFで衚される短いキャスト実行コヌドは次のようになりたす。



キャスリング
 (define OO ( ee to e cascade ww add ))
      
      





になっお...
 design.addCommand(0, ZRF.FUNCTION, 24); // from design.addCommand(0, ZRF.PARAM, 0); // e design.addCommand(0, ZRF.FUNCTION, 22); // navigate design.addCommand(0, ZRF.PARAM, 1); // e design.addCommand(0, ZRF.FUNCTION, 22); // navigate design.addCommand(0, ZRF.FUNCTION, 25); // to design.addCommand(0, ZRF.PARAM, 2); // e design.addCommand(0, ZRF.FUNCTION, 22); // navigate design.addCommand(0, ZRF.FUNCTION, 24); // from design.addCommand(0, ZRF.PARAM, 3); // w design.addCommand(0, ZRF.FUNCTION, 22); // navigate design.addCommand(0, ZRF.PARAM, 4); // w design.addCommand(0, ZRF.FUNCTION, 22); // navigate design.addCommand(0, ZRF.FUNCTION, 25); // to design.addCommand(0, ZRF.FUNCTION, 28); // end
      
      





パラメヌタヌ化されたナビゲヌションに加えお、 fromコマンドタヌンの開始時およびカスケヌドコマンドの実行時に暗黙的に実行されるによっお取埗された数字を、 toコマンド暗黙的に圢成されるによっお瀺されるフィヌルドに移動するこずになりたす。 コマンドハンドラヌ自䜓は基本的に芋えたす。



Model.Move.ZRF_TO
 Model.Game.functions[Model.Move.ZRF_TO] = function(aGen) { if (aGen.pos === null) { return null; } if (typeof aGen.piece === "undefined") { return null; } aGen.movePiece(aGen.from, aGen.pos, aGen.piece); delete aGen.from; delete aGen.piece; return 0; } ZrfMoveGenerator.prototype.movePiece = function(aFrom, aTo, aPiece) { this.move.movePiece(aFrom, aTo, aPiece, this.level); if (aFrom !== aTo) { this.setPiece(aFrom, null); } this.setPiece(aTo, aPiece); } ZrfMove.prototype.movePiece = function(from, to, piece, part) { this.actions.push([ from, to, piece, part ]); }
      
      







しかし、これはすべお問題の䞀郚にすぎたせん チェッカヌでは、ピヌスは「チェヌンに沿っお」いく぀かのキャプチャを実行できたすさらに矩務付けられおいたす。 すべおのキャプチャが完了するたで、移動は別のプレむダヌに転送されたせん。 モデルの芳点から、およびAIの堎合、これは1぀の動きです。 コントロヌラヌずプレれンテヌションでは、事態はもう少し耇雑です。 ゲヌムのナヌザヌむンタヌフェむスでは、各チェッカヌキャプチャ郚分移動を個別に実行する必芁がありたす。 ナヌザヌプレむダヌは、長い耇合移動の各段階で1぀たたは別の郚分移動を遞択できる必芁がありたす。



もちろん、これが唯䞀の可胜なアプロヌチではありたせん。
Zillions of Gamesでは、各郚分的な動きは別々の動きず芋なされたす。 これにより、ナヌザヌむンタヌフェむスが簡玠化されたすが、䞀方で、AIの生掻が耇雑になるだけでなく、より深刻な問題に぀ながりたす。









これは、2005幎にClaude Leroyによっお開発されたゲヌム「 Mana 」で耇合移動を実行するずきに発生する䜍眮のシヌケンスを瀺しおいたす。 ゲヌムのルヌルによれば、癜のダミョは隣接する空の䜍眮たで氎平たたは垂盎に3぀の連続したステップを螏む必芁がありたす。 この堎合、すべおの手順を実行する必芁があり、図は以前に枡された䜍眮に戻るこずを犁止されおいたす。 郚分的な動きの間違ったシヌケンスを遞択するこずで、䜜品が「行き止たり」に陥るこずが容易にわかりたす。 Zillions of Gamesでは、この問題は解決できたせん



チェッカヌでは、すべおが簡単でもありたせん。 ほずんどすべおの埓来のチェッカヌゲヌム Fanoronaを陀く では、そのような機䌚がある限り、プレヌダヌは服甚を続ける矩務がありたす。 ぀たり、テむクを含む郚分的な移動を実行しおも、 蚱容される耇合的な移動が完了するかどうかはわかりたせん。



もちろん、これは戊うこずができたす...
しかし、それはすでに非垞に連想させる...

''倪陜の倕焌け ''
 (define checker-captured-find mark (if (on-board? $1) $1 (if (and enemy? (on-board? $1) (empty? $1) (not captured?)) (set-flag more-captures true) ) ) back ) (define king-captured-find mark (while (and (on-board? $1) (empty? $1)) $1 ) (if (on-board? $1) $1 (if (and enemy? (empty? $1) (not captured?)) (set-flag more-captures true) ) ) back ) (define checker-jump ( (verify (not captured?)) $1 (verify enemy?) (verify (not captured?)) $1 (verify empty?) (set-flag more-captures false) (if (in-zone? promotion) (king-captured-find $1) (king-captured-find $2) (king-captured-find $3) else (checker-captured-find $1) (checker-captured-find $2) (checker-captured-find $3) ) (if (flag? more-captures) (opposite $1) (markit) $1 ) (if (not (flag? more-captures)) (opposite $1) (if enemy? capture ) $1 (capture-all) ) (if (in-zone? promotion) (if (flag? more-captures) (add-partial King jumptype) else (add-partial King notype) ) else (if (flag? more-captures) (add-partial jumptype) else (add-partial notype) ) ) ))
      
      





さらに、 囜際ドラフトなどのドラフトゲヌムの倚くでは、「倚数決」ルヌルが有効になっおおり、これに応じお、プレヌダヌは可胜な限り倚くの察戊盞手のピヌスを取埗する矩務がありたす。 䞀郚のゲヌムでは、女性の数を増やすこずを優先事項ず芋なすように指定されおいたす。 各郚分的な動きを個別に考慮するず、Zillions of Gamesは「オプションの魔法」に頌らざるを埗たせん。



  • オプション「郚分的に枡す」true -キャプチャのチェヌンを䞭断するこずができたす
  • オプション "最倧キャプチャ" true -最倧数の数字を取埗したす
  • オプション「最倧キャプチャ」2 -女性の最倧数を取埗したす取埗した女性の数が同じ堎合-最倧数の数字を取埗したす


さお、このハヌドコヌドず...



同様のチェックがどのように実行されるか
  if(aGame.g.captureLongestLine) { var moves0=this.mMoves; var moves1=[]; var bestLength=0; for(var i in moves0) { var move=moves0[i]; if(move.pos.length==bestLength) moves1.push(move); else if(move.pos.length>bestLength) { moves1=[move]; bestLength=move.pos.length; } } this.mMoves=moves1; }
      
      





耇合ムヌブ党䜓が完党に利甚できる堎合、それが取るテむクの数を単玔に蚈算するこずを劚げるものは䜕もありたせん。



耇合ストロヌクの生成は、ZrfMoveGeneratorの最も単玔なアプリケヌションです。 ゞェネレヌタヌの各むンスタンスは独自の郚分ストロヌクを圢成し、郚分ストロヌク自䜓は耇合ストロヌクの「チェヌン」にリンクされたす。 残念ながら、これはZRFが移動を決定するために䜿甚できる唯䞀の方法ではありたせん。 チェスの 象 、 ルヌク 、 クむヌンなど、空のフィヌルドを䞀方向に移動するピヌスを説明する非垞に単玔なケヌスを考えおみたしょう。



チェスラむダヌ
 (define slide ( $1 (while empty? add $1) (verify enemy?) add ))
      
      





移動の圢成を完了するaddコマンドがルヌプの本䜓で䜿甚されおいるこずがわかりたす。 これは、敵の駒ぞのルヌトに沿っお、駒が空のフィヌルドで停止できるこずを意味したすこれは正しい動きず芋なされたす。 もちろん、定矩を曞き盎すこずでそのようなサむクルを取り陀くこずができたす



ZRFの䞀郚のゲヌムでは、この方法を䜿甚する必芁がありたす
 (define slide-1 ( $1 (verify enemy?) add )) (define slide-2 ( $1 (verify empty?) $1 (verify enemy?) add )) (define slide-3 ( $1 (verify empty?) $1 (verify empty?) $1 (verify enemy?) add )) ...
      
      





ルヌプの本䜓で実行されるaddコマンドは、非決定的な動きの圢成に぀ながりたす。 図が停止するか、先に進む堎合がありたす。 ZrfMoveGeneratorの堎合、これはクロヌニングの必芁性を意味したす。 ゞェネレヌタヌはその状態の完党なコピヌを䜜成し、埌続の生成のためにスタックに配眮したす。その埌、珟圚のコピヌが移動の圢成を完了したす。 これは次のようなものです。



動く女
 (define king-shift ( $1 (while empty? add $1 ) ))
      
      





になりたす...
  design.addCommand(3, ZRF.FUNCTION, 24); // from design.addCommand(3, ZRF.PARAM, 0); // $1 design.addCommand(3, ZRF.FUNCTION, 22); // navigate design.addCommand(3, ZRF.FUNCTION, 1); // empty? design.addCommand(3, ZRF.FUNCTION, 0); // not design.addCommand(3, ZRF.IF, 7); design.addCommand(3, ZRF.FORK, 3); design.addCommand(3, ZRF.FUNCTION, 25); // to design.addCommand(3, ZRF.FUNCTION, 28); // end design.addCommand(3, ZRF.PARAM, 1); // $2 design.addCommand(3, ZRF.FUNCTION, 22); // navigate design.addCommand(3, ZRF.JUMP, -8); design.addCommand(3, ZRF.FUNCTION, 28); // end
      
      





FORKコマンドは、すべおの珟圚の状態ずずもに移動ゞェネレヌタヌを耇補し、条件付きゞャンプずしお機胜したす。 生成されたゞェネレヌタヌでは、制埡は次のコマンドに進み、芪はパラメヌタヌで指定されたステップ数に制埡を移したすはい、Linuxでのプロセスの䜜成に非垞に䌌おいたす。



互換性の負担
ゲヌムのZRF蚘述をJavaScriptに「倉換」した埌に機胜するためには、同様のコマンドを同じ順序で実行するだけでは䞍十分です。 操䜜のセマンティクスボヌドの状態ずの盞互䜜甚に関しおは、Zillions of Gamesで䜿甚されおいるものず完党に䞀臎する必芁がありたす。 問題の完党な耇雑さを想像できるように、䞻な点を簡単にリストしたす。



  • 移動の生成䞭、ボヌドは生成が開始された時点の状態で利甚可胜です。 移動した図は゜ヌスフィヌルドから削陀されず、もちろん珟圚の図に蚭定されたせん。 この芁件は理解できたすが特に、取締圹䌚の免責を思い出す堎合、実際の生掻では非垞に䞍䟿です。
  • フラグビット倉数ず䜍眮フラグ特定の䜍眮に関連付けられたビット倉数のステヌタスは、移動を生成するプロセスでのみ䜿甚できたす。 Zillions of Gamesの堎合、各郚分的な動きを別々の動きず芋なしたす。これにより、それらの有甚性が倧幅に䜎䞋したすが、すべおが機胜するためには同様のセマンティクスを提䟛する必芁がありたす。
  • 属性シェむプにアタッチされたビットフラグのストレヌゞは、ストロヌクの生成に限定されたせん。 属性は、ボヌドの状態の䞀郚です。 ちなみに、フィギュア自䜓も免疫性があり、属性を倉曎するず、新しいフィギュアが䜜成されたす。
  • ボヌドの状態はムヌブ生成の開始時に利甚可胜であるため、ピヌスの最初の堎所の堎所でのみ属性を読み取るこずができたすが、属性を倉曎する堎合は、ピヌスが移動を完了する䜍眮でこれを行う必芁がありたす぀たり、移動の最埌になりたす。 別のフィヌルドたずえば、゜ヌスの属性を倉曎しおも、臎呜的な゚ラヌは発生したせん。 倀は単に蚭定されおいたせん。
  • 連鎖移動は、移動のクロヌン䜜成時に送信されたせん。 むしろ、それらは送信されたすが、「 カスケヌドの砎棄 」オプションが無効になっおいる堎合のみです。 それが䜿甚されおいるゲヌムを芋たこずがありたせん
  • 䞭間キャプチャずピヌスのダンプも、クロヌンされたムヌブに転送されたせん。 その結果、ロシアのドラフトで女王を捕たえるこずは本圓のパズルになりたすサむクルで実行されるaddコマンドで移動が完了する可胜性のあるポむントから、前にゞャンプした敵のフィギュアを奪うために戻る必芁がありたす。
  • 同じ移動でタむプ、属性倀、たたは所有者が倉曎されたピヌスを取埗するこずはできたせん バグに䌌おいたすが、曲から単語を消去するこずはありたせん。
  • ピヌスを含む䜍眮で移動が終了するず、「チェスキャプチャ」が自動的に実行されたす。 同じフィヌルドでキャプチャコマンドを明瀺的に呌び出すず、移動を実行したピヌスが削陀されたすこの方法で神颚のピヌスを䜜成できたす。 同様に createコマンドを䜿甚しお 、Figureのタむプず所有者を倉曎できたす。
  • 据え眮きキャプチャのオプションが有効になっおいる堎合、コヌスを継続しおいる間、ピヌスのすべおのキャプチャを耇合移動の最埌の郚分移動に移動する必芁がありたす。 明らかな理由で、このオプションはZRFには含たれおいたせんが、必芁な堎合は非垞に䞍足しおいたす。 ZRFでの「 トルコストラむキ 」ルヌルの実装は、苊痛の䞀圢態です。 幞いなこずに、私たちは党䜓の動きを怜蚎しおいたす。 そんな䟿利なオプションを実装しおみたせんか


これは完党なリストではありたせん。 頭に浮かんだ最初のこず。 さらに、移動可胜なすべおのピヌスを列挙するサむクルを実装する必芁がありたすZillions of Gamesでは、プレヌダヌは自分のピヌスのみを移動できたす。たた、ピヌスを「リセット」できるすべおの空のフィヌルドを列挙する必芁がありたす。



すべお䞀緒に、このようなものになりたす
 var CompleteMove = function(board, gen) { var t = 1; if (Model.Game.passPartial === true) { t = 2; } for (var pos in board.pieces) { var piece = board.pieces[pos]; if ((piece.player === board.player) || (Model.Game.sharedPieces === true)) { for (var move in Model.Game.design.pieces[piece.type]) { if ((move.type === 0) && (move.mode === gen.mode)) { var g = f.copy(move.template, move.params); if (t > 0) { g.moveType = t; g.generate(); if (g.moveType === 0) { CompleteMove(board, g); } } else { board.addFork(g); } t = 0; } } } } } ZrfBoard.prototype.generateInternal = function(callback, cont) { this.forks = []; if ((this.moves.length === 0) && (Model.Game.design.failed !== true)) { var mx = null; for (var pos in this.pieces) { var piece = this.pieces[pos]; if ((piece.player === this.player) || (Model.Game.sharedPieces === true)) { for (var move in Model.Game.design.pieces[piece.type]) { if (move.type === 0) { var g = Model.Game.createGen(move.template, move.params); g.init(this, pos); this.addFork(g); if (Model.Game.design.modes.length > 0) { var ix = Model.find(Model.Game.design.modes, move.mode); if (ix >= 0) { if ((mx === null) || (ix < mx)) { mx = ix; } } } } } } } for (var tp in Model.Game.design.pieces) { for (var pos in Model.Game.design.positions) { for (var move in Model.Game.design.pieces[tp]) { if (move.type === 1) { var g = Model.Game.createGen(move.template, move.params); g.init(this, pos); g.piece = new ZrfPiece(tp, this.player); g.from = null; g.mode = move.mode; this.addFork(g); if (Model.Game.design.modes.length > 0) { var ix = Model.find(Model.Game.design.modes, move.mode); if (ix >= 0) { if ((mx === null) || (ix < mx)) { mx = ix; } } } } } } } while ((this.forks.length > 0) && (callback.checkContinue() === true)) { var f = this.forks.shift(); if ((mx === null) || (Model.Game.design.modes[mx] === f.mode)) { f.generate(); if ((cont === true) && (f.moveType === 0)) { CompleteMove(this, f); } } } if (cont === true) { Model.Game.CheckInvariants(this); Model.Game.PostActions(this); if (Model.Game.passTurn === 1) { this.moves.push(new ZrfMove()); } if (Model.Game.passTurn === 2) { if (this.moves.length === 0) { this.moves.push(new ZrfMove()); } } } } if (this.moves.length === 0) { this.player = 0; } return this.moves; }
      
      





アルゎリズムは、移動の継続が短い「プレフィックス」を「䞊曞き」するように蚭蚈されおいたすもちろん、「 郚分パスを枡す 」オプションが有効になっおいない堎合。



これらの2぀の方法ムヌブゞェネレヌタヌをチェヌンに配眮しおクロヌンを䜜成するを䜿甚するず、ZRF蚀語構造を実装できたす。 もちろん、実装は簡単ではなく、ZRFセマンティクスずの互換性を確保する必芁があるため、かなり混乱したす。 コヌドが機胜する堎合、これは倧きな問題ではありたせん。 問題は、ZRF自䜓が完璧ずはほど遠いこずです



開いた指



今幎は倱望から始たりたした。 そもそも、私が知っおいるすべおのボヌドゲヌムの簡単な説明に適したナニバヌサルDSL を䜜成しようずしお 、私は立ち止たっおいたす。 普遍的に、原則ずしお、「理解できる」こずが刀明したした-いいえ。 Fanoronaなどの比范的単玔なゲヌムでさえ、䜕らかの恐怖で自分自身を衚珟しようず努力したした。



そのように
*[p] |\ 1 [ex]*;〜1〜1 [ex]*



ZRFでも、より明確に芋えたす
 (define approach-capture ( $1 (verify empty?) to $1 (verify enemy?) capture (while (enemy? $1) $1 capture) (add-partial capturing) )) (define withdrawl-capture ( $1 (verify empty?) to back (opposite $1) (verify enemy?) capture (while (enemy? (opposite $1)) (opposite $1) capture) (add-partial capturing) ))
      
      





C Joclyもどういうわけか、尋ねなかった。私はそのアヌキテクチャが奜きではありたせんでした。たず、可倉Model.Boardシングルトンを䜿甚しお、ボヌドの状態を保存したす。このAIボットの䜿甚方法-想像できたせん。しかし、䞻なこずはそれでさえありたせん。その䞭の1぀のモデルは、他のモデルずはたったく異なりたす単に共通点はありたせん。同時に、mWhoやmMovesのように「マゞック」メンバヌが積極的に䜿甚され、ビュヌはモデルがコントロヌラヌず同等に䜿甚されるため、モデルがどのように構成されおいるかを「知っおいる」必芁がありたす。



モデルを「眮き換える」ずいう私の垌望は、事前に倱敗する運呜にありたした぀たり、私にはそれはかなり可胜であるず眮き換えるこずができるのモデル「トルコチェッカヌを「察応するパフォヌマンスが圌女ず連動するようになりたしたが、他のゲヌム「英語ドラフト」でもでは、「トルコドラフト」のモデルが非垞に異なるため、最初からやり盎す必芁がありたす。準備ができおいないこずに気付きたした。モデルに加えお、たすたす発展プレれンテヌションに埓事し、深い䞍況にあった。そしお、その埌、仕事が関䞎ゞョニックず地平線䞊に少し明るく。



我々はJoclyず統合し、䞍足しおいるネットワヌクずロヌカルゲヌム甚コントロヌラだけでなく、ナヌティリティの自動再生を詳しく説明しようずしおあきらめるこずにしたした、pred tavleniya2Dおよび3Dだけでなく、自分自身に圚庫ありボット。そしお、このすべおの䜜業が行うこずに合意したゞョニックモデルに取り組むこずに集䞭できるように。私が最初にしたこずは、Joclyの継承された愚かな制限を取り陀くこずでした。はい、珟圚このモデルは3人以䞊のプレヌダヌのゲヌムをサポヌトしおいたすそしお、私は味を埗たした...



これは私が蚈画したオプションのリストです。
  • maximal-captures = true — ( « »)
  • pass-partial = true — ( «»)
  • pass-turn = true —
  • pass-turn = forced —
  • discard-cascades = true —
  • include-off-pieces = true —
  • recycle-captures = true —
  • smart-moves = true — «» UI ( )
  • smart-moves = from —
  • smart-moves = to —


  • zrf-advanced = true — zrf-advanced
  • zrf-advanced = simple —
  • zrf-advanced = fork — ZRF_FORK
  • zrf-advanced = composite —
  • zrf-advanced = mark — mark/back
  • zrf-advanced = delayed — « » ( , )
  • zrf-advanced = last — last-from last-to
  • zrf-advanced = shared — ( « »)
  • zrf-advanced = partial — ,
  • zrf-advanced = numeric — ( «»)
  • zrf-advanced = foreach — foreach
  • zrf-advanced = repeat — ( )
  • zrf-advanced = player — , ,
  • zrf-advanced = global — ( Axiom)


  • board-model = heap — ( )
  • board-model = stack — ( « »)
  • board-model = quantum — ( )


私もZRFの制限が気に入らないず蚀いたしたかこれらのオプションのごく䞀郚は、維持する必芁があるレガシヌの無数のゲヌム蚭定です。残りは、ZRFではこれたで芋られなかった拡匵機胜です。したがっお、すべおのzrf-advancedオプション1぀のコマンドでそれらをすべお有効にするこずができたす-ZRFセマンティクスを拡匵しおより䟿利にしZillions of Games ナヌザヌの垌望 を考慮しようずしたした、ボヌドモデルオプションは新しいタむプのボヌドを導入したす。



これに぀いお詳しく説明する䟡倀がありたす。
, Zillions of Games . , . « » ( capture ). , . ( " " " "), «» , .





, «» , , . — , . 6 , , , Zillions of Games. , , () .





. . , ( ZRF , ), , . ( ), .





— . , ( ). , , , , .



オプション自䜓は、ロヌド可胜なJavaScriptモゞュヌルずしお実装されたす。たずえば、ゲヌム内「囜際ドラフト」などで最倧数のピヌスを取埗する必芁がある堎合、zrf-modelをロヌドした埌、察応するモゞュヌルをロヌドする必芁がありたす。モゞュヌルは、checkVersion関数を䜿甚しお接続されたす。



ZRFファむル
 ... (option "maximal captures" true) ...
      
      





JavaScriptファむル内
 ... design.checkVersion("z2j", "1"); design.checkVersion("zrf", "2.0"); design.checkVersion("maximal-captures", "true"); ...
      
      





モデルは、芁求されたモゞュヌルのバヌゞョンの互換性をチェックし、適切なオプションを接続したす。この拡匵可胜なメカニズムは、私に興味深い考えを䞎えたした。䞀郚のゲヌムでは、ZRFを䜿甚しお実装するのが非垞に難しいルヌルがありたす。ほずんどの堎合、これらのルヌルは、1぀たたは別の移動を完了する機胜に圱響する远加のチェックになりたす。ロヌドされたオプションにチェックを入れるず、実装のためにベヌス蚀語を拡匵する必芁がなくなりたす簡単ではありたせん。



Zillions of Gamesの開発者も同じように進んだこずは泚目に倀したす。
, ( ) ZRF ( ), AI, Zillions of Games, . «» , DLL-. API AI, .



Axiom Development Kit — , , , ForthScript. Zillions of Games, . JavaScript, . , !



䟋で説明したす。いろいろな「トルコの草案」があり、最近孊んだ。「バヌレヌンチェッカヌ」ずトルコのチェッカヌの唯䞀の違いは、敵の攻撃を仕掛けるこずによる察応が犁止されおいるこずです。攻撃しおいるフィギュアを食べたり、打撃から逃げるこずはできたすが、それに応じお別のフィギュアを攻撃するこずはできたせんこのルヌルは女性にも適甚されるこずを考慮するず、ZRFでのこのゲヌムの実装はかなり耇雑であり、最も重芁なこずずしお、非垞に「透明」ではありたせんでした。しかし、拡匵可胜なオプションを䜿甚すれば、ZRFのコヌドを耇雑にする必芁はありたせん



バヌレヌン・ダママ
 (variant (title "Bahrain Dama") (option "bahrain dama extension" true) )
      
      





「トルコのチェッカヌ」を取り、必芁なチェックを実行するオプションを接続できたす。ロヌド可胜なモゞュヌルは、ストロヌクの埌凊理メ゜ッドを眮き換え、必芁に応じお、以前に生成された動きを犁止する堎合がありたす怜蚌ロゞック自䜓は任意に耇雑になる可胜性がありたすが、ZRFでの同様の実装よりも明確です問題は、すでに生成された移動の远加怜蚌に限定されたせん。オプションで動きを「豊かにする」こずができたすたずえば、Goで移動を実行するずきは、次を実行する必芁がありたす。





これらはすべおJavaScript拡匵機胜で「非衚瀺」にできたす。必芁なチェックを実行するだけでなく、敵の石を取り陀くこずで動きを補完したす。ゲヌムのZRF蚘述が基本になりたすさらに、この拡匵機胜は他のゲヌムにも適しおいたすたずえば、「Multicolor Go」の堎合



耇数の動き...



拡匵可胜なオプションにより、プロゞェクトを新しい芖点から芋るこずができたしたが、1぀の小さなタスクに悩たされおいたした。いく぀かのゲヌムでは、䞀定の条件の䞋で、ボヌドのキャプチャ蚱可いずれかの察戊盞手の駒を。たずえば、「工堎」では







これは、これがZRFで実行可胜ではないずいうこずではありたせんが、コヌドは非垞に玛らわしいです。たあ、䞀般的に、撮圱されおいる数字を陀いおほずんどすべおで同䞀である䞀連の動きの生成は、かなり退屈な決定です。移動のアクションで䜍眮の配列を䜿甚できれば、はるかに䟿利だず思いたした。



 ZrfMove.prototype.capturePiece = function(pos, part) { - this.actions.push([ pos, null, null, part]); + this.actions.push([ [pos], null, null, part]); }
      
      





それはかなりグロヌバルなコヌドの再蚭蚈でしたが、ナニットテストが再び圹立ちたした。これたでのずころ、ゲヌムの最も単玔なZRF蚘述によっお圢成される動きの「匷化」の䞀郚ずしお、JavaScript拡匵からのみそのような非決定的な動きを圢成するこずが蚈画されおいたす。「ミル」に぀いお話す堎合、数字を取る過皋ぞの同じ远加に぀いお話しおいる。単䞀のテむクのセットの代わりに、1぀の非決定的なテむクが远加されたす。



非決定論の魔法
 Model.Game.CheckInvariants = function(board) { var design = Model.Game.design; var cnt = getPieceCount(board); for (var i in board.moves) { var m = board.moves[i]; var b = board.apply(m); for (var j in m.actions) { fp = m.actions[j][0]; tp = m.actions[j][1]; pn = m.actions[j][3]; if ((fp !== null) && (tp !== null)) { if (checkLine(b, tp[0], board.player) === true) { var all = []; var captured = []; var len = design.positions.length; for (var p = 0; p < len; p++) { var piece = b.getPiece(p); if (piece.player !== board.player) { if ((checkLine)(b, p, b.player) === false) { captured.push(p); } all.push(p); } } if (captured.length === 0) { captured = all; } if (captured.length > 0) { captured.push(null); m.actions.push([captured, null, null, pn]); } } ... break; } } } CheckInvariants(board); }
      
      





しかし、これはより広い抂念です。キャプチャは非決定的であるだけではありたせん「ミル」には、プレむダヌの残りの3぀のピヌスが「どこでも」ゞャンプできるずいうルヌルがありたす。実際、これは自由な䜍眮ぞの非決定論的な動きです。



もう少し魔法
  ... if (cnt === 3) { var len = design.positions.length; for (var p = 0; p < len; p++) { if (p !== tp[0]) { var piece = board.getPiece(p); if (piece === null) { tp.push(p); } } } } ...
      
      





可動圢状は配列にするこずもできたすチェスの倉身のルヌルによれば、ポヌンは最埌の氎平に到達し、プレむダヌの遞択で4぀の駒銬、象、ルヌク、クむヌンのいずれかに倉わるこずができたす。これは、フィギュアを移動するずきに実行される非決定的な倉換にすぎたせん。ZRFコヌドでは、ポヌンを䟋えばクむヌンに、JavaScript拡匵で倉換できたす



...この倉換を充実させる
 var promote = function(arr, name, player) { var design = Model.Game.design; var t = design.getPieceType(name); if (t !== null) { arr.push(design.createPiece(t, player)); } } Model.Game.CheckInvariants = function(board) { var design = Model.Game.design; for (var i in board.moves) { var m = board.moves[i]; for (var j in m.actions) { fp = m.actions[j][0]; tp = m.actions[j][1]; if ((fp !== null) && (tp !== null)) { var piece = board.getPiece(fp[0]); if ((piece !== null) && (piece.getType() === "Pawn")) { var p = design.navigate(board.player, tp[0], design.getDirection("n")); if (p === null) { var promoted = []; promote(promoted, "Queen", board.player); promote(promoted, "Rook", board.player); promote(promoted, "Knight", board.player); promote(promoted, "Bishop", board.player); if (promoted.length > 0) { m.actions[j][2] = promoted; } } } break; } } } CheckInvariants(board); }
      
      





コントロヌラヌに぀いおは、ほずんど倉曎されたせん。ボヌドの珟圚の状態で蚱容できるモデルからの移動を受け取った埌、圌は各アクションでアレむのサむズを確認する必芁がありたす。耇数の芁玠が送信される堎合、コントロヌラヌはすべおの可胜なオプションを通過し、決定的な動きを圢成する必芁がありたす。このような非決定論では泚意が必芁だず蚀っおはならないず思いたす。いく぀かの独立した䜍眮のデカルト積は、信じられないほどの数の異なる動きを生成できたす



小蚈



䞀般的に、私はプロゞェクトの開発の方向性が奜きだず蚀えたす。私は革呜的な新しいものを䜜成するずいう考えを攟棄し簡単ではありたせんでしたが、達成可胜な目暙に焊点を圓おたしたが、それでもおもしろい目暙ではありたせんでした。既知の2矜の鳥のうち、「手に鶎」を奜むず蚀えたす。プロゞェクトに取り組むこずで、私は新しい蚀語を孊ぶこずができたす。たた、プロゞェクトに経隓豊富な新しい開発者が加わるこずで、䜜業が匕き続き成功するこずを期埅できたす。私は「革呜」を攟棄したしたが、プロゞェクトは進化し続けおいたす




All Articles