Skip to main content

A board game in MVVM Part 1 - The Model

This is a continuation of my experience creating a quick board game in silverlight 5
Original Post
Play the Game

I planned on using MVVM so I began the process by breaking down the individual pieces into how they exist in the rules and how they are displayed. I came up with the following:

  • Square
  • Piece
  • Board
  • Game

The board is made up of squares and squares have pieces on them. The game manages the back-and-forth flow of the game. I knew I wanted an AI to be able to use the board, pieces and squares, but wanted it to use separate objects that could potentially reduce overhead so I started by creating interfaces for them defining the properties I knew would be needed. I'm going to use "Square" as a representation of how I went about doing this and why. Here's an example of the interface for Square:

  1. namespace Viking
  2. {
  3.     using System.Collections.Generic;
  4.  
  5.     public interface ISquare
  6.     {
  7.         ISquare Bottom { get; set; }
  8.  
  9.         int Col { get; set; }
  10.  
  11.         System.Windows.Point Coords { get; }
  12.  
  13.         bool IsOccupied { get; }
  14.  
  15.         bool IsRestricted { get; set; }
  16.  
  17.         bool IsStartPosition { get; set; }
  18.  
  19.         bool IsValidMove { get; set; }
  20.  
  21.         ISquare Left { get; set; }
  22.  
  23.         Dictionary<Viking.Square.NeighborDirection, ISquare> Neighbors { get; }
  24.  
  25.         IPiece Occupant { get; set; }
  26.  
  27.         ISquare Right { get; set; }
  28.  
  29.         int Row { get; set; }
  30.  
  31.         ISquare Top { get; set; }
  32.     }
  33. }

I might've made the Square a bit more complicated than it absolutely needs to be. However, what I can do with this is that the data allows squares to be accessed on 3 fronts:

  • Via direction (ie. "mySquare.Left")
  • Via index based on an enum (ie. "mySquare.Neighbors[Viking.Square.Direction.Left]" which is useful for limiting code duplication by being able to pass in a direction to a function)
  • By keeping track of row/column, a board can easily index its squares. "Coords" is for convenience and simply gets a Point(x,y) based on the Row/Col of the square

This should allow reading the code and traversing the squares easier. The other properties are things we want to be able to indicate on the View via Binding. None of these should call anything on the view. Instead, each of these are properties on the square that either the viewmodel can use in its logic, or the view can use to display things differently.

