7

私はこのオブジェクト指向の設計の質問についてしばらく考えていましたが、満足のいく解決策を思い付くことができなかったので、ここの群衆にいくつかの意見を公開したいと思いました。

ターン制のボードゲームを表すゲームクラスがあります。この質問の目的では、モノポリーに似ていると想定できます。私のデザインには、TakeTurnメソッドを含むPlayerクラスがあります。

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

ゲームPlayerクラスのみを認識し、各PlayerでTakeTurnメソッドを順番に呼び出すだけです。私の問題は、ComputerPlayerオブジェクトを完全に自動化できるという事実にあります。つまり、独占の例を維持すると、ロジックの一部を使用してプロパティを購入することを決定できます。ここで、HumanPlayerオブジェクトを使用すると、たとえばプロパティを購入できるようにするために、実際のユーザーから入力を取得する必要があります。これは、異なるインターフェイスを意味し、派生してはならないことを意味する可能性があります。

GameクラスにさまざまなPlayerクラスの実際の実装を明示的に知らない限り、問題の適切な解決策を思いつくことはできませんでした。ゲームクラスでは、人間とコンピューターのプレーヤーだけが存在し、拡張のために効果的に閉じると常に想定できましたが、オブジェクト指向プログラミングとしては適切ではないようです。

これについてのご意見をいただければ幸いです。

4

9 に答える 9

7

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

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

于 2008-09-18T09:21:29.937 に答える
2

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

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

プレイヤーがゲームの状態を調べて、自分のターン中に法的措置を実行するようにします。

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

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

于 2008-09-20T20:29:18.480 に答える
2

おそらく2つのHumanPlayerandComputerPlayerクラスはなく、Player作成時に適切な入力戦略で構成された1つのクラスがあります。

プレーヤーがゲームの次のターンで自分の動きを決定するための情報を取得する方法は、(少なくとも元の問題の説明から)唯一の違いであるため、別の抽象化でカプセル化してください。

ゲームをセットアップする高レベル クラスは、2 組のプレーヤー (1 人は人間、もう 1 人はコンピュータでシミュレート) を作成し、それぞれに適切な入力戦略を適用し、これらのプレーヤー オブジェクトをゲーム オブジェクトに渡すだけです。TakeTurnGame クラスは、新しいターンごとに、指定されたプレーヤーのリストのメソッドのみを呼び出します。

于 2009-09-14T16:32:44.193 に答える
1

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

于 2008-09-18T09:22:10.370 に答える
1

PlayerがGameに提示するインターフェースは、派生したPlayerクラスの動作と直交しています。

TakeTurnの実装がPlayerオブジェクトの具体的なタイプによって異なるという事実は、心配する必要はありません。

于 2008-09-18T09:25:10.707 に答える
0

GameクラスはPlayerクラスの実装については気にせず、ユーザーインターフェイスも無視するべきだと思います。

HumanPlayerユーザー入力はすべて、クラスで処理する必要があります。

于 2008-09-18T09:23:21.290 に答える
0

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

于 2008-09-18T10:09:05.983 に答える
0

これがあなたの望むものかどうかわかりません

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
  }
}
于 2008-09-18T09:41:20.840 に答える
0

GameクラスがすべてのプレーヤーでTakeTurnを呼び出す代わりに、プレーヤーはGameクラスでTakeTurnを呼び出す必要があり、Gameクラスは正しいプレーヤーが自分の順番を取っているかどうかを検証する必要があります。

これは、ユーザーコンピュータプレーヤーの問題を解決するのに役立ちます。

于 2009-03-10T07:25:09.557 に答える