重构c#象棋游戏以遵循MVC设计模式

本文关键字:MVC 设计模式 游戏 重构 | 更新日期: 2023-09-27 18:13:37

我接到了一份大学作业,我必须用c# WinForms开发一个国际象棋游戏,建议我们遵循模型-视图-控制器的设计模式。我正在努力确定哪些代码应该放在哪里,所以我希望能得到一些建议和对我的设计的一般性批评。对于那些有足够勇气尝试遍历我的面条式代码的人,这里是完整的项目。对于其他人,这里是我目前为止想到的描述:

层:

  • Piece -表示单个棋子。已经派生类King, Queen, Rook等,覆盖虚拟方法来定义每个块类型的移动行为。
  • Player -一个小的实用程序类,除了在List<Piece>对象中存储每个玩家的棋子并对它们执行单个棋子不能(或不应该)自己执行的全局操作之外,没有做太多的事情,例如测试检查,清除过路和城堡移动等。
<

视图/strong>层:

  • frmChess -应用程序的主要形式。当用户调整表单大小时,覆盖WndProc以保持表单的1:1长宽比,但除此之外只是一个普通表单。
  • Board -一个标准的WinForms TableLayoutPanel的简单派生,我在Visual Studio设计器中编辑了8列和8行。该类的一个实例位于主窗体上,除了简化正方形的对齐和表示之外,它实际上不做任何事情
控制器

层:

  • Game -一个静态类,将64个Square s(见下)存储在List<Square>对象中,并具有各种方法,允许在给定(x, y)坐标处获取正方形,将游戏状态保存/加载到二进制文件中,并检测将死。

确定:

  • Square -另一个标准WinForms控件的简单派生,即Panel。其中64个在设计时被添加到Board中,每个都是空的,或者在任何给定的时间保存一个单独的Piece实例。那块还持有一个圆形引用到它的正方形,我想改变,因为它看起来像正方形属于视图层,模型应该不知道视图。我还重写了正方形的OnPaint方法,以便在其前景上绘制其包含的块的图像,并在主窗体中添加了一个事件处理程序,连接到每个正方形的Click事件,以便可以选择和移动块。我还可以从这里想到很多其他的事情,比如确定其他可以被攻击的方块,或者正在攻击这个方块。所以这让我觉得也许它应该毕竟是模型的一部分…任何想法吗?

  • PieceMove -这个类在测试检查时处理移动的做和撤消,并且还允许测试一个移动是否会导致移动的团队检查,使该移动无效。我真的不知道这是否应该被视为模型的一部分,还是移动控制器。另外,我应该有一个单独的移动控制器,视图控制器等等还是一个控制器类来完成所有这些?

最后,我知道这篇文章太长了,所以我很抱歉,但是我想实现一个事件驱动的方法来通知模型更改的视图,例如选择一个棋子,移动一个棋子,团队在检查中,团队在检查中,等等。我该怎么做呢?

提前感谢大家花时间阅读这篇文章和/或我的代码;我真的很感激!: D

重构c#象棋游戏以遵循MVC设计模式

我认为你已经有了一个良好的开端,所有的核心概念都有了清晰的定义。

我将稍微不同地分解模型:

模型
  • Board -包含单板上棋子的当前状态。
    • 属性: [List<PieceState> Pieces]
    • 方法: void PlacePiece(Piece, Square) , void MovePiece(FromSquare, ToSquare) , void RemovePiece(Square)
  • : [Type] , [Colour]
  • Square -表示单板上的一个正方形。
    • 属性: [Coordinates]
  • PieceState : [Piece], [IsActive] , [Square]
  • MoveValidator -确保一个片段可以执行所需的移动。
      方法: bool MoveIsValid(Piece, FromSquare, ToSquare)
  • GameState -描述游戏的整体状态。
    • 价值观: InPlay , CheckMate , StaleMate ,等。
  • Player:代表一个玩家。
    • 属性: [Colour] , [List<Piece> Pieces]
  • GameLogic -将利用 MoveValidator ,以及包含逻辑,以确保棋子保持在棋盘边界内,一个方块只包含一个棋子。该类还将包含确定当前 GameState 的逻辑。
    • 属性: Board
    • Has: MoveValidator
    • 方法: void SetupBoard(Board) , bool CheckMoveIsValid(Piece, FromSquare, ToSquare) , GameState GetGameState()
<

视图/h3>

这是程序中处理渲染的部分。

把你的模型想象成包含游戏的所有逻辑和状态,把视图层想象成"绘制"的逻辑。它在屏幕上。

就任何设计模式而言,技术实现都不太重要。 重要的是保持内容松散耦合,并确保将内容分组到正确的区域。

视图的主要功能有:

  1. 渲染板
  2. 用正确的图标和颜色渲染棋盘上的棋子。
  3. 显示相关游戏统计数据、得分、活动棋子、游戏时间等
控制器

控制器提供模型、视图和用户交互之间的管道。它"glues"在一起上课。

控制器需要利用和协调游戏类。职责如下:

  1. 设置一个新板,然后将其传递回视图进行渲染。
  2. 接收用户输入,验证它,然后相应地更新板。将更新视图传回渲染。
  3. 如果玩家赢了,或者达到了一个过时的伴侣(由 GameState 决定),停止游戏。

这还远远不够详尽,但它应该提供一些思考的食物。

在这里查看更多关于MVC结构的信息

您可能希望查看的其他模式是MVVM(模型视图-视图-模型)和MVP(模型视图呈现者)。在我看来MVP是WinForms应用程序的最佳选择。

最后,没有正确的方法可以做到这一点!遵循良好的设计实践(但不要武断地), 保持松散耦合,您应该最终得到无面条代码