ZoGを使いこなす(パート2:ワム!)

ワム...



...この音で、重いクラブが誰かの頭に触れました。 体はけいれんし、ひっくり返った。 行為は、誰にも見られなかった、聞いたことのない、理想的な終わり、理想的な決定、理想的な物語であった。



しかし、ドワーフが言うように、トロルは不幸の背後にあります。



サー・テリー・プラットチェット



ドッ! もちろん、私はこのゲームをすり抜けることができませんでした。 テリー・プラチェットの作品が本当に好きだからだけでなく、主にゲームが何のようでもないからです。 まず、八角形のボードで演奏します。 ドワーフはトロルと戦う(そしてトロルははるかに小さい)。 少数派でトロルはどのように勝つことができますか? 非常に簡単です-1回の動きで、トロールはボードからいくつかのノームを削除できます。 そして、ドワーフは、ボードから1つのトロールを取り除くために一緒に行動する場合でも、汗をかかなければなりません。



Pratchettの作品に基づいたボードゲームは、2002年にTrevor Truranによって開発され、販売されました。 このゲームについて知った瞬間から、本当にプレイしたかったです。 長い間、私はそのコンピュータ実装の検索に失敗しましたが、私が見つけたのは、ゲームが複雑すぎてコンピュータがプレイできないという議論だけでした。 今、私はこの声明を検証する機会があります。



まず、ゲームのルールに取り組みましょう。



前述したように、ゲームは八角形のボードでプレイされ、その中央には1つのセルを占める「ロック」があります。 ゲームには、8つのトロールと、32のノーム(小人)が含まれます。 両側のタスクは、敵の数を最小限にすることです。



ゲームは2段階で行われます(ルールのこの段落は、同じ名前の本のプロットで本質的に使用されます)。 各プレイヤーは、ノームとトロルの両方でプレイする必要があります。 原則として、対戦相手のすべてのピースをボードから削除することはできません。 ゲームはプレイヤーの同意により終了し、その後ポイントが考慮されます。 ボードに残っている各小人は、1ポイント、トロール-4ポイントで評価されます。 プレイした2つのゲームの結果が合計されます。 最も多く得点した人が勝ちました。



ドワーフは縦、横、または斜めに(チェスの女王のように)任意の数のフリーセルに移動しますが、トロールボードから削除するには、ドワーフはそこに「ジャンプ」する必要があります。 ラインを形成するいくつかのノーム(垂直、水平、または斜め)は、ラインのノームの数以下のセルの数だけ極端なノームが(ラインと反対方向に)ジャンプできるようにします(トロールがジャンプの終点にある場合)。 単独で立っているgnomeもラインを形成するため、任意の方向に1つのセルをジャンプしてトロールを除去できます(もちろん、彼が彼に近づいた場合を除きます)。



トロールは、チェスの王のように、任意の方向に1つのセルに移動できます。 移動の完了点から1つのセルの距離にいるすべてのノームは、ボードから削除されます。 したがって、1回の動きで、トロールはボードから最大7つのノームを削除できます(非常に幸運な場合)。 ボードからgnomeを削除するには、トロールが移動する必要があります(gnomeが既にその横に立っている場合でも)。 トロールは整列することもできます(ただし、必要な範囲はノームよりもはるかに少ないです)。 N個のトロールの行(垂直、水平、または斜め)は、この移動の結果として少なくとも1つのgnomeがボードから削除されるという条件で、N(またはそれ以下)セルだけ極端なトロールを「プッシュ」できます。



ピースが互いに飛び越えたり、ボードの中央の「岩」を飛び越えたりすることはできません。



「行」の数字の数を数える必要があることに気づくかもしれません。 ZoGでの計算は非常に難しいため(ほとんどの場合、2回以上説明します)、これらのルールの実装は、何らかの形でテストであり、同時に言語の可能性をより完全に説明することを可能にしますZRFの説明。 ただし、簡単なものから始めましょう。



ボード
(define board-defs (image "images\gluk\Thud.bmp") (grid (start-rectangle 45 35 60 58) (dimensions ("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o" (35 0)) ; files ("15/14/13/12/11/10/9/8/7/6/5/4/3/2/1" (0 35)) ; ranks ) (directions (n 0 -1) (e 1 0) (s 0 1) (w -1 0) (nw -1 -1) (ne 1 -1) (se 1 1) (sw -1 1)) ) (kill-positions a15 b15 c15 d15 e15 k15 l15 m15 n15 o15 a14 b14 c14 d14 l14 m14 n14 o14 a13 b13 c13 m13 n13 o13 a12 b12 n12 o12 a11 o11 h8 a5 o5 a4 b4 n4 o4 a3 b3 c3 m3 n3 o3 a2 b2 c2 d2 l2 m2 n2 o2 a1 b1 c1 d1 e1 k1 l1 m1 n1 o1 ) (symmetry Black (ns)(sn) (ne sw) (sw ne) (nw se) (se nw)) )
      
      







