【问题标题】:What pattern do I use for interdependent class我对相互依赖的类使用什么模式
【发布时间】:2019-06-06 12:49:38
【问题描述】:

我从其他来源了解到,对象相互了解并不是一个好主意,尤其是同一级别的对象。它应该更像层次结构。

我的问题非常独特,因为我还没有找到解决方法。此外,我很不幸遇到任何专门解决我的问题的主题。

问题 我正在构建一个国际象棋应用程序,并且正在构建该应用程序的模型。现在我有一个抽象对象,例如Piece,其他部分如QueenKnight 和其余部分将继承自。 我还有一个Board 类,它处理所有棋盘模型和游戏状态。现在我的每一件作品都有一个generateMove() 方法来计算从他们的位置可能的移动,为此他们需要知道棋盘的状态。此外,Board 在启动时也会对 Pieces 进行实例化。

问题 我是否继续通过例如实例化 Pieces

public class ChessBoard{
   Boardbit = 64bit
   Knight = new Knight(start_position, this) 

  //calculate

}

然后在 Knight 类方法中

public long generateMove(ChessBoard);

如果没有,我还有什么其他方法可以解决?

【问题讨论】:

    标签: oop design-patterns chess


    【解决方案1】:

    Chessboard 知道Knight 反之亦然并不优雅。在这一点上我同意你的看法。坚持“告诉不要问”规则会强制“更高级别”元素(在本例中为棋盘)告诉棋子移动,同时提供所有必需的信息。 Chessboard 本身不知道哪个棋子正在移动(在这种情况下,预测所有棋子的可能移动),但肯定永远不知道关于棋子如何移动或被允许移动的任何细节。这只是使用某种策略模式的一种可能解决方案。 (这里也可以使用访问者或一些类似的模式):

    Main() {
        chessboard = new Chessboard()
        PiecesCollection = new PiecesCollection(new Knight(KnightStrategy, Color.Black))
        chessboard.AddPieces(PiecesCollection)
    
        CollectionOfAllPossibleMoveCollections = chessBoard.CallculateAllPossibleMoves()
    
        Move selectedMove = ShowOrSelectMove(CollectionOfAllPossibleMoveCollections)
        chessboard.ExecuteMove(selectedMove)
    }
    
    public class Chessboard{
       // fields
       PiecesCollectionWhite
       // where 'PiecesCollectionWhite' is a collection of `Piece`
    
       PiecesCollectionBlack
       // where 'PiecesCollectionBlack' is a collection of `Piece`
    
       CurrentlyVisitedPositionsCollection
       // where 'CurrentlyVisitedPositionsCollection' is a collection of `Position`
    
       // methods
       AddPieces(PiecesCollection, Color)
    
       CallculateAllPossibleMoves(Color) {
         CollectionOfPossibleMoveCollections = 
             FOREACH Piece IN PiecesCollection OF Color
                 DO Piece.CalculateMoves(this.CurrentlyVisitedPositionsCollection)
         return CollectionOfAllPossibleMoveCollections // where 'CollectionOfAllPossibleMoveCollections ' is a collection that holds a collection of `Move` of which each nested collection represents the possible moves of a chess piece.
       }
    
       ExecuteMove(Move) {
           RemovePieceFromBoardIfNecessary(Move.ToPosition)
       }
    } 
    
    public class Piece 
    {
       // fields
       Strategy
       Position
       Color
    
       // methods
       CallculateMoves(CurrentlyVisitedPositionsCollection) {
           PossibleMovesCollection = this.Strategy.Execute(CurrentlyVisitedPositionsCollection, this.Position)
           return PossibleMovesCollection where `PossibleMovesCollection` is a collection of `Move`
       }
    }
    
    public class Knight extends Piece
    {
       ctor(Strategy, Color)
    }
    
    public class Stragtegy
    {
      abstract Execute(currentPosition, allPiecesPositions) : PossibleMovesCollection 
    }
    
    public class KnightStrategy extends Strategy
    {
      Execute(currentPosition, allPiecesPositions) {
          PossibleMovesCollection = ApplyKnightMoveAlgorithm()
          return PossibleMovesCollection 
      }
    
      private ApplyKnightMoveAlgorithm() : PossibleMovesCollection 
    }
    
    public class Move
    {
      Position fromPosition
      Position toPosition
    }
    
    public class Color
    {
      Black
      White
    }
    
    public class Position
    {
      Color
      xCoordinate
      yCoordinate
    }
    

    这只是一个草图而不是一个完整的例子。缺少一些状态信息或操作。例如。也许您必须存储在棋盘上最后移动的Color

    由于Chessboard 返回所有可能的移动(有关所有当前访问的坐标的信息),您可以通过实施一些智能来轻松地增强算法,以根据该信息预测最佳可能移动。所以在控制器之前或者在这种情况下Main() 将调用Chessboard.ExecuteMove(Move) 它可以调用PredictionEngine.PredictBestMove(CollectionOfAllPossibleMoveCollections)

    【讨论】:

    • 感谢您的回复,您生成所有可能的移动功能似乎很有见地,但如您所知,我想问一下 this.currentlyVisitedPositionsCollection 类型是什么。
    • 这很重要,因为如果棋盘上有支票,也需要进行有效的移动。将信息包括在内。
    • 还需要相同颜色的位表示,这样棋子就不会跳到自己的方格上。
    • 我想说的是棋盘存储了所有棋子的坐标。 ChessBoard然后将此信息传递给策略算法,以便Strategy可以知道自己或对手颜色访问了哪些字段。
    • 是的,你是对的。我知道。这是您必须在例如KnightStrategy 班级。就像检查您的 ow 是否访问了该字段。所以是的,在实际实施此建议时,您必须将 Colorattribute 添加到 Position
    【解决方案2】:

    最好有方法generateMove(boardState),所以你的董事会应该调用你拥有的任何部分,并传递给他们完成这项任务的必要信息。它甚至可以用于一些优化,因为板子每轮只能预生成一些好用的结构,然后将其传递给所有部分(如一些二维数组)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-26
      • 2013-05-29
      • 2011-01-25
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      相关资源
      最近更新 更多