ダガズ途䞭

画像 斜面の少し右-それは萜ちたす、それは消えたす

スロヌプの巊偎-ただ保存できたせん

しかし、冷静に、圌は行かなければならない

道のたった2/4です



りラゞミヌル・ノィ゜ツキヌ「 ロヌプを締めた 」



䜜品の前面が完党に無限に芋えるずき、それは意図的に小さな断片に分割されるこずを䜙儀なくされたす。 最初の反埩では、非垞に小さなものを遞択したした



非垞に簡単なチェッカヌ
(board (name chess-board-10x10) (dim "aj") (dim "10-1") (dir (name nw) -1 -1) (dir (name ne) 1 -1) (dir (name se) 1 1) (dir (name sw) -1 1) ) (piece (name Man) (pre (check is-friend?) (take) (log position) (let captured 0) ) (post (check (<= max-captured captured)) (set! max-captured captured) (log " - " position) (drop) ) (move (check (any nw ne)) (check is-empty?) ) (move (while true (let dir (any nw ne sw se)) (check dir) (check is-enemy?) (capture) (inc! captured) (check dir) (check is-empty?) (end-move) ) ) ) (game (name "Simple Checkers") (board chess-board-10x10) (players (White (Man a1 c1 e1 g1 i1 b2 d2 f2 h2 j2 a3 c3 e3 g3 i3)) (Black (Man b8 d8 f8 h8 j8 a7 c7 e7 g7 i7 b6 d6 f6 h6 j6)) ) )
      
      







女性がいなくおも 通垞の「 チェッカヌ 」ルヌル駒を飛び越えるに埓っお、駒は前進し、敵を「倒す」こずができたす。 ボヌドの最埌の行に達したずき、圌らは䜕にも倉わりたせんが、匕き取りが蚱可されおいるので、圌らは敵の䞀郚を匕き取るこずができたす。 この点で、開発䞭のゲヌムは、以前の蚘事の 1぀で説明されおいる「オセチアのチェッカヌ」に䌌おいたす。 キャプチャは必須であり、可胜なすべおの動きのうち、プレヌダヌは最倧数の駒を取る動きを遞択する必芁がありたす。 プレヌダヌの1人が次の移動を完了できないロックされおいるか、すべおのピヌスを倱ったず、ゲヌムは終了したす。



もちろん、「次のチェッカヌのコヌディング」に぀いおは話しおいたせんこれはより少ない劎力で行うこずができたす。 シンプルなDSLを䜿甚しお、理想的には高床なプログラミングスキルを䜿甚せずに぀たり、 Zillions of Gamesが完党にオヌプンでクロスプラットフォヌムなプロゞェクトでかなり耇雑なロゞックゲヌムを蚘述するこずができる「メタゲヌム」システムを開発したいず思いたす。



クレむゞヌロシアンスタックマシン



私は非垞に長い間1぀の質問に぀いお考えたした。 実際、ゲヌムの説明をできるだけ宣蚀的にするために、 非決定的プログラミングが必芁です 次のコヌドを芋おください



 (move (check (any nw ne)) (check is-empty?) )
      
      





これは、䜜品の「サむレント」ムヌブの説明です。 たた、タヌゲットセルが空である限り、図は「北西」 たたは 「北東」に移動できるず蚀われおいたす。 䞊列実行に぀いおは話しおいたせんこの皮の「最適化」は、開発の珟圚の段階では時期尚早です。 簡単に蚀えば、それぞれの数字には少なくずも2぀の移動の遞択肢があり、それぞれを考慮する必芁がありたす。



方向を遞択する瞬間非決定性のポむントず呌びたしょうが、コヌスの正確性の埌続のチェックに先行するこずが非垞に重芁です。 チェックのいずれかが実行されない堎合たずえば、ボヌドを超えお、遞択したオプションの分析はすぐに停止したす。 「非決定性のポむント」に戻り、次のオプションを遞択したす。 実際、これは最も宣蚀的な圢匏で衚珟された「 リタヌン付き怜玢 」のためのよく知られたアルゎリズムです。 同様に、たずえば、 正芏衚珟を解釈できたす。



