Advertisement
AceInfinity

Reversi Game

Feb 21st, 2013
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 19.74 KB | None | 0 0
  1. // Developed by AceInfinity (c) Tech.Reboot.Pro 2013
  2. // Reversi Game
  3. //
  4. // OBJECTIVE:
  5. // The objective of this game is to own more pieces than your opponent by the time the game is finished.
  6. // The game is over when the board is fully filled in, or neither player can make a move.
  7.  
  8. // RULES:
  9. // Each reversi piece has a red side and a blue side. Player1 will be red, and Player2 will be blue here.
  10. // You must place the piece so that an opponent's piece is sandwiched between 2 of your pieces including the
  11. // piece you just played for that turn. All of the opponent's pieces between that newly placed piece and the
  12. // pre-existing piece of your own, become your own pieces and change to your Player's color.
  13. //
  14. // You can only place a piece on an empty tile. If you cannot make a legal move, you have to pass your turn,
  15. // and allow your opponent to make a move instead. You can capture vertical, horizontal, and diagonal paths of pieces.
  16. // You can also, capture more than one path of your opponents pieces at once with a good move.
  17.  
  18. using System;
  19. using System.ComponentModel;
  20. using System.Collections.Generic;
  21. using System.Drawing;
  22. using System.Drawing.Drawing2D;
  23. using System.Windows.Forms;
  24.  
  25. namespace Reversi
  26. {
  27.     class ReversiBoard : PictureBox
  28.     {
  29.         #region // Constructors
  30.         public ReversiBoard() : this(new ReversiLayout(8, 8)) { }
  31.  
  32.         public ReversiBoard(ReversiLayout layout)
  33.         {
  34.             _layout = layout;
  35.  
  36.             // Default Initialization
  37.             _borderColor = Color.FromArgb(255, 50, 50, 50);
  38.             _tileColor = Color.FromArgb(255, 25, 25, 25);
  39.  
  40.             _player1Color = Color.FromArgb(255, 255, 25, 25); // Red
  41.             _player2Color = Color.FromArgb(255, 25, 150, 255); // Blue
  42.  
  43.             _markers = new ReversiPlayer[_layout.Columns, _layout.Rows];
  44.  
  45.             this.Size = new Size(_layout.Columns * _tileSize, _layout.Rows * _tileSize + _paddingBottom);
  46.             _faintCollection.ListChanged += new ListChangedEventHandler((sender, e) => this.Invalidate());
  47.             NewGame();
  48.         }
  49.         #endregion
  50.  
  51.         #region // Fields & Properties
  52.         private ReversiLayout _layout; // Stores board layout information
  53.         private Coordinates _lastCoordinates; // Keeps track of last coordinate for efficient checking
  54.         private const int _tileSize = 25; // Constant tile size for game board
  55.         private const int _paddingBottom = 15; // Constant for extra information at bottom (score)
  56.         private ReversiPlayer[,] _markers; // Player markers for game board
  57.         private BindingList<Marker> _faintCollection = new BindingList<Marker>(); // For hover image on valid locations
  58.  
  59.         private ReversiPlayer _currentPlayer = ReversiPlayer.Player1; // Current player to take his/her turn
  60.         private Coordinates _targetCoordinates; // Represents the target coordinate for the flips
  61.         private int _player1MarkerCount; // Represents the target coordinate for the flips
  62.         private int _player2MarkerCount; // Represents the target coordinate for the flips
  63.  
  64.         /// <summary>
  65.         /// Game tiles border color.
  66.         /// </summary>
  67.         private Color _borderColor;
  68.         public Color BorderColor
  69.         {
  70.             get { return _borderColor; }
  71.             set { _borderColor = value; }
  72.         }
  73.  
  74.         /// <summary>
  75.         /// Game tiles back color.
  76.         /// </summary>
  77.         private Color _tileColor;
  78.         public Color TileColor
  79.         {
  80.             get { return _tileColor; }
  81.             set { _tileColor = value; }
  82.         }
  83.  
  84.         /// <summary>
  85.         /// Player1's marker color.
  86.         /// </summary>
  87.         private Color _player1Color;
  88.         public Color Player1Color
  89.         {
  90.             get { return _player1Color; }
  91.             set { _player1Color = value; }
  92.         }
  93.  
  94.         /// <summary>
  95.         /// Player2's marker color.
  96.         /// </summary>
  97.         private Color _player2Color;
  98.         public Color Player2Color
  99.         {
  100.             get { return _player2Color; }
  101.             set { _player2Color = value; }
  102.         }
  103.        
  104.         public bool GameFinished
  105.         {
  106.             get
  107.             {
  108.                 bool boardComplete = true;
  109.                 for (int i = 0; i < _layout.Columns; i++)
  110.                 {
  111.                     for (int j = 0; j < _layout.Rows; j++)
  112.                     {
  113.                         if (_markers[i, j] == ReversiPlayer.None)
  114.                         {
  115.                             goto BoardNotComplete;
  116.                         }
  117.                     }
  118.                 }
  119.                 if (boardComplete)
  120.                 {
  121.                     return true;
  122.                 }
  123.             BoardNotComplete:
  124.                 // Board was found incomplete so let's check if any moves can still be made
  125.                 //...
  126.  
  127.                 return false;
  128.             }
  129.         }
  130.         #endregion
  131.  
  132.         #region // Overrides
  133.         /// <summary>
  134.         /// Paints the board visual with all the player markers and current player indicator.
  135.         /// </summary>
  136.         /// <param name="pe">PaintEventArgs.</param>
  137.         protected override void OnPaint(PaintEventArgs pe)
  138.         {
  139.             base.OnPaint(pe);
  140.  
  141.             Graphics g = pe.Graphics;
  142.             g.SmoothingMode = SmoothingMode.AntiAlias;
  143.  
  144.             // Paint the grid
  145.             SolidBrush sb = new SolidBrush(_borderColor);
  146.             Pen p = new Pen(sb);
  147.  
  148.             HatchBrush hb1 = new HatchBrush(HatchStyle.SmallCheckerBoard, _tileColor);
  149.             HatchBrush hb2 = new HatchBrush(HatchStyle.SmallCheckerBoard, Color.FromArgb(245, _tileColor));
  150.  
  151.             int x = 0;
  152.             bool evenRows = _layout.Rows % 2 == 0;
  153.  
  154.             for (int i = 0; i < _layout.Columns; i++)
  155.             {
  156.                 for (int j = 0; j < _layout.Rows; j++, x++)
  157.                 {
  158.                     Rectangle rect = new Rectangle(i * _tileSize, j * _tileSize, _tileSize, _tileSize);
  159.                     g.FillRectangle(x % 2 == 0 ? hb1 : hb2, rect);
  160.                     g.DrawRectangle(p, rect);
  161.                 }
  162.  
  163.                 if (evenRows)
  164.                 {
  165.                     x++;
  166.                 }
  167.             }
  168.  
  169.             hb1.Dispose();
  170.             hb2.Dispose();
  171.  
  172.             // Paint Markers
  173.             sb.Color = _player1Color;
  174.             p.Color = sb.Color;
  175.  
  176.             for (int i = 0; i <= _markers.GetUpperBound(0); i++)
  177.             {
  178.                 for (int j = 0; j <= _markers.GetUpperBound(1); j++)
  179.                 {
  180.                     if (_markers[i, j] != ReversiPlayer.None)
  181.                     {
  182.                         Color color = _markers[i, j] == ReversiPlayer.Player1 ? _player1Color : _player2Color;
  183.                         p.Color = color;
  184.                         Rectangle rect = new Rectangle(i * _tileSize + 1, j * _tileSize + 1, _tileSize - 2, _tileSize - 2);
  185.                         g.DrawEllipse(p, rect);
  186.  
  187.                         sb.Color = Color.FromArgb(100, color);
  188.                         g.FillEllipse(sb, rect);
  189.                     }
  190.                 }
  191.             }
  192.  
  193.             foreach (Marker m in _faintCollection)
  194.             {
  195.                 Color color = Color.FromArgb(50, m.Player == ReversiPlayer.Player1 ? _player1Color : _player2Color);
  196.                 p.Color = color;
  197.                 Rectangle rect = new Rectangle(m.TileCoordinates.X * _tileSize + 1, m.TileCoordinates.Y * _tileSize + 1, _tileSize - 2, _tileSize - 2);
  198.                 g.DrawEllipse(p, rect);
  199.  
  200.                 sb.Color = Color.FromArgb(25, color);
  201.                 g.FillEllipse(sb, rect);
  202.             }
  203.  
  204.             p.Dispose();
  205.  
  206.             // Paint current player indicator
  207.             using (Font font = new Font("Arial", 7.5f, FontStyle.Regular))
  208.             {
  209.                 sb.Color = Color.FromArgb(200, 255, 255, 255);
  210.                 g.DrawString(string.Format("{0}'s Turn", _currentPlayer), font, sb, new PointF(2, 2));
  211.                 sb.Color = Color.Black;
  212.                 g.DrawString(string.Format("Player1: {0} | Player2: {1}", _player1MarkerCount, _player2MarkerCount), font, sb, new PointF(2, this.Height - 14));
  213.             }
  214.  
  215.             sb.Dispose();
  216.         }
  217.  
  218.         /// <summary>
  219.         /// Makes sure that we cannot resize the board once it has been initialized.
  220.         /// </summary>
  221.         /// <param name="e">EventArgs.</param>
  222.         protected override void OnResize(EventArgs e)
  223.         {
  224.             base.OnResize(e);
  225.             this.Size = new Size(_layout.Columns * _tileSize, _layout.Rows * _tileSize + _paddingBottom);
  226.         }
  227.  
  228.         /// <summary>
  229.         /// For clicking on the game board and adding a marker to a location on the grid.
  230.         /// </summary>
  231.         /// <param name="e">MouseEventArgs.</param>
  232.         protected override void OnMouseUp(MouseEventArgs e)
  233.         {
  234.             base.OnMouseUp(e);
  235.             // Check release boundaries
  236.             Coordinates coordinates = new Coordinates(e.X / _tileSize, e.Y / _tileSize);
  237.             if (IsValidLocation(coordinates))
  238.             {
  239.                 _markers[coordinates.X, coordinates.Y] = _currentPlayer;
  240.                 FlipOpponentMarkers(coordinates);
  241.                 _faintCollection.Clear();
  242.                 UpdateMarkerCount();
  243.  
  244.                 if (GameFinished)
  245.                 {
  246.                     GameOver();
  247.                 }
  248.             }
  249.         }
  250.  
  251.         /// <summary>
  252.         /// Calculates move validity and shows faint marker indicator for valid tiles
  253.         /// to place markers on.
  254.         /// </summary>
  255.         /// <param name="e">MouseEventArgs.</param>
  256.         protected override void OnMouseMove(MouseEventArgs e)
  257.         {
  258.             base.OnMouseMove(e);
  259.             if (e.Button == MouseButtons.None)
  260.             {
  261.                 Coordinates coordinates = new Coordinates(e.X / _tileSize, e.Y / _tileSize);
  262.                 if (!_lastCoordinates.Equals(coordinates))
  263.                 {
  264.                     if (IsValidLocation(coordinates))
  265.                     {
  266.                         _faintCollection.Add(new Marker(_currentPlayer, coordinates));
  267.                         if (_faintCollection.Count > 1)
  268.                         {
  269.                             _faintCollection.RemoveAt(0);
  270.                         }
  271.                     }
  272.                     _lastCoordinates = coordinates;
  273.                 }
  274.             }
  275.         }
  276.  
  277.         /// <summary>
  278.         /// Gets rid of the faint marker indicator if mouse leaves the control.
  279.         /// </summary>
  280.         /// <param name="e">EventArgs.</param>
  281.         protected override void OnMouseLeave(EventArgs e)
  282.         {
  283.             base.OnMouseLeave(e);
  284.             _faintCollection.Clear();
  285.         }
  286.         #endregion
  287.  
  288.         #region // Methods
  289.         /// <summary>
  290.         /// Initialize and start a new game.
  291.         /// </summary>
  292.         private void NewGame()
  293.         {
  294.             for (int i = 0; i <= _markers.GetUpperBound(0); i++)
  295.             {
  296.                 for (int j = 0; j <= _markers.GetUpperBound(1); j++)
  297.                 {
  298.                     _markers[i, j] = ReversiPlayer.None;
  299.                 }
  300.             }
  301.  
  302.             int xPos = _markers.GetUpperBound(0) / 2;
  303.             int yPos = _markers.GetUpperBound(1) / 2;
  304.  
  305.             _markers[xPos++, yPos] = ReversiPlayer.Player1;
  306.             _markers[xPos, yPos++] = ReversiPlayer.Player2;
  307.             _markers[xPos--, yPos] = ReversiPlayer.Player1;
  308.             _markers[xPos, yPos] = ReversiPlayer.Player2;
  309.             this.Invalidate();
  310.         }
  311.  
  312.         /// <summary>
  313.         /// Game was finished: Display winner and reset the game.
  314.         /// </summary>
  315.         private void GameOver()
  316.         {
  317.             string msg = string.Empty;
  318.             if (_player1MarkerCount > _player2MarkerCount)
  319.             {
  320.                 msg = string.Format("Player1 won with {0} markers!", _player1MarkerCount);
  321.             }
  322.             else
  323.             {
  324.                 msg = string.Format("Player2 won with {0} markers!", _player2MarkerCount);
  325.             }
  326.             MessageBox.Show(msg, "Game Over", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
  327.             NewGame();
  328.         }
  329.  
  330.         /// <summary>
  331.         /// Updates the marker count for both players.
  332.         /// </summary>
  333.         private void UpdateMarkerCount()
  334.         {
  335.             _player1MarkerCount = _player2MarkerCount = 0;
  336.             for (int i = 0; i <= _markers.GetUpperBound(0); i++)
  337.             {
  338.                 for (int j = 0; j <= _markers.GetUpperBound(1); j++)
  339.                 {
  340.                     if (_markers[i, j] == ReversiPlayer.Player1)
  341.                     {
  342.                         _player1MarkerCount++;
  343.                     }
  344.                     else if (_markers[i, j] == ReversiPlayer.Player2)
  345.                     {
  346.                         _player2MarkerCount++;
  347.                     }
  348.                 }
  349.             }
  350.             this.Invalidate();
  351.         }
  352.  
  353.         /// <summary>
  354.         /// Determining whether a move from the current coordinate in a specific direction is possible.
  355.         /// </summary>
  356.         /// <param name="coordinates">Current coordinates to check.</param>
  357.         /// <param name="direction">Current direction from coordinates to check.</param>
  358.         /// <returns>Whether the marker position is a possible move.</returns>
  359.         private bool PossibleMove(Coordinates coordinates, ReversiPlayer player, Direction direction)
  360.         {
  361.             bool valid = false;
  362.             int x = coordinates.X;
  363.             int y = coordinates.Y;
  364.  
  365.             switch (direction)
  366.             {
  367.                 case Direction.Up:
  368.                     y--;
  369.                     while (y > 0 && !valid)
  370.                     {
  371.                         if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; }
  372.                         y--;
  373.                         if (_markers[x, y] == _currentPlayer) { valid = true; }
  374.                     }
  375.                     break;
  376.                 case Direction.Down:
  377.                     y++;
  378.                     while (y < _markers.GetUpperBound(1) && !valid)
  379.                     {
  380.                         if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; }
  381.                         y++;
  382.                         if (_markers[x, y] == _currentPlayer) { valid = true; }
  383.                     }
  384.                     break;
  385.                 case Direction.Left:
  386.                     x--;
  387.                     while (x > 0 && !valid)
  388.                     {
  389.                         if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; }
  390.                         x--;
  391.                         if (_markers[x, y] == _currentPlayer) { valid = true; }
  392.                     }
  393.                     break;
  394.                 case Direction.Right:
  395.                     x++;
  396.                     while (x < _markers.GetUpperBound(0) && !valid)
  397.                     {
  398.                         if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; }
  399.                         x++;
  400.                         if (_markers[x, y] == _currentPlayer) { valid = true; }
  401.                     }
  402.                     break;
  403.                 case Direction.DiagonalRightUp:
  404.                     x++;
  405.                     y--;
  406.                     while ((x < _markers.GetUpperBound(0) && y > 0) && !valid)
  407.                     {
  408.                         if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; }
  409.                         x++;
  410.                         y--;
  411.                         if (_markers[x, y] == _currentPlayer) { valid = true; }
  412.                     }
  413.                     break;
  414.                 case Direction.DiagonalRightDown:
  415.                     x++;
  416.                     y++;
  417.                     while ((x < _markers.GetUpperBound(0) && y < _markers.GetUpperBound(1)) && !valid)
  418.                     {
  419.                         if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; }
  420.                         x++;
  421.                         y++;
  422.                         if (_markers[x, y] == _currentPlayer) { valid = true; }
  423.                     }
  424.                     break;
  425.                 case Direction.DiagonalLeftUp:
  426.                     x--;
  427.                     y--;
  428.                     while ((x > 0 && y > 0) && !valid)
  429.                     {
  430.                         if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; }
  431.                         x--;
  432.                         y--;
  433.                         if (_markers[x, y] == _currentPlayer) { valid = true; }
  434.                     }
  435.                     break;
  436.                 case Direction.DiagonalLeftDown:
  437.                     x--;
  438.                     y++;
  439.                     while ((x > 0 && y < _markers.GetUpperBound(1) && y > 0) && !valid)
  440.                     {
  441.                         if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; }
  442.                         x--;
  443.                         y++;
  444.                         if (_markers[x, y] == _currentPlayer) { valid = true; }
  445.                     }
  446.                     break;
  447.             }
  448.  
  449.             if (valid)
  450.             {
  451.                 _targetCoordinates = new Coordinates(x, y);
  452.             }
  453.  
  454.             FoundEmpty:
  455.             return valid;
  456.         }
  457.        
  458.         /// <summary>
  459.         /// Checks if current tile is a valid move for the current player.
  460.         /// </summary>
  461.         /// <param name="coordinates">Coordinates that indicate the current tile.</param>
  462.         /// <returns>Valid move or not.</returns>
  463.         private bool IsValidLocation(Coordinates coordinates)
  464.         {
  465.             if ((coordinates.X >= 0 && coordinates.X <= _markers.GetUpperBound(0)) &&
  466.                 (coordinates.Y >= 0 && coordinates.Y <= _markers.GetUpperBound(1)))
  467.             {
  468.                 // Check if marker already exists
  469.                 if (_markers[coordinates.X, coordinates.Y] != ReversiPlayer.None)
  470.                 {
  471.                     return false;
  472.                 }
  473.  
  474.                 bool validLocation = false;
  475.                 ReversiPlayer opponent = _currentPlayer ^ (ReversiPlayer)3;
  476.  
  477.                 // Check 3 spots to the right of tile
  478.                 if (coordinates.X < _markers.GetUpperBound(0))
  479.                 {
  480.                     if (coordinates.Y > 0 && _markers[coordinates.X + 1, coordinates.Y - 1] == opponent)
  481.                     {
  482.                         if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalRightUp))
  483.                         {
  484.                             validLocation = true;
  485.                         }
  486.                     }
  487.                     if (coordinates.Y < _markers.GetUpperBound(1) && _markers[coordinates.X + 1, coordinates.Y + 1] == opponent)
  488.                     {
  489.                         if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalRightDown))
  490.                         {
  491.                             validLocation = true;
  492.                         }
  493.                     }
  494.                     if (_markers[coordinates.X + 1, coordinates.Y] == opponent)
  495.                     {
  496.                         if (PossibleMove(coordinates, _currentPlayer, Direction.Right))
  497.                         {
  498.                             validLocation = true;
  499.                         }
  500.                     }
  501.  
  502.                     if (validLocation)
  503.                     {
  504.                         goto FoundValidMove;
  505.                     }
  506.                 }
  507.  
  508.                 // Check 3 spots to the left of tile
  509.                 if (coordinates.X > 0)
  510.                 {
  511.                     if (coordinates.Y > 0 && _markers[coordinates.X - 1, coordinates.Y - 1] == opponent)
  512.                     {
  513.                         if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalLeftUp))
  514.                         {
  515.                             validLocation = true;
  516.                         }
  517.                     }
  518.                     if (coordinates.Y < _markers.GetUpperBound(1) && _markers[coordinates.X - 1, coordinates.Y + 1] == opponent)
  519.                     {
  520.                         if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalLeftDown))
  521.                         {
  522.                             validLocation = true;
  523.                         }
  524.                     }
  525.                     if (_markers[coordinates.X - 1, coordinates.Y] == opponent)
  526.                     {
  527.                         if (PossibleMove(coordinates, _currentPlayer, Direction.Left))
  528.                         {
  529.                             validLocation = true;
  530.                         }
  531.                     }
  532.  
  533.                     if (validLocation)
  534.                     {
  535.                         goto FoundValidMove;
  536.                     }
  537.                 }
  538.  
  539.                 // Check 1 spot below the tile
  540.                 if (coordinates.Y < _markers.GetUpperBound(1))
  541.                 {
  542.                     if (_markers[coordinates.X, coordinates.Y + 1] == opponent)
  543.                     {
  544.                         if (PossibleMove(coordinates, _currentPlayer, Direction.Down))
  545.                         {
  546.                             validLocation = true;
  547.                         }
  548.                     }
  549.  
  550.                     if (validLocation)
  551.                     {
  552.                         goto FoundValidMove;
  553.                     }
  554.                 }
  555.  
  556.                 // Check 1 spot above the tile
  557.                 if (coordinates.Y > 0)
  558.                 {
  559.                     if (_markers[coordinates.X, coordinates.Y - 1] == opponent)
  560.                     {
  561.                         if (PossibleMove(coordinates, _currentPlayer, Direction.Up))
  562.                         {
  563.                             validLocation = true;
  564.                         }
  565.                     }
  566.                 }
  567.  
  568.             FoundValidMove:
  569.                 return validLocation;
  570.             }
  571.             return false;
  572.         }
  573.  
  574.         /// <summary>
  575.         /// Flip opponent markers from current move at specified coordinates.
  576.         /// </summary>
  577.         /// <param name="coordinates">Coordinates of the newly placed marker.</param>
  578.         private void FlipOpponentMarkers(Coordinates coordinates)
  579.         {
  580.             if (PossibleMove(coordinates, _currentPlayer, Direction.Up))
  581.             {
  582.                 for (int i = coordinates.Y; i > _targetCoordinates.Y; i--)
  583.                 {
  584.                     _markers[coordinates.X, i] = _currentPlayer;
  585.                 }
  586.             }
  587.  
  588.             if (PossibleMove(coordinates, _currentPlayer, Direction.Down))
  589.             {
  590.                 for (int i = coordinates.Y; i < _targetCoordinates.Y; i++)
  591.                 {
  592.                     _markers[coordinates.X, i] = _currentPlayer;
  593.                 }
  594.             }
  595.  
  596.             if (PossibleMove(coordinates, _currentPlayer, Direction.Left))
  597.             {
  598.                 for (int i = coordinates.X; i > _targetCoordinates.X; i--)
  599.                 {
  600.                     _markers[i, coordinates.Y] = _currentPlayer;
  601.                 }
  602.             }
  603.  
  604.             if (PossibleMove(coordinates, _currentPlayer, Direction.Right))
  605.             {
  606.                 for (int i = coordinates.X; i < _targetCoordinates.X; i++)
  607.                 {
  608.                     _markers[i, coordinates.Y] = _currentPlayer;
  609.                 }
  610.             }
  611.  
  612.             if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalRightUp))
  613.             {
  614.                 int j = coordinates.Y;
  615.                 for (int i = coordinates.X; i < _targetCoordinates.X; i++, j--)
  616.                 {
  617.                     _markers[i, j] = _currentPlayer;
  618.                 }
  619.             }
  620.  
  621.             if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalRightDown))
  622.             {
  623.                 int j = coordinates.Y;
  624.                 for (int i = coordinates.X; i < _targetCoordinates.X; i++, j++)
  625.                 {
  626.                     _markers[i, j] = _currentPlayer;
  627.                 }
  628.             }
  629.  
  630.             if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalLeftUp))
  631.             {
  632.                 int j = coordinates.Y;
  633.                 for (int i = coordinates.X; i > _targetCoordinates.X; i--, j--)
  634.                 {
  635.                     _markers[i, j] = _currentPlayer;
  636.                 }
  637.             }
  638.  
  639.             if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalLeftDown))
  640.             {
  641.                 int j = coordinates.Y;
  642.                 for (int i = coordinates.X; i > _targetCoordinates.X; i--, j++)
  643.                 {
  644.                     _markers[i, j] = _currentPlayer;
  645.                 }
  646.             }
  647.  
  648.             _currentPlayer ^= (ReversiPlayer)3;
  649.             this.Invalidate();
  650.         }
  651.         #endregion
  652.     }
  653.  
  654.     /// <summary>
  655.     /// Determines the layout for the game grid/board.
  656.     /// </summary>
  657.     struct ReversiLayout
  658.     {
  659.         public ReversiLayout(int rows, int columns)
  660.         {
  661.             this.Rows = rows;
  662.             this.Columns = columns;
  663.         }
  664.  
  665.         public readonly int Rows;
  666.         public readonly int Columns;
  667.     }
  668.  
  669.     /// <summary>
  670.     /// Determines the current player and occupied or vacant tile piece.
  671.     /// </summary>
  672.     enum ReversiPlayer : short
  673.     {
  674.         None = 0,
  675.         Player1 = 1,
  676.         Player2 = 2
  677.     }
  678.  
  679.     /// <summary>
  680.     /// Determines the direction to look in for a valid move.
  681.     /// </summary>
  682.     enum Direction : short
  683.     {
  684.         Up,
  685.         Down,
  686.         Left,
  687.         Right,
  688.         DiagonalRightUp,
  689.         DiagonalRightDown,
  690.         DiagonalLeftUp,
  691.         DiagonalLeftDown
  692.     }
  693.  
  694.     /// <summary>
  695.     /// Stores relative tile coordinates on game board.
  696.     /// </summary>
  697.     struct Coordinates
  698.     {
  699.         public Coordinates(int x, int y)
  700.         {
  701.             this.X = x;
  702.             this.Y = y;
  703.         }
  704.  
  705.         public readonly int X;
  706.         public readonly int Y;
  707.     }
  708.  
  709.     /// <summary>
  710.     /// Data for game pieces that are displayed on the board.
  711.     /// </summary>
  712.     class Marker
  713.     {
  714.         // Fields & Properties
  715.         public ReversiPlayer Player;
  716.         public Coordinates TileCoordinates;
  717.        
  718.         // Constructor
  719.         public Marker(ReversiPlayer player, Coordinates location)
  720.         {
  721.             this.Player = player;
  722.             this.TileCoordinates = location;
  723.         }
  724.     }
  725. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement