狂気の危機にOnして

連珠は多くのcommon民です

ヒーローはチェスをする

Go-神々のゲーム



日本のことわざ。



愚かさに対して、神自身は戦う力がない。



アイザック・アシモフ。





秋の到来とともに、私は奇妙な何かが欲しい。 私はできるだけ難しいゲーム、プレイをすべきだと考えましたか? ボードゲームの世界の一種のBrainfuckアナログに興味があります。 ゲームのルールをできる限りシンプルにしたい( Rhythmachyは明らかにこの定義に合わない)。 Goはこの役割の有力な候補ですが、人々はそれを多数演じています(これは簡単ではありませんが)。 Goが神のゲームである場合、あなたは神がプレイするのが難しいゲームを見たいと思うでしょう。 私は神の力と私の狂気を対比することにしました。 良い意味で...



もちろん、Habréのゲーム「 Life 」に特化した投稿を公開するのは初めてではありません。 このトピックは繰り返し議論されてきました。 「 ... 30行で 」という伝統的な投稿があり、 面白い投稿がありました他の スペース規則変える可能性が考えられました 。 親愛なるx0m9k、HaskellLifeを実装する方法を示し、 BarsMonsterはそれをフーリエ変換に関連付けました。 Lifeに基づいて、ボードゲームを実装することにしました(この点で、私は再びオリジナルではありません )。



なぜLifeゲームをベースにしたのですか? 2つの理由:



  1. このゲームのルールは簡単に策定できます。
  2. ほんの数回の移動で初期構成が何になるかを予測することは非常に困難です


これは、本当に複雑なゲームの優れた基盤ですが、2つの重要なポイントが欠けています。それは、双方向性と複数のプレイヤーとプレイする能力です。 ゲーム「Life」は完全に非インタラクティブです。 非常に複雑な初期構成(たとえば、「グライダー」またはチューリングマシンの生産のための生産ライン全体)を構築できますが、プロセスが開始されるとすぐに、「プレーヤー」にオブザーバーの役割が割り当てられます。 何も変更できません。 また、最初のコンセプトは、2つ(またはそれ以上)の競合する原則のゲームへの参加を提供していません(このトピックは、 PsiBG投稿でわずかに異なる平面で検討されました)。



ルール



対話性を追加する問題は、さまざまな方法で解決できます。 そのため 、彼の投稿でアバルモットは 、プレイヤーに既製のフォームまたは「爆弾」を投げて敵の領域をクリアする機会を与えることを提案しました(敵の領土を移動するフォーム、例えば「グライダー」で「砲撃」する提案もありました)。 これは複雑すぎると思います。 ゲームにインタラクティブ機能を導入する変更は最小限に抑える必要があります。



プレイヤーに、ターンごとに自分の色の石を1つだけフィールドに追加する機会を与えましょう。 ボード上のどの場所でも、主なことは空です。 この方法で追加された石は、ゲームのすべてのルールに従います。 たとえば、隣人が2人に満たない場合、次のプレイヤーに手が渡される前に彼は死にます(もちろん、会社では彼の不在で生きる石を手に入れることができます)。



「ライフ」ゲームのルールによれば、ちょうど3人の隣人がいる空のフィールドに新しい石が作成されます。 新しい石の色は、この地域の色の優位性によって決まります。 2人のプレーヤーをプレイするとき、新しい石の色は常に一意に決定されることは明らかです。 近隣にある特定の色の優位性に応じて、すでにボード上にある石も塗り直すことができます(色が均一であれば、変化はありません)。 石自体の現在の色は考慮されず、その隣の色のみが重要です。



これで、ゲームのルールを定式化できます。





ボードをトーラスに「接着」せず、境界効果が表示されます。 ボード外のすべてのフィールドは常に空のままです。 これにより、ゲームがより面白く予測不可能になると思います。



実装



このゲームは、ForthScriptの機能の良い例として役立ちます。 実装の詳細が混乱するほど複雑ではなく、同時に、ささいなことでもありません。 基本は、ボードに石を置くためのコードです。



ゲームブランク
19 CONSTANT R 19 CONSTANT C {board RC {grid} board} {directions -1 0 {direction} North 1 0 {direction} South 0 1 {direction} East 0 -1 {direction} West -1 1 {direction} Northeast 1 1 {direction} Southeast -1 -1 {direction} Northwest 1 -1 {direction} Southwest directions} {players {player} B {player} W players} {turn-order {turn} B {turn} W turn-order} : drop-stone ( -- ) empty? IF drop add-move ENDIF ; {moves drop-moves {move} drop-stone moves} {pieces {piece} S {drops} drop-moves pieces}
      
      







このコードにより、プレイヤーはボードのフリーフィールドに石を交互に配置できます。 「ライフ」のルールを実装することは残っています。 主な難点は、ボード上で直接変更を加えることができないため、後続の計算に影響しないことです。 コース計算中に入力する配列を作成します。



ストローク計算
 RC * CONSTANT SIZE VARIABLE new-cnt SIZE [] new-pos[] SIZE [] new-player[] {players {neutral} ?E {player} B {player} W players} : gen-move ( pos player -- ) new-cnt @ SIZE < IF new-cnt @ new-player[] ! new-cnt @ new-pos[] ! new-cnt ++ ELSE 2DROP ENDIF ; : life-tick ( -- ) here SIZE BEGIN 1- DUP calc-neighbors w-neighbors @ b-neighbors @ + my-empty? IF DUP 3 = IF here w-neighbors @ b-neighbors @ > IF W ELSE B ENDIF gen-move ENDIF ELSE DUP 2 < OVER 3 > OR IF here ?E gen-move ELSE w-neighbors @ b-neighbors @ > IF my-player W <> IF here W gen-move ENDIF ENDIF b-neighbors @ w-neighbors @ > IF my-player B <> IF here B gen-move ENDIF ENDIF ENDIF ENDIF DROP DUP 0= UNTIL DROP to ;
      
      







