私は haskell ネットワーキング (および一般的なピアツーピア通信) にかなり慣れていないので、人気のある「友達とぶらぶら」に似た、プレイヤー ツー プレイヤーのネットワーク化されたハングマン ゲームに取り組みたいと考えていました。haskell.org の「Implement a chat server」を含むいくつかのチュートリアルに従った後、サーバーを正常に作成し、ソケットをソケットに接続して、メッセージを前後にバウンスすることができました。
また、所定の入力が与えられたときに期待どおりに再生されるハングマン クライアントもあります。
ただし、接続されたクライアント間のイベントの順序付けで問題が発生しています。ソケット チャネルへの読み取りと書き込みは別のスレッドで行われるため (readChan と writeChan のブロック性のため)、リモート ターミナル間でアクションをシーケンス化する方法がわかりません。私は自分が欲しいものを知っていますが、そこにたどり着く方法は知りません:
- 2 番目のユーザーが接続したら、「send」関数を呼び出して、最初のプレーヤーの入力単語を要求します。
- プレーヤー 1 は、"recieve" 関数を介してこの単語を受け取り、それがコマンド キーワード (参加、終了、結果) でない場合は、指定された単語でハングマン ゲームを実行します。その間、プレーヤー 2 の画面がブロックされ、プレーヤー 1 が終了するのを待ちます。
- プレーヤー 1 が終了します。彼の結果が記録され、「送信」関数が呼び出されて、ゲームをプレイするための入力が求められます。
- プレーヤーが終了するまで 2 ~ 3 を繰り返します。
私はこれについていくつかの方法で行ってきました。私のより成功した方法の 1 つは、ブロッキング セマフォを使用することでした。「コントロール」プレイヤーのターンで MVar を使用することを考えました。最初のターンは正しく実行されますが、その後は意味不明に低下します。チャネル内のセマフォの概念 (これは本質的に、ブロックするという点で MVar です) は、私の頭を悩ませています。実際にブロックするため、デバッグも困難です。
私はセマフォの知識が少し不安定です。私がこれをやろうとしている方法は理にかなっていますか?
コードは bitbucket リポジトリにあります。正しいコード/ブランチを取得するために必要な手順は次のとおりです。
git clone git@bitbucket.org:ndisidore/haskell-hangman.git
git checkout block-sem
または、ここでオンラインで表示します。
走る:runhaskell NetInterface.hs
これにより、ポート 3468 でリッスンするソケットが作成されます。
クライアント/プレーヤーとして接続するには、別のターミナルを開いて「telnet localhost 3468」を実行します。これは、各プレイヤーに 1 回ずつ、合計 2 回行う必要があります。
前もって感謝します。