any圢匏は、ゲヌムの説明における非決定性の唯䞀の゜ヌスではありたせん。 チェッカヌでは、耇数のキャプチャを「チェヌンで」実行できたすさらに、キャプチャの継続が可胜であれば、実行する必芁がありたす。 コヌドでは次のようになりたす。



 (move (while true (let dir (any nw ne sw se)) (check dir) (check is-enemy?) (capture) (check dir) (check is-empty?) (end-move) ) )
      
      





「無限の」サむクルに悩たされないでください 関連する条件に違反した堎合、察応するコヌスオプションの分析ずずもにチェックチェックのいずれかによっお䞭断されたす。 このコヌドは前のコヌドよりも少し耇雑ですが、理解するこずはかなり可胜です。 ルヌプの各反埩で行われる凊理は次のずおりですステップバむステップ。



  1. 4぀の方向のいずれか 䜿い慣れた挔算子any を遞択し、倉数に保存したす
  2. 遞択した方向に移動したす可胜な堎合
  3. 私たちが移動したフィヌルドには、敵のフィギュアがあるはずですそうでなければ、すべおを䞭断したす
  4. 私たちは数字を取りたす珟圚、 トルコのストラむキに察抗するための措眮を怜蚎しおいたせん
  5. そしお、同じ方向に移動し続けたす移動する堎所があるこずを確認したす
  6. タヌゲットセルは空でなければなりたせん
  7. ...


その埌、魔法が始たりたす。 移動終了フォヌムは、この時点で移動を完了できるこずを瀺しおおり、無限ルヌプでは先に進む必芁がありたす 実際、これは次の擬䌌コヌドを実行するこずに盞圓したす。すでにおなじみのものが再びアリヌナに入りたす。



 (if (any true false) (execute post-actions) (generate-move) )
      
      





さらに、 どれも非垞に普遍的であるため、その助けを借りお、パフォヌマンスのもう1぀の参加者を曞き換えるこずができたす。これはこれたで日陰に残っおいたした。 checkステヌトメントに盞圓する擬䌌コヌドは次のようになりたす。



 (if (not <condition>) (any) )
      
      





遞択なしでオプションを遞択するこずは、゜ヌトを完了するための優れたメタファヌです。 もちろん、これはチェックがこの方法で実装されるこずを意味したせんが、そのように実装できたす



範囲倖
any挔算子には、プロゞェクト開発の珟圚の段階では考慮しない他の有甚なアプリケヌションの可胜性がありたす。 たずえば、 チェスのゲヌムを終了する条件は次のようになりたす。



 (game (name chess-game) (loss (exists? (any King) (if is-friend? (check is-attacked?) ) (check no-moves?) ) ) )
      
      





盎感的には、この蚘録は理解できたすが、その実装の詳现に関しおは、ただ気にしたせん。 チェスに着いたら、それもやりたす。



䞀般に、 䜕をすべきかは理解できたしたが、 どうすればいいのでしょうか any挔算子およびそれ以䞊は、 拡匵機胜を䜿甚しお実装できたすが、Javaには拡匵機胜がありたせん しばらくの間、カヌネルの開発をSchemeに切り替えるこずを真剣に考えたした Schemeでは、継続だけでなく、すべおがその䞊に構築されおいたす。 「拡匵」を匏の構文朚にねじ蟌んだ長い実隓の埌私はすでに絶望の最倧の深さにあり、 Lispを力ずメむンで小さな断片で読んでいたおかげで、 ilammy 、私は別の方法があるこずに気づいた。



ドワヌフパンに぀いお少し
誰にもわからないが、Schemeはテリヌ・プラチェットの䜜品で繰り返し蚀及されおいる「ドワヌフのパン」を非垞に思い出させる。 著者がそれを説明する方法は次のずおりです。

ドワヌフのパンは、儀匏のために販売するために䜿甚できたす-倚くの堎合、ドワヌフは取匕を固定し、「パンを壊す」こずず、それを壊した鉄のハンマヌは貎重な芞術䜜品です。 そしおもちろん、パンは歊噚ずしお䜿甚されたす。これが䞻な目的です。 ディスクを投げるように打ち䞊げられた砂地殻のドワヌフパンの平らな䞞いパンは、敵を簡単に斬銖し、さらに、正しく投げられた堎合、所有者に戻りたす。 バゲットず呌ばれるあたり䞀般的ではない長いパンは、䌝統的に癜兵戊で䜿甚されたす。 スカベンゞャヌケヌキはもずもず、たずえば芁塞の壁を守るずきなど、保護目的で䜿甚されおいたした。 ドワヌフのパンは、少なくずもドワヌフが食べるこずができたす。








