質問

私はこのオブジェクト指向設計の問題についてしばらく考えてきましたが、満足のいく解決策を見つけることができませんでした。そこで、意見を求めてここで群衆に公開してみようと思いました。

私は持っています ゲーム ターンベースのボード ゲームを表すクラスなので、この質問の目的では、Monopoly に似ていると想定できます。私のデザインには、 プレーヤー メソッドを含むクラス 交代する.

ゲーム すべてをループします プレーヤーそして、TakeTurn メソッドを呼び出して、ターンを完了するために必要なすべての処理を実行します。n 人のプレーヤーを持ち、そのうちの任意の数をコンピューター プレーヤーに設定できるようにしたいと考えています。そこで、私の考えは、HumanPlayer クラスと コンピュータプレーヤー どちらも Player から派生したクラスです。

ゲーム だけを知っています プレーヤー クラスを呼び出して、単に 交代する それぞれの方法 プレーヤー 順番に。私の問題は、次のような事実にあります。 コンピュータプレーヤー オブジェクトは完全に自動化できます。モノポリーの例で言えば、何らかのロジックを使用して不動産の購入を決定できます。さて、 ヒューマンプレイヤー オブジェクトの場合、たとえばプロパティを購入できるようにするには実際のユーザーから入力を取得する必要がありますが、これは別のインターフェイスを暗示しているようで、潜在的にインターフェイスを派生すべきではないことを意味しているようです。

がなければ、問題に対する良い解決策を思いつくことができませんでした。 ゲーム クラスはさまざまな実際の実装を知っています プレーヤー 明示的にクラスを指定します。私はいつでも次のような仮定を立てることができました ゲーム 人間とコンピューターのプレイヤーのみが存在するクラスを作成し、拡張のために事実上閉じますが、それは良いオブジェクト指向プログラミングとは思えません。

これに関してご意見がございましたら、よろしくお願いいたします。

役に立ちましたか?

解決

Game クラスに IO を処理させるべきではないと思います。このようにして、(ブロックする) TakeTurn メソッドは実装手段をゲーム ボードから隠します。他のオブジェクトを使用してユーザーと通信できます。

Game クラスが関係する必要があるのは、ボードとターンの状態だけです。プレイヤーはすべて単一のプレイヤー インターフェイスを実装し、すべての実装をゲームから隠す必要があります。

他のヒント

ゲームがゲームの状態を管理している場合 そして I/O を実行すると、ゲームがやりすぎます。

ゲームはルール、ターン、状態の変化だけにしっかりと焦点を当てたいと考えています。ゲームはプレイヤーが何であるかを知りません。プレイヤーがいることだけを知っています。

プレイヤーにゲームの状態を調べて、自分のターン中に法的措置を実行してもらいたいと考えています。

人間のプレイヤーとゲーム全体 両方 ゲームの状態を表示し、人間に入力を促す共通の I/O パッケージを共有します。

Javaを上手に活用できる Observable I/O パッケージを Observer ゲームの。そうすることで、ゲーム状態の変化が表示またはログ、あるいはその両方のために I/O に報告されます。

たぶん2つも持たないだろう HumanPlayer そして ComputerPlayer クラスですが、単一の Player 作成時に適切な入力戦略を使用して構成されたクラス。

プレイヤーがゲームの次のターンで手を決定するための情報を取得する方法は、 のみ (少なくとも元の問題の説明とは) 異なるものがあるため、それを別の抽象化でカプセル化するだけです。

ゲームを設定する高レベルのクラスが何であれ、それぞれに適切な入力戦略を使用して 2 組のプレーヤー (1 人は人間、もう 1 人はコンピューターでシミュレート) を作成し、これらのプレーヤー オブジェクトをゲーム オブジェクトに与えるだけです。Game クラスは、 TakeTurn 新しいターンごとに、指定されたプレイヤーのリストのメソッド。

人間は 1 人だけであることをゲーム クラスに伝える代わりに、ゲームのメニュー/初期化中にその入力を取得できるようにしてはどうでしょうか?さらに多くのプレイヤーがいる場合は、ゲーム クラスの初期化の前に、何らかの形式の入力 (メニューでプレイヤーを選択) によって決定できます。

そのインターフェースは、 プレーヤー にプレゼントする ゲーム は導出された関数の動作と直交します プレーヤー クラス。

の実装という事実は、 交代する 具体的な種類によって異なります プレーヤー オブジェクトは心配する必要はありません。

私は思います Game クラスは、Player クラスの実装を考慮すべきではなく、ユーザー インターフェイスも無視する必要があります。

ユーザー入力はすべて、 HumanPlayer クラス。

私が言うのは、 ゲーム クラスは、これがコンピューター プレーヤーであるか人間のプレーヤーであるかを気にする必要はありません。常に呼び出す必要があります 交代する 次のプレイヤークラスについて。これが人間のプレイヤーの場合、それはプレイヤーの責任です。 プレーヤー クラスを使用してユーザーと通信し、ユーザーに何をすべきかを尋ねます。つまり、ユーザーが決定するまでブロックされます。通常、UI の対話はアプリケーションのメインスレッドで行われるため、ブロックすることのみが重要です。 交代する アプリケーション全体をブロックしません。ブロックしないと、その間ユーザー入力を処理できません。 ゲーム 待っています 交代する.

の代わりに、 ゲーム クラス呼び出し 交代する プレイヤーがコールすべきすべてのプレイヤーについて 交代するゲーム クラスと ゲーム クラスは、正しいプレイヤーが順番をとっているかどうかを検証する必要があります。

これは問題の解決に役立つはずです ユーザー そして コンピューター 選手の問題。

これがあなたが望んでいることかどうかわかりません

public abstract class Player 
{
  int position;
  DecisionMaker decisionDependency;

  ...

  public void TakeTurn()
  {
    position += RollDice();
    GameOption option GetOptions(position);
    MakeDescion(option);
  }

  protected int RollDice()
  {
    //do something to get the movement
  }

  protected abstract void MakeDecision(GameOption option);

}

Public class ComputerPlayer : Player
{
  public ComputerPlayer()
  {
    decisionDependency = new AIDecisionMaker();
  }

  protected override void void MakeDecision(GameOption option)
  {
    decisionDependency.MakeDecision(option);
    //do stuff, probably delgate toan AI based dependency
  }
}

Public class HumanPlayer : Player
{
  public HumanPlayer()
  {
    decisionDependency = new UIDecisionMaker();
  }

  protected override void void MakeDecision(GameOption option)
  {
    decisionDependency.MakeDecision(option);
    //do stuff, probably interacting with the a UI or delgate to a dependency
  }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top