3

ゲームエンジンを実装しています。現在、私のコードのほとんどはStateT Game IO ()モナドにあります。私は IO を使用してユーザー入力を取得します。実際には、すべての IO チャネルが 1 つの関数を介して、

getChoice :: Show a => [ a ] -> IO a

これは、提示されたすべてのオプションをユーザーに促し、応答を読み取り、それを返します。ユーザー応答 (および初期状態) の特定のフローでは、ゲームは決定論的に進行します。これらのユーザー応答を除外して、テストに役立てたいと思います。

これを Pipes を使用するように変換しようとすると、現在 にあるすべてのコードを変更してStateT Game IO ()で実行するのが最も似ていますProxy p, Monad m => Client p [String] String m ()。このようにして、ユーザーからの選択を「要求」することができます。これにより、必要に応じてユーザーの選択が提供されると仮定して、ブロック スタイルでエンジン コードを記述できます。

しかし、これは間違っているようです。ユーザーはクライアントであり、ゲーム エンジンはサーバーである必要があります。この区別を正しく行うために、どのような原則を使用できますか?

4

2 に答える 2

1

ヌシオが言ったように、ClientServerは完全に対称です。非対称性を導入する唯一のものは合成演算子です。( >->) はClient最後に始まり、( >~>) は最後に始まりますServer

( >->) を使用しているため、Clientコンポーネントには「イニシアチブ」があり、物事が進行することを意味します。これは、 が を作成しない限り、 は何もしないことを意味しServerます。が最初に始まるという事実を除けば、との間に違いはありません。ClientrequestClientClientServer

( >->) を に特化し、この非対称性をイニシアチブに反映した場合ClientServer( ) のタイプ:

(>->) => ([String] -> Server [String] String IO r)
      -> (()       -> Client [String] String IO r)
      -> (()       -> Session                IO r)

Server(つまり、ユーザー) は (つまり、ゲーム エンジン) にのみ反応します。そのため、サーバーはボールを転がすためClientに型の引数を受け入れる必要があります。[String]これは、ゲーム エンジンがユーザーに選択を求めるプロンプトを表示しない場合、ユーザーが選択できる一連の選択肢がないため、ユーザーは「決して実行できない」という事実に反映されています。問題を特定した方法から、ユーザーではなくゲームエンジンが制御しています。逆に指定して、ユーザーにゲーム エンジンを操作させると、役割が逆になります。

于 2013-06-20T15:46:45.407 に答える
1

ではpipesServerとは、 とのように、上流と下流でClientほとんど交換可能です。1 つの違いは、最初の要求を発行して開始するのが s の仕事であることです。requestrespondClientSession

http://hackage.haskell.org/packages/archive/pipes/2.5.0/doc/html/Control-Proxy-Tutorial.html

Clientゲームプレイヤーをとの両方で定式化できると確信していますServer。すべては感覚です。彼/彼女をキーボード入力サーバーと考えてみませんか?

于 2013-06-20T14:22:46.297 に答える