Here's the actual implementation of "Square":

  1. namespace Viking
  2. {
  3.     using System.Collections.Generic;
  4.     using System.Windows;
  5.  
  6.     public class Square : BasePropertyChanged, ISquare
  7.     {
  8.         private ISquare bottom;
  9.  
  10.         private int col;
  11.  
  12.         private bool isRestricted;
  13.  
  14.         private bool isStartPosition;
  15.  
  16.         private bool isValidMove;
  17.  
  18.         private ISquare left;
  19.  
  20.         private Dictionary<NeighborDirection, ISquare> neighbors;
  21.  
  22.         private IPiece occupant;
  23.  
  24.         private ISquare right;
  25.  
  26.         private int row;
  27.  
  28.         private ISquare top;
  29.  
  30.         public Square()
  31.         {
  32.             Neighbors = new Dictionary<NeighborDirection, ISquare>();
  33.             Neighbors.Add(NeighborDirection.Left, Left);
  34.             Neighbors.Add(NeighborDirection.Right, Right);
  35.             Neighbors.Add(NeighborDirection.Top, Top);
  36.             Neighbors.Add(NeighborDirection.Bottom, Bottom);
  37.         }
  38.  
  39.         public enum NeighborDirection
  40.         {
  41.             Left,
  42.  
  43.             Right,
  44.  
  45.             Top,
  46.  
  47.             Bottom
  48.         }
  49.  
  50.         public ISquare Bottom
  51.         {
  52.             get
  53.             {
  54.                 return this.bottom;
  55.             }
  56.  
  57.             set
  58.             {
  59.                 if (value != bottom)
  60.                 {
  61.                     bottom = value;
  62.                     RaisePropertyChanged(() => Bottom);
  63.                     Neighbors[NeighborDirection.Bottom] = value;
  64.                 }
  65.             }
  66.         }
  67.  
  68.         public int Col
  69.         {
  70.             get
  71.             {
  72.                 return this.col;
  73.             }
  74.  
  75.             set
  76.             {
  77.                 if (value != col)
  78.                 {
  79.                     col = value;
  80.                     RaisePropertyChanged(() => Col);
  81.                     RaisePropertyChanged(() => Coords);
  82.                 }
  83.             }
  84.         }
  85.  
  86.         public Point Coords
  87.         {
  88.             get
  89.             {
  90.                 return new Point(Row, Col);
  91.             }
  92.         }
  93.  
  94.         public bool IsOccupied
  95.         {
  96.             get
  97.             {
  98.                 return Occupant != null;
  99.             }
  100.         }
  101.  
  102.         public bool IsRestricted
  103.         {
  104.             get
  105.             {
  106.                 return this.isRestricted;
  107.             }
  108.  
  109.             set
  110.             {
  111.                 if (value != isRestricted)
  112.                 {
  113.                     isRestricted = value;
  114.                     RaisePropertyChanged(() => IsRestricted);
  115.                 }
  116.             }
  117.         }
  118.  
  119.         public bool IsStartPosition
  120.         {
  121.             get
  122.             {
  123.                 return this.isStartPosition;
  124.             }
  125.  
  126.             set
  127.             {
  128.                 if (value != isStartPosition)
  129.                 {
  130.                     isStartPosition = value;
  131.                     RaisePropertyChanged(() => IsStartPosition);
  132.                 }
  133.             }
  134.         }
  135.  
  136.         public bool IsValidMove
  137.         {
  138.             get
  139.             {
  140.                 return this.isValidMove;
  141.             }
  142.  
  143.             set
  144.             {
  145.                 if (value != isValidMove)
  146.                 {
  147.                     isValidMove = value;
  148.                     RaisePropertyChanged(() => IsValidMove);
  149.                 }
  150.             }
  151.         }
  152.  
  153.         public ISquare Left
  154.         {
  155.             get
  156.             {
  157.                 return this.left;
  158.             }
  159.  
  160.             set
  161.             {
  162.                 if (value != left)
  163.                 {
  164.                     left = value;
  165.                     RaisePropertyChanged(() => Left);
  166.                     Neighbors[NeighborDirection.Left] = value;
  167.                 }
  168.             }
  169.         }
  170.  
  171.         public Dictionary<NeighborDirection, ISquare> Neighbors
  172.         {
  173.             get
  174.             {
  175.                 return this.neighbors;
  176.             }
  177.  
  178.             private set
  179.             {
  180.                 if (value != neighbors)
  181.                 {
  182.                     neighbors = value;
  183.                     RaisePropertyChanged(() => Neighbors);
  184.                 }
  185.             }
  186.         }
  187.  
  188.         public IPiece Occupant
  189.         {
  190.             get
  191.             {
  192.                 return this.occupant;
  193.             }
  194.  
  195.             set
  196.             {
  197.                 if (value != occupant)
  198.                 {
  199.                     occupant = value;
  200.                     RaisePropertyChanged(() => Occupant);
  201.                     RaisePropertyChanged(() => IsOccupied);
  202.                 }
  203.             }
  204.         }
  205.  
  206.         public ISquare Right
  207.         {
  208.             get
  209.             {
  210.                 return this.right;
  211.             }
  212.  
  213.             set
  214.             {
  215.                 if (value != right)
  216.                 {
  217.                     right = value;
  218.                     RaisePropertyChanged(() => Right);
  219.                     Neighbors[NeighborDirection.Right] = value;
  220.                 }
  221.             }
  222.         }
  223.  
  224.         public int Row
  225.         {
  226.             get
  227.             {
  228.                 return this.row;
  229.             }
  230.  
  231.             set
  232.             {
  233.                 if (value != row)
  234.                 {
  235.                     row = value;
  236.                     RaisePropertyChanged(() => Row);
  237.                     RaisePropertyChanged(() => Coords);
  238.                 }
  239.             }
  240.         }
  241.  
  242.         public ISquare Top
  243.         {
  244.             get
  245.             {
  246.                 return this.top;
  247.             }
  248.  
  249.             set
  250.             {
  251.                 if (value != top)
  252.                 {
  253.                     top = value;
  254.                     RaisePropertyChanged(() => Top);
  255.                     Neighbors[NeighborDirection.Top] = value;
  256.                 }
  257.             }
  258.         }
  259.     }
  260. }