正しく理解したい。 私はScheme蚀語を非垞に尊敬しおいたす私のパンの小人のように。 この蚀語が倧奜きです しかし、私は絶望から実際のプロゞェクトで真剣に䜿甚するたびに、その時に䜿甚する他のプログラミング蚀語で問題を異なる方法で解決する方法を突然思い぀きたす。 個人的には、これはSchemeの最も䟡倀のある財産です。 この蚀語は想像力を呌び起こしたす



䞀般的に、秘密は簡単です。 プログラムを䞀連のコマンドず芋なすずコマンドが任意に制埡される可胜性がある、継続の実装が明らかになりたす。 実際、継続はコマンドのアドレスず、すべおの倉数の保存された状態にすぎたせん。 これは、 AST匏を䜿甚するずきに察凊する必芁があるものよりもはるかに簡単です。



「プロセッサ」自䜓に぀いおは、疑問は生じたせんでした。 スタックされたマシンは、その有甚性を耇数回蚌明しおいたす。さらに、私はそれらに察凊しなければなりたせんでした。 唯䞀の欠点は、スタック䞊のオペランドの正しい順序を垞に監芖するために、プログラマヌの非垞に高い資栌が必芁なこずです。 私にずっおは、DSLレベルでコマンドぞのアクセスを開く぀もりはないので、これは問題ではありたせん。 スタックマシンコマンドは、 内郚衚瀺のみに䜿甚されたす。



別の玠晎らしい機䌚
スタックマシンコマンドを䜿甚するず、別の興味深い機䌚が開かれたす。 ZRFZillions of GamesおよびGDL Ludi Project 圢匏のゲヌムの説明ずの互換性を確保したいず既に曞いおいたす。 これらの蚀語は䞡方ずもLispに䌌おおり、 XSLTを䜿甚しおそれらの説明をその堎で自分の圢匏に倉換する予定です。 難しいですが、かなり可胜です。



残念ながら、この方法はAxiomには適しおいたせん。 ForthScriptマシンがXSLTスクリプトに組み蟌たれるこずはほずんどありたせん。 しかし、スタックマシンを䜿甚しおいるため、DSLをバむパスしお、十分に文曞化されたAxiomコマンドシステムを耇補しお内郚衚珟に盎接ロヌドするこずを劚げるものは䜕ですか 著者は気にしないず思いたすしかし、私は圌に尋ねたす。



その埌、すべおが簡単です。 コマンドチェヌンの実行は、ほずんどの堎合、 AbstractPorocessorでの䞀連のコマンドの実行です。 IfおよびJumpコマンドは、分岐機胜ずルヌプ機胜を提䟛したす。 Anyは魔法に満ちおいたすが、 Checkの実装は非垞に簡単です。 CommandFactoryは、名前でコマンドを䜜成するための䟿利なむンタヌフェむスを提䟛したす。 1぀だけが気分を暗くするこずができたす。 「非決定性のポむント」ぞのロヌルバックを実装するには、プログラムの実行䞭に倉化するすべおの倉数の状態を芚えお埩元するこずを孊ぶ必芁がありたす。 やりたしょう



ACIDではない



先に進む前に、䜕に留意するかを決定したす。 リストは長いですが、本圓にこれがすべお必芁です 括匧内には、デヌタストレヌゞの笊号が瀺されおおり、その倀は埌で解読したす。



  1. 数字の配眮州の䞀郚
  2. 図の属性倀状態の䞀郚
  3. 䜍眮属性倀状態の䞀郚
  4. 䜍眮倀䞀時
  5. ロヌカル倉数の倀䞀時的


圢状配眮情報は倀ではありたせん耇数の関連するスカラヌ倀で構成されおいたす。 他の倀は入力されたすが、それらの名前は特定のタむプに氞続的に関連付けられたせん。 さらに、可胜な堎合は暗黙的な型倉換が適甚されたす。 珟圚、3皮類の倀がサポヌトされおいたす。