この説明では、前の記事で説明した内容と比較して、新しいキーワードkill-positionsが追加されました。 説明のこのセクションでは、ボードの多数の位置を禁止して、ボードを四角形から八角形に回転させることができます。 私が約束したように、中央には「ロック」があります。 図形は通過できません。 実際、これは競技場の一部ではありません。



進む
 ( define game-defs ( board (board-defs) ) ( board-setup (White (Dwarf f1 g1 i1 j1 e2 k2 d3 l3 c4 m4 b5 n5 a6 o6 a7 o7 a9 o9 a10 o10 b11 n11 c12 m12 d13 l13 e14 k14 f15 g15 i15 j15) ) (Black (Troll g7 h7 i7 g8 i8 g9 h9 i9) ) ) (loss-condition (White Black) stalemated) (draw-condition (White Black) repetition) )
      
      







ここに新しいものはありません。 数字を整理し、負けの条件(それぞれの側-次の動きができないこと)と引き分け(位置の繰り返し)を決定します。 今、楽しみが始まります。 行の形状を数える方法を考え出す必要があります。



ノーム・リープ
 ( define dwarf-3 ( mark (opposite $1) (verify friend?) (opposite $1) (verify friend?) back $1 (verify empty?) $1 (verify empty?) $1 (verify enemy?) add ) )
      
      







図を3つのセルにジャンプするには、次のようにします。



  1. markコマンドで現在の位置を覚えています
  2. セル上でフレンドリーな形状を確認しながら、反対方向に2回移動します
  3. backコマンドで元のセルに戻ります
  4. セルが空であることを確認しながら、移動方向に2回移動します
  5. 敵のフィギュアがターゲットスクエアにある場合は再度移動します
  6. すべての条件が満たされた場合、追加コマンドで移動を完了します(敵の駒はボードから自動的に削除されます)


これで、ドワーフは3つのセル(適切なラインがある場合)にジャンプして、トロールボードから取り出すことができます。 3つに加えて、ノームは別のセル数にジャンプできるように、dwarf-7までのマクロdwarf-1、dwarf-2などを追加する必要があります。 さらに、ボード上の多数のセルにジャンプしても機能しないため、マクロを決定することはできません(7セルにジャンプできる場合でも、ドワーフは非常に幸運であるため、このマクロはほとんど使用されません) ) この解決策は多少冗長ですが、機能します。



キャプチャに加えて、ノームは(指定された方向の任意の数のセルに対して)通常の動きを行える必要があります。 ここではすべてが簡単です:



ノームの動き
 ( define shift ( $1 ( while empty? add $1 ) ) )
      
      







ループを使用します。 セルが空の間、指定された方向に移動し、可能な移動を追加します。 これはこれらすべてのセルに行くという意味ではありません。 これらの細胞の上歩くことができると ZoGコアに伝えますが 、残りは彼次第です。



トロルの動きの実装は、動きの終わりにボードの隣接するセルからノームの図形を削除できるという事実により、やや複雑です。 これは、トロールの実装が2つのセルに移動する方法です。



トロール移動
 ( define troll-2 ( mark (opposite $1) (verify friend?) back $1 (verify empty?) $1 (verify empty?) (verify (or (enemy? n) (enemy? nw) (enemy? s) (enemy? ne) (enemy? w) (enemy? sw) (enemy? e) (enemy? se))) (if (enemy? n) (capture n)) (if (enemy? nw) (capture nw)) (if (enemy? s) (capture s)) (if (enemy? ne) (capture ne)) (if (enemy? w) (capture w)) (if (enemy? sw) (capture sw)) (if (enemy? e) (capture e)) (if (enemy? se) (capture se)) add ) )
      
      







適切なラインの可用性をチェックすることに加えて、移動の結果として、少なくとも1つのgnomeが取得されることをチェックします。 また、コースの終了前に、8方向すべての隣人のキャプチャが追加されました(これらが敵のピースである場合)。 などの述語に注意する必要がありますか? または空ですか? これらは、方向パラメーターの転送を伴う呼び出しの形式を許可します。これにより、別のセルに移動することなくチェックを実行できます。 これはしばしば非常に便利です。 1つのセルでの移動の実装では、単純に不要なチェックを削除します。