And here's the AI version that doesn't have the same overhead that this version does in notifying of property changes and such:

  1. namespace Viking
  2. {
  3.     using System.Collections.Generic;
  4.     using System.Windows;
  5.  
  6.     public class DecisionSquare : ISquare
  7.     {
  8.         private ISquare bottom;
  9.  
  10.         private ISquare left;
  11.  
  12.         private ISquare right;
  13.  
  14.         private ISquare top;
  15.  
  16.         public DecisionSquare()
  17.         {
  18.             Neighbors = new Dictionary<Square.NeighborDirection, ISquare>();
  19.             Neighbors.Add(Square.NeighborDirection.Left, Left);
  20.             Neighbors.Add(Square.NeighborDirection.Right, Right);
  21.             Neighbors.Add(Square.NeighborDirection.Top, Top);
  22.             Neighbors.Add(Square.NeighborDirection.Bottom, Bottom);
  23.         }
  24.  
  25.         public ISquare Bottom
  26.         {
  27.             get
  28.             {
  29.                 return bottom;
  30.             }
  31.  
  32.             set
  33.             {
  34.                 bottom = value;
  35.                 Neighbors[Square.NeighborDirection.Bottom] = bottom;
  36.             }
  37.         }
  38.  
  39.         public int Col { get; set; }
  40.  
  41.         public Point Coords
  42.         {
  43.             get
  44.             {
  45.                 return new Point(Row, Col);
  46.             }
  47.         }
  48.  
  49.         public bool IsOccupied
  50.         {
  51.             get
  52.             {
  53.                 return Occupant != null;
  54.             }
  55.         }
  56.  
  57.         public bool IsRestricted { get; set; }
  58.  
  59.         public bool IsStartPosition { get; set; }
  60.  
  61.         public bool IsValidMove { get; set; }
  62.  
  63.         public ISquare Left
  64.         {
  65.             get
  66.             {
  67.                 return left;
  68.             }
  69.  
  70.             set
  71.             {
  72.                 left = value;
  73.                 Neighbors[Square.NeighborDirection.Left] = left;
  74.             }
  75.         }
  76.  
  77.         public Dictionary<Square.NeighborDirection, ISquare> Neighbors { get; set; }
  78.  
  79.         public IPiece Occupant { get; set; }
  80.  
  81.         public ISquare Right
  82.         {
  83.             get
  84.             {
  85.                 return right;
  86.             }
  87.  
  88.             set
  89.             {
  90.                 right = value;
  91.                 Neighbors[Square.NeighborDirection.Right] = right;
  92.             }
  93.         }
  94.  
  95.         public int Row { get; set; }
  96.  
  97.         public ISquare Top
  98.         {
  99.             get
  100.             {
  101.                 return top;
  102.             }
  103.  
  104.             set
  105.             {
  106.                 top = value;
  107.                 Neighbors[Square.NeighborDirection.Top] = top;
  108.             }
  109.         }
  110.     }
  111. }

I've also attached the source for the rest of the "Model". I will be releasing portions of the code in subsequent posts and will release the final source in the last post.

AttachmentSize
Viking Model Source10.74 KB

Comments

MVVM Part 1

It is really good game to play, which is programmed well. I have also read the reviews from the best essays and all are giving best rating for this game. I really appreciate you for programming this game.

"The Model View ViewModel

"The Model View ViewModel (MVVM) is a building design utilized as a part of programming building that started from Microsoft as a specialization of the Presentation Model plan design Write My Essay For Me presented by Martin Fowler. To a great extent in view of the model–view–controller design (MVC)"