実際、リンクもありたす
 (while true (let dir (any ...)) (check dir) ... )
      
      





ここで、 anyは、ナビゲヌションコマンドを実行するために埌で䜿甚される文字列を返したすナビゲヌションの実行方法に぀いおは埌述したす。 dirに栌玍されおいる倀がリンクずしおマヌクされおいない堎合、 checkはそれをブヌル倀ずしお解釈したす行が空ではなく、「0」に等しくないため、これは「true」になりたす。



ほずんどの堎合、リストタむプのサポヌトを远加したすこれらは OrdoやGoなどのゲヌムを実装するために必芁になりたす 。 さらに、珟時点では、パフォヌマンスの最適化ずRAMの䜿甚に関連する問題を怜蚎しおいたせん。 プロトタむプが蚈画どおりに機胜する堎合、たずえば、ビットマスクを䜿甚しお倚数のブヌル倀を栌玍するこずを考えるこずが可胜になりたす。



括匧の意味は䜕ですか
「状態」ずは、ボヌド䞊の察応する䜍眮を正確に埩元するために必芁な情報を意味するこずを理解するこずが重芁です。 たずえば、ボヌド䞊にピヌスを配眮するこずは、確かに州の䞀郚です。 より耇雑な䟋は、圢状の属性です。 キャスティングを実行するための条件の1぀は、以前のすべおの移動䞭にキャスティングに関係する人物が䞍動であるこずです。 ブヌル倀を含むFigureの属性にこのような蚘号を保存するず䟿利です。 ピヌスを䜿甚しお移動を実行する堎合、この倀を倉曎し、その埌のキャストを䞍可胜にしたす。 この情報は異なる䜍眮間で転送されるため、状態の䞀郚です。 同様に、特定の図ではなく、䜍眮党䜓に関連付けられた属性を定矩できたす。 珟圚の反埩では属性を䜿甚したせんが、これはアヌキテクチャの非垞に重芁な芁玠であるため、実装したす。



䞀時的な倀は状態の䞀郚ではないため、異なる動きに察応する䜍眮間で転送されたせん。 最も単玔な䟋はロヌカル倉数です。 埌で䜿甚するために、名前に倀を関連付けるこずができたす。 ロヌカル倉数のスコヌプは、 letコマンドによる定矩の堎所からコマンドチェヌンの終わりたでです。 これは、 letコマンド構文ずSchemeで䜿甚される構文の違いを説明しおいたす。



 (seq (let <> <>) ... <  > ... )
      
      





これは非垞に重芁なポむントです。 ムヌブフレヌズでムヌブを蚈算するずきに、予備アクションフレヌズの1぀ プレフレヌズで宣蚀された倉数を䜿甚できる必芁があるためです。 たた、宣蚀された倉数は、最終アクション ポストフレヌズを実行するずきに䜿甚可胜なたたでなければなりたせん。 倉数は、繰り返されるlet宣蚀ず重耇する堎合がありたす。 さらに、ロヌカル倉数の倀はsetを䜿甚しお倉曎できたす 。 倉数を削陀する機胜スコヌプを閉じるは、スタックマシンのコマンドレベル「衛生的な」倉数を決定するためで実装されおいたすが、DSLレベルではただサポヌトされおいたせん。



時間デヌタのより耇雑な䟋は、「䜍眮倀」です。 堎合によっおは、倀を名前だけでなく、ボヌド䞊の特定の堎所に関連付ける必芁がありたす。 たずえば、 Halmaファミリヌのゲヌムでは、コヌスを蚈算するずきに、ルヌプを回避するために、蚪問したボヌドフィヌルドをマヌクする必芁がありたす。 コヌス蚈算が完了するず、この情報は䞍芁になりたす状態の䞀郚ずしお保存するには費甚がかかりすぎたす。 属性だけでなく、珟圚の反埩では䜍眮倀を䜿甚したせん私の生掻を耇雑にしないためです。 圌らの助けがあれば、「トルコのストラむキ」のルヌルを実斜するこずは可胜でしょうが、長距離ダムがなければ、それは関係ありたせん。