ワンセルトロール
 ( define troll-1 ( $1 (verify empty?) (if (enemy? n) (capture n)) (if (enemy? nw) (capture nw)) (if (enemy? s) (capture s)) (if (enemy? ne) (capture ne)) (if (enemy? w) (capture w)) (if (enemy? sw) (capture sw)) (if (enemy? e) (capture e)) (if (enemy? se) (capture se)) add ) )
      
      







ゲームを組み立て、すべてが機能することを確認することは残っています。



ドッ!
 (game (title "Thud") (description "...") (history "...") (strategy "...") (players White Black) (turn-order White Black) (game-defs) (piece (name Dwarf) (image White "images\gluk\d.bmp") (description "d") (moves (dwarf-1 n) (dwarf-1 ne) (dwarf-2 n) (dwarf-2 ne) (dwarf-1 e) (dwarf-1 nw) (dwarf-2 e) (dwarf-2 nw) (dwarf-1 s) (dwarf-1 se) (dwarf-2 s) (dwarf-2 se) (dwarf-1 w) (dwarf-1 sw) (dwarf-2 w) (dwarf-2 sw) (dwarf-3 n) (dwarf-3 ne) (dwarf-4 n) (dwarf-4 ne) (dwarf-3 e) (dwarf-3 nw) (dwarf-4 e) (dwarf-4 nw) (dwarf-3 s) (dwarf-3 se) (dwarf-4 s) (dwarf-4 se) (dwarf-3 w) (dwarf-3 sw) (dwarf-4 w) (dwarf-4 sw) (dwarf-5 n) (dwarf-5 ne) (dwarf-6 n) (dwarf-6 ne) (dwarf-5 e) (dwarf-5 nw) (dwarf-6 e) (dwarf-6 nw) (dwarf-5 s) (dwarf-5 se) (dwarf-6 s) (dwarf-6 se) (dwarf-5 w) (dwarf-5 sw) (dwarf-6 w) (dwarf-6 sw) (dwarf-7 n) (dwarf-7 ne) (shift n) (shift ne) (dwarf-7 e) (dwarf-7 nw) (shift e) (shift nw) (dwarf-7 s) (dwarf-7 se) (shift s) (shift se) (dwarf-7 w) (dwarf-7 sw) (shift w) (shift sw) ) ) (piece (name Troll) (image Black "images\gluk\T.bmp") (description "T") (moves (troll-1 n) (troll-1 ne) (troll-2 n) (troll-2 ne) (troll-1 e) (troll-1 nw) (troll-2 e) (troll-2 nw) (troll-1 s) (troll-1 se) (troll-2 s) (troll-2 se) (troll-1 w) (troll-1 sw) (troll-2 w) (troll-2 sw) (troll-3 n) (troll-3 ne) (troll-4 n) (troll-4 ne) (troll-3 e) (troll-3 nw) (troll-4 e) (troll-4 nw) (troll-3 s) (troll-3 se) (troll-4 s) (troll-4 se) (troll-3 w) (troll-3 sw) (troll-4 w) (troll-4 sw) (troll-5 n) (troll-5 ne) (troll-6 n) (troll-6 ne) (troll-5 e) (troll-5 nw) (troll-6 e) (troll-6 nw) (troll-5 s) (troll-5 se) (troll-6 s) (troll-6 se) (troll-5 w) (troll-5 sw) (troll-6 w) (troll-6 sw) (troll-7 n) (troll-7 ne) (troll-7 e) (troll-7 nw) (troll-7 s) (troll-7 se) (troll-7 w) (troll-7 sw) ) ) )
      
      







このゲームでは、トロルは非常に強い数字であることが判明したことに注意してください。 より大きなボードがあれば、ドワーフは逃げ出してコンパクトなユニットに集まることができたでしょう。 しかし、私たちのボードでは、ジャンプの可能性のおかげで、トロルはすでに2〜3手でノームに到達します。 私は長い間、このゲームを両側でコンピューター制御モードで実行しました。 最終的に、両側に5個のピース​​が残った後、トロールはドワーフの機動性のためにドワーフに追いつかなくなりました。 人はノームのためによりよくプレーできると認めます。 一方、荒らしのように遊んでいるコンピュータは、確かにそのタスクに対応しています。



いつものように、ソースはGitHubで取得できます。



念のため、Zillions of Gamesのデモ版で起動することはできないことを思い出してください。 あなたも試してみる必要はありません。




All Articles