ここにゲーム「ライフ」のルールがあります。 コードの基礎は、すべてのボードフィールドを列挙するループです(Axiomのボードが1次元配列にマッピングされているため、各フィールドの位置は単純な数値インデックスによって決定されます)。 近傍calc-neighborsの計算結果に基づいて、フィールドの状態を変更する決定が行われます。 変更するフィールドのインデックスはnew-pos []配列に保存され、作成されたFigureの色はnew-player []に保存されます。 ピースの除去を可能にするために、架空のプレイヤー?Eが作成されました 。 プレイヤーとフィギュアの名前は偶然にそれほど簡潔ではないことに注意してください(なぜ重要なのかについては後で説明します)。



ネイバーカウント
 VARIABLE w-neighbors VARIABLE b-neighbors VARIABLE curr-pos : my-empty? ( -- ? ) here curr-pos @ = IF FALSE ELSE empty? ENDIF ; : my-player ( -- player ) here curr-pos @ = IF current-player ELSE player ENDIF ; : calc-direction ( 'dir -- ) EXECUTE IF my-empty? NOT IF my-player B = IF b-neighbors ++ ENDIF my-player W = IF w-neighbors ++ ENDIF ENDIF ENDIF ; : calc-neighbors ( pos -- ) 0 w-neighbors ! 0 b-neighbors ! DUP to ['] North calc-direction DUP to ['] South calc-direction DUP to ['] West calc-direction DUP to ['] East calc-direction DUP to ['] Northeast calc-direction DUP to ['] Southeast calc-direction DUP to ['] Northwest calc-direction DUP to ['] Southwest calc-direction to ;
      
      







ここではすべてが簡単です。 現在の位置から8つの異なる方向に移動しそれぞれb近傍w近傍の黒と白の近傍の数をカウントします。 微妙な点は1つだけです-移動の計算時に、ボードの状態は、プレイヤーが行った移動の結果を考慮しません。 この問題を解決するには、 空を再定義しますか? プレーヤーmy-empty?およびmy-player )は、フィールドの空をチェックし、フィールド上にあるフィギュアの色を取得します。これにより、直前に行われた移動を考慮に入れます(追加されたストーンの位置をcurr-pos変数に保存します)。



ボードの状態変化のベクトルが受信され、それを適用するために残ります。



位置変更
 : exec-moves ( -- ) BEGIN new-cnt -- new-cnt @ new-player[] @ DUP ?E = IF DROP new-cnt @ new-pos[] @ capture-at ELSE STONE new-cnt @ new-pos[] @ create-player-piece-type-at ENDIF new-cnt @ 0= UNTIL ; : drop-stone ( -- ) empty? IF SIZE curr-pos ! here calc-neighbors w-neighbors @ b-neighbors @ + 0> IF 0 new-cnt ! here curr-pos ! drop life-tick new-cnt @ 0> IF exec-moves ENDIF add-move ENDIF ENDIF ;
      
      







ここで、 exec-movesが以前に埋められた配列を「スクロール」し、位置を変更するために必要なコマンドを形成することがわかります。 ドロップストーンコールは、変更の計算とその適用(適用するものがある場合)によって補完されます。 ソースコード全体がGitHubで利用可能です。



結果



このゲームがZoGに本当の強さのテストを与えすぐに言いたいです。 そして、ZoGはこのテストに合格しませんでした。 各移動は多数のフィールド(すべてのボードフィールドまで)の状態を変更できるため、ZSG表記の移動レコードのサイズは500バイト以上に達する可能性があります(プレイヤーとピースの簡潔な命名を考慮しなければ、移動レコードのサイズははるかに大きくなります) ) このサイズの動きを処理するためのZoGシェルは、明らかに設計されておらず、時には落ちます。 幸いなことに、Greg Schmidtが私に提供してくれたAxiomプログラム用に設計された実装は、このサイズを実現します。 2人のランダムプレーヤーのゲームは次のようになります。





パーティーはすぐに終了します。 また、自動再生では予期しないものは表示されません。



 Final results: Player 1 "Random", wins = 54. Player 2 "Random", wins = 46. Draws = 0 100 game(s) played
      
      





ほぼ等しい勝利があり、引き分けはありません。 最もシンプルな評価関数(Rhythmachyで使用されるものと同様)を設定すると、動作がより興味深いものになります。



評価機能
 : OnEvaluate ( -- score ) current-player material-balance ;
      
      











各動きははるかに長く計算され始めましたが、プレイヤーは「よりスマート」にプレイし始めました(その結果、そのような2人のプレイヤー間のゲームはほとんど無制限に遅れました)。 自動再生を使用すると、このプレーヤーがランダムなプレーヤーと比べてどれだけ優れているかを確認できます。



 Final results: Player 1 "Random", wins = 0. Player 2 "Eval", wins = 100. Draws = 0 100 game(s) played
      
      





「スマート」プレーヤーが100のうち100ケースで自信を持って勝つことがわかります。これは、ゲームを意図的にプレイできることを意味します。 確かに、人々にとってはまだ意図されていません。




All Articles