Alternate properties are

Alternate properties are things we need to have the capacity to demonstrate on the View by means of Binding. None of these ought to call anything on the view. Oblivion Tom Cruise Jacket Buymoviejackets

Fileviewpro

You are a great writer and give us much information. fileviewpro

Iperius Backup

Your post so inspirative and good point. Thanks, great post. I really like your point of view! Iperius Backup

ulead videostudio

Well thanks for posting such an outstanding site. I like this blog & I like the topic and thinking of making it right. ulead videostudio

Wondershare MobileTrans

Brilliantly composed article, if just all bloggers offered the same substance as you, the web would be a far superior spot. Wondershare MobileTrans

imagenomic portraiture serial number

Nice post.I am more than ever impressed through your approach of look in this blog. It shows your visualization. imagenomic portraiture serial number

hotspot shield elite serial key

Really good work by the blog writer! such informative article keep sharing more articles. hotspot shield elite serial key

I would like to say that this

I would like to say that this blog really convinced me to do it! Thanks, very good post. low price to fix your teeth

Sleemalax

Wow what a Great Information about World Day its very nice informative post. thanks for the post. learn more

DeskSoft BWMeter full version

Very easy to understand the material! Thanks to the author!

blackmart

Blackmart APK Download is the best application market which is very simple to use and has got many great features

Headshots Sydney

You have some real writing talent. Thank you. Headshots Sydney

Bullet Force is a fast-paced

Bullet Force is a fast-paced modern multiplayer FPS. It offers you ultimate features. This is a very fast multi player experience for you. You can have 20 team players through this and even use the ultimate weapons to kill the enemies. There are 20 different weapons which you can use to play. aptoide ios

Hunting

Great! It sounds good. Thanks for sharing.

linkedin photos sydney

Thanks for this useful article, waiting for this article like this again. linkedin photos sydney

portrait photographer sydney

I really appreciate the kind of topics you post here. Thanks for sharing us a great information that is actually helpful. portrait photographer sydney

Grain Stark proceeds with his

Grain Stark proceeds with his preparation under the Three-Eyed Raven at the tree. He is demonstrated a scene from Winterfell, watching his dad and uncle Benjen preparing in the yard as young men.  game of thrones season 7 episode 2 review

It is difficult to create the

It is difficult to create the code for games. And some of them won’t show the code to the public due to the duplication of the content. Here you have shared the code and so that people can understand the code and even possible to create changes in the game. Babylon City Tours

IP address 192.168.0.1 is the

IP address 192.168.0.1 is the management ip address of some wireless router,it is the default ip address for all kinds of TP-link,D-Link and Netgear models. 192.168..0.1 

bego live

bego live is the best apk that you can download for free. This Article is all About Bigo Live Apk

Unshackle galleries

Sexy pctures
http://asses.sexblog.pw/?marlene
erotic sculptures sexy women erotic guru arabic erotic erotic museum

Great Post

Very nice, thanks for sharing to us Enjoyed every bit of your blog.Really looking forward to read more
Razer Surround Pro

Auslogics Boostspeed 8 Serial Key

Universal Adobe Patcher By Painter

Iobit Uninstaller 6 Key

CCleaner Crack

Fallout 4 Black Box

Reimage Repair License Key

Wonderful work!

I like the way you have presented the article here briefly. Windows 7 loader

Fantastic Article

Nice post! Thanks a lot for the kind of perfect topic.I like your post. Thanks for sharingHitman Pro 3.7.14 Product Key

Great Tips. I Have to Thanks

Great Tips. I Have to Thanks To You to Share It Many points have extremely useful mc hjälmar

Great post

Great post! I am actually getting ready to across this information, is very helpful my friend. Also great blog here with all of the valuable information you have. Keep up the good work you are doing here.
nba 2k17 download
ios emulators for pc

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <asp>, <c>, <cpp>, <cs>, <css>, <drupal5>, <drupal6>, <html4strict>, <java>, <javascript>, <jquery>, <php>, <python>, <ruby>, <sql>, <xml>. The supported tag styles are: <foo>, [foo]. PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.