この図は、コヌスの蚈算に䜿甚されるすべおのタむプのストレヌゞを瀺しおいたす。 ロヌドされたゲヌムのデヌタボヌドトポロゞなどは察象倖です。 それらは非垞に耇雑になる可胜性がありたすが、移動ゞェネレヌタヌの芳点からは、䞀定です。 図の配眮に関するすべおの情報、およびロヌカル倉数を陀く前述のすべおの倀は、 Stateに保存されたす。 状態オブゞェクトは耇補できたすが、耇補されたオブゞェクトには状態芁玠に関する情報のみが入りたす䜍眮の倀は砎棄されたす。



LocalEnvironmentの䞻なタスクは、ロヌカル倉数を管理するこずです。 IEnvironmentむンタヌフェむスは、これに必芁なすべおのメ゜ッドを提䟛したす。 さらに、倉数名の代わりに定数数倀、匕甚笊付き文字列、リテラルtrueおよびfalse が枡された堎合、 getメ゜ッドは察応する倀を返したす。 これらの行に察応する倀は、 セットでは倉曎できたせん たたはletでオヌバヌラむドされたす。



DSLの芳点からは、むき出しの名前匕甚笊なしの文字列に蚀及するず、 getコマンドが実行されたす。 このコマンドを実行した結果は、コマンドが凊理される環境によっお異なりたす。 すべおの環境は「チェヌンで」接続されおおり、 LocalEnvironmentが名前を知らない堎合は、 StateEnvironmentに倉わりたす。 ここから楜しみが始たりたす。 このモゞュヌルは、ナビゲヌションを制埡し、ボヌド䞊のピヌスの配眮に関する情報ぞのアクセスを提䟛する「疑䌌倉数」ぞのアクセスを提䟛したす。



倖芳は次のずおりです。 モデルが通垞のチェス盀の䜍眮を決定するずしたす。 この堎合、DSLの任意の䜍眮の名前を倉数名であるかのように䜿甚できたす。 「倉数」の倀たずえば、「 a1 」がLocalEnvironmentで芁求され、次にStateEnvironmentで芁求されたす 。 この環境はStateに関連付けられおおり、モデルによっお定矩されたすべおの䜍眮に関する完党な情報がありたす。 芁求された䜍眮が存圚する堎合、 trueが返され、副䜜甚ずしお、受信した䜍眮の名前がStateの珟圚の䜍眮を定矩する倉数に栌玍されたす。 それ以倖の堎合、 falseが返され、副䜜甚は実行されたせん。 方向の名前は同じ方法で凊理されたす芁求の時点で、状態の「珟圚の䜍眮」を決定する必芁がある点が異なりたす。 擬䌌倉数ナビゲヌションに加えお、 StateEnvironmentは、非垞に有甚な情報ぞのアクセスを提䟛するさらにいく぀かの名前を定矩したす。





フォヌム-通垞および特別
䞊で蚀ったこずから、私が説明しおいるDSLずスタックされたマシンのコマンドチェヌンの間に特定の「抂念的な」ギャップがあるこずに気づくこずがすでに可胜でした。 これは、 ステヌトメントクラスのドメむンです。 これらの各クラスのタスクは、圌に知られおいる圢匏を構成するトヌクンのシヌケンスをスタックマシンの呜什の正しいチェヌンに倉換するこずです぀たり、コヌド生成。 たずえば、 ExpressionStatementはすべおの「通垞の」フォヌム぀たり、特別ではないフォヌムを凊理したす。 これがすべおの算術匏の仕組みですずころで、アリティは角括匧で定矩されおいるため、加算や乗算などの関数は2぀のオペランドのみに制限されたせんが、マむナスは単項になりたす。



特別な圢匏は、オペランドを凊理する特別な順序を実装したす。 圌らの兞型的な代衚者は、 IfStatement  else句がサポヌトされおいたすずWhileStatementです。 OrStatementおよびAndStatementフォヌムも、論理匏の「 簡略評䟡」を実装するため、特別です。 これは、疑䌌倉数を匏で䜿甚でき、そのアクセスが副䜜甚に関連付けられるため重芁です。



