I've been given a university assignment whereby I have to develop a chess game in C# WinForms and it has been recommended that we follow the Model-View-Controller design pattern. I'm struggling to identify what code should go where, so I'm hoping for a bit of advice and a general critique of my design. For those brave enough to attempt traversing my spaghetti code, here's the full project. For everyone else, here's a description of what I've come up with so far:
Model layer:
Piece
- Represents a single chess piece. Has derived classesKing
,Queen
,Rook
, etc. that override virtual methods to define movement behaviour for each piece type.Player
- A small utility class that doesn't do much besides storing each player's pieces in aList<Piece>
object and performing global operations on them that a single piece can't (or shouldn't) perform on its own, such as testing for check, clearing en passant and castle moves, etc.
View layer:
frmChess
- The main form of the application. OverridesWndProc
to keep the form's 1:1 aspect ratio when the user resizes it, but is otherwise just a normal form.Board
- A simple derivation of a standard WinFormsTableLayoutPanel
that I've edited in the Visual Studio designer to have 8 columns and rows. A single instance of this class sits on the main form and really doesn't do anything besides simplifying the alignment and presentation of the squares.
Controller layer:
Game
- A static class that stores the 64Square
s (see below) in aList<Square>
object, and has various methods that allow getting the square at a given (x, y) coordinate, saving/loading the game state to/from a binary file and detecting checkmate.
Unsure:
Square
- Another simple derivation of a standard WinForms control, namelyPanel
. 64 of these have been added to theBoard
at design time and each one is either empty, or holds a singlePiece
instance at any given time. That piece also holds a circular reference to its square, which I'd like to change since it seems like squares belong in the view layer, and the model should know nothing of the view. I've also overriden the square'sOnPaint
method to draw its contained piece's image on its foreground, and have an event handler in the main form hooked up to every square's Click event so that pieces can be selected and moved. I can think of lots of other things to do from here as well, such as determining other squares that can be attacked from, or are attacking, this square. So that makes me think that maybe it should be part of the model after all...any thoughts?PieceMove
- This class handles the doing and undoing of moves when testing for check, and also allows testing whether a move will cause check for the moving piece's team, making that move invalid. I really don't know whether this should be considered as part of the model, or a move controller. Also on that note, should I have a separate move controller, view controller, etc. or just one controller class that does all of that?
Lastly, I know this post is getting way too long so I apologise for that, but I'd like to implement an event-driven method of notifying the view of the model's changes, e.g. select a piece, move a piece, team is in check, team is in checkmate, etc. How would I go about that?
Thank you all in advance for taking the time to read this and/or my code; I really appreciate it! :D