2009-08-16 5 views
1

私はしばしば、 "あなたが友人/内部が必要な場合はあなたのデザインが間違っています"といったようなことを言う人は、ChessPiece.Locationの内部を取り除くために次のコードを再設計する方法を教えてくれますか?友人や内臓を排除するのに役立ちます

これは現在、ChessBoardにピースを追加するとChessPiece.Locationプロパティが一致するように設定されているため、内部よりも悪化してプライベートにするとChessBoardが場所を更新できなくなります。どんな洞察にも感謝します。

public struct Coord 
{ 
    public Coord(int x, int y) { this.X = x; this.Y = y; } 
    public int X { get; private set; } 
    public int Y { get; private set; } 
} 

public class ChessBoard 
{ 
    public ChessBoard() { /*[...]*/ } 
    public ChessPiece this[int x, int y] 
    { 
     get 
     { 
      // Return ChessPiece at this position (or null) 
     } 
     set 
     { 
      // Add ChessPiece at this position and set its Location property 
     } 
} 

public class ChessPiece 
{ 
    public ChessPiece() { /*[...]*/ } 
    public Coord Location { get; internal set; } 
} 

答えて

2

私の最初の考えは

  • ボードになりちょうどコンテナ
  • 作品は、公共の読み取り専用 不変positionプロパティ
  • 初期位置は一片 建設
  • に設定されていています
  • ピース上で 移動操作を呼び出すことによって位置が変更されます
6

私は個人的にはチェスピースがその場所を知っていることは奇妙だと思います。それはチェスボードの機能のようであり、作品そのものではありません。 (チェスピースはどこの場所に置かれたのか、テーブルから外れていますか?通常はまだ有効なピースです...)

私はチェス盤に位置/運動ロジックを入れて、Dictionary<ChessPiece, Coord>各有効なチェスの場所。

0

私は、多くの場合、人々は、私はそれは愚かなことだと思う

「あなたは友人/内部が必要な場合は、あなたのデザインが間違っている」のようなものを言ってご覧ください。正当な理由で、友人と社内が言語で存在します。

は不可能ChessPiece.Locationを更新することになるだろうことChessPiece.Location

で内部を排除します。これはあなたができる「聞かないで教えてくれ」と呼ばれるオブジェクト指向の原則があります詳細については

public class ChessPiece 
{ 
    public ChessPiece() { /*[...]*/ } 
    public Coord Location { get; } 
    //a measure of how good it would be to move this piece 
    public int GoodnessOfBestMove 
    { 
    get 
    { 
     //calculate what self's best possible move is 
     ... todo ... 
    } 
    } 
    //an instruction to go head and do that move 
    public void Move() 
    { 
    //do self's self-calculated best move, by updating self's private Location 
    ... todo ... 
    } 
} 

class Strategy 
{ 
    void Move() 
    { 
     ChessPiece bestChessPiece = null; 
     foreach (ChessPiece chessPiece in chestPieces) 
     { 
     if ((bestChessPiece == null) || 
      (chessPiece.GoodnessOfBestMove > bestChessPiece.GoodnessOfBestMove)) 
     { 
      //found a better piece to move 
      bestChessPiece = chessPiece; 
     } 
     } 
     //found the best piece to move, so now tell it to move itself 
     bestChessPiece.Move(); 
    } 
} 

:ChessPieceは、例えば、自身の位置を更新し、ゲームについて十分に知っていたならばOKでしょう

Google for。

ボードが所有する2次元アレイに各ChessPieceを格納する可能性もあります。作品を移動するには、ボードはその作品をアレイの別のスロットに置きます。ピースがその位置を報告したいとき、それは配列の中でそれ自身を探します。

上記選択肢ですが、私は彼らが必ずしもこの問題ため良いまたはより良い解決策だとは言わないよ。私は、ゲーム戦略をエンコードしたいと思うしないでください各部分の実装の詳細。代わりに、他のクラスが各部分の場所を更新できるように非公開の方法があるかもしれません。

0

私はSteveと強く同意します。内部と友人は理由のために言語になっていますが、これは必ずしもその例ではありません。

個人的に私はその作品にMove(Coord)メソッドを入れました。そうすれば、自分の動きの妥当性を検証することができます(特殊なロジック、つまりポーンとナイトの派生クラスを使うこともできます)。座標は不変でなければなりません(座標は動かず、不変でなければならず、新しい座標に移動します)。

あなたは、あなたのコールクラスへの移動の妥当性をあなたの責任に移して、いつでもボード上にピースを置くことはできません。カスタムボードをセットアップする必要がある場合は、新しい開始位置を持つ新しいボードを作成します。

私は戦略アプローチについても同意しません。私は戦略パターンがここで良いことに同意するが、必ずしもその部分に組み込まれるべきではない。私はその戦略を個別の戦略クラスに移します。この方法であなたの作品とボードはシンプルでクリーンで、人対対人のゲームに使用でき、人対対CPUゲームにも拡張されます

関連する問題