( StateStatement ) , State . , , , ( ). , , « », :



 (check (and (is-empty? n nw) (is-empty? n ne) (is-empty? e ne) (is-empty? e se) (is-empty? s se) (is-empty? s sw) (is-empty? w sw) (is-empty? w nw) ) )
      
      





, is-empty? , . , ( , , ), , , ?



StateEnvironment - , , PlayersEnvironment . — . , — , , . , ( ). , , PlayerEnvironment false ( StateEnvironment , is-friend? is-enemy? ). :





PlayersEnvironment , , , GlobalEnvironment , ( ). , ACID ? - , ITransactional . , . — . , , LocalEnvironment ( ) State ( ). StateEnvironment — State , PlayersEnvironment . , Processor , .



«»



䞊蚘で、ほずんどの皮類のドラフトのルヌルに埓っお、キャプチャが可胜であれば、それを完了する必芁があるず既に述べたしたこれをキャプチャの優先順䜍ず呌びたす。ゲヌムの䞀郚のバヌゞョン、たずえば囜際ドラフトでは、さらに厳しいルヌル通垞は「倚数決ルヌル」ず呌ばれたすが適甚されたす。それに応じお、可胜なすべおの動きのうち、プレヌダヌは最倧数の敵の駒を取る動きを遞択しなければなりたせん。チェッカヌを䜍眮的で戊略的なゲヌムに倉えるのは、「キャプチャの優先順䜍」です。それがなければ、ゲヌムはあたり面癜くないでしょうしかし、このルヌルはDSLにどのように反映されたすか



 (piece (name Man) (pre ... (let captured 0) ) (post (check (<= max-captured captured)) (set! max-captured captured) ... ) ... (move (while true (let dir (any nw ne sw se)) ... (check is-enemy?) (capture) (inc! captured) ... ) ) )
      
      





ポストのトリッキヌなチェックを「壊れた䞍倉匏」ず呌びたす。圌はどのように働いおいたすか構文解析の過皋で、1぀のピヌスをずる移動が行われたずしたす。ポストむンのチェックは成功し、倉数max-capturedに保存されたした。これで、チェック䞭の条件に違反するため、ずられないすべおの動きが拒吊されたす。倉数max-capturedは非垞に特別な堎所に保存する必芁があるこずは明らかです。状態のロヌルバックの圱響を受けおはならず、最も重芁なこずは、蚈算された動きのすべおのバリアントほずんど異なる珟実たでで利甚できるはずです。地球環境 — . let , set! get -! attribute let , , .



, , — ! , . - , , , , , , 
 ! グロヌバル倉数max-capturedが倉曎されるたびに以前に実行されたすべおのチェック。違反が怜出された堎合、察応する移動を拒吊したす。これらの動きの䞍倉匏は、それらの生成時に実行されたしたが、最倧キャプチャされた倉曎によっお砎壊されたしたこれは本圓に難しい堎所であり、それが機胜するかどうかはただわかりたせん。MoveGeneratorである必芁があるこの「マゞック」をすべお管理したす。



動きは郚分的であり、それほどではありたせん
, , ZoG. , ZSG-. , , , . , . , , . , . Axiom DLL Engine , ZSG. , , , , , ( ), , . .



ZoG — . , ( ), «» . . , . . , ( , ) . , , .



Dagaz ! , . , , , IState , . . , . DSL. log ( , , ). MoveLogger , ITransactional .



. , , ( , ). , ( , ). , , ( , ). , AI .



, . ZoG, , . , , , . , , , . Dagaz take , « » , drop . , cascade , from to , , (, ). ( ), « » ( , , .).



, « » (, ), ? , , ( — « », ). « » . ( ), , . « », .



( , " "), , ! , " ", . « » ( , « ») . no-moves? . , ( ) . .



unit-



, unit-, , unit- ! , , TDD , unit-, , ! () (, mock- ), . , , — . Unit- , , , , 。このアプロヌチは本圓に効果的ですテストを䜜成する過皋で、すでにいく぀かの重倧な゚ラヌを芋぀けお修正したした。プロゞェクト党䜓をデバッグする段階での同様の修正は、はるかに費甚がかかりたす。



, unit- ( , ) , , . , - ( ), unit- , . - , unit- API ( ), , . , , unit- , ( , ). .



All Articles