/// <summary>
 /// Checks if a given move is valid
 /// </summary>
 /// <param name="board">The game board</param>
 /// <param name="point">The point to play in</param>
 /// <param name="currentPlayer">The current player's color</param>
 /// <returns>True if the move is valid, false otherwise</returns>
 public static bool IsValidMove(Disc[,] board, Point point, Disc currentPlayer)
 {
     if (point == null)
         return false;
     return board.At(point).IsEmpty() &&
         PointsToReverse(board, point, currentPlayer).Count > 0;
 }
        public Point NextMove(Disc[,] board, Disc playerColor)
        {
            Point bestMove = new Point(0, 0);
            int MaxD = 1;

            foreach (Point p in ReversiGame.ValidMoves(board, playerColor))
            {
                if ((p.X == 7 && p.Y == 7) || (p.X == 7 && p.Y == 0) || (p.X == 0 && p.Y == 7) || (p.X == 0 && p.Y == 0))
                {
                    return p;
                }
                int score = ReversiGame.Score(ReversiGame.PlayTurn(board, p, playerColor), playerColor);
                if (board.At(p) == playerColor)
                {

                }

                if (score > MaxD)
                {
                    bestMove = p;
                    MaxD = score;
                }
            }
            return bestMove;
        }
 /// <summary>
 /// Counts the number of discs of a given color on the board.
 /// (works for Disc.Empty)
 /// </summary>
 /// <param name="board">The game board</param>
 /// <param name="color">The player color</param>
 /// <returns>The disc count</returns>
 public static int CountDiscs(Disc[,] board, Disc color)
 {
     int count = 0;
     foreach (Point p in board.PointsIterator())
         if (board.At(p) == color)
             count++;
     return count;
 }
 /// <summary>
 /// Counts the number of discs of a given color on the board.
 /// (works for Disc.Empty)
 /// </summary>
 /// <param name="board">The game board</param>
 /// <param name="color">The player color</param>
 /// <returns>The disc count</returns>
 public static int CountDiscs(Disc[,] board, Disc color)
 {
     return board.PointsIterator().Count(p => board.At(p) == color);
 }
 /// <summary>
 /// Returns the set of points to reverse in a given direction.
 /// </summary>
 /// <remarks>
 /// Returns the consecutive set of discs from the current point 
 /// to the next same colored point in the given direction.
 /// </remarks>
 /// <param name="board">The game board</param>
 /// <param name="point">The point of the new disc</param>
 /// <param name="direction">The direction to scan in</param>
 /// <param name="currentPlayer">The current player's color</param>
 /// <returns></returns>
 public static ISet<Point> ReversedToNext(Disc[,] board, Point point, Point direction, Disc currentPlayer)
 {
     HashSet<Point> points = new HashSet<Point>();
     point += direction;
     if (!board.OnBoard(point))
         return points;
     Disc currentDisc;
     for (currentDisc = board.At(point);
         currentDisc == currentPlayer.Reversed() && board.OnBoard(point + direction);
         point += direction, currentDisc = board.At(point))
         points.Add(point);
     if (currentDisc.IsEmpty() ||
         !board.OnBoard(point + direction) && currentDisc != currentPlayer)
         points.Clear();
     return points;
 }
 /// <summary>
 /// Returns a set of points to reverse as a result of placing a new disc
 /// </summary>
 /// <remarks>
 /// A move is invalid if the number of points in the set is zero
 /// <see cref="ReversiGame.IsValidMove(Disc[,], Point, Disc)"/>
 /// </remarks>
 /// <param name="board">The game board</param>
 /// <param name="newDisc">The new disc's position</param>
 /// <param name="currentPlayer">The new disc's color</param>
 /// <returns>A set of points to reverse</returns>
 public static ISet<Point> PointsToReverse(Disc[,] board, Point newDisc, Disc currentPlayer)
 {
     if (!board.At(newDisc).IsEmpty())
         throw new Exception("Non-empty point chosen to place new disc");
     HashSet<Point> result = new HashSet<Point>();
     foreach (Point direction in Point.Directions)
         result.UnionWith(ReversedToNext(board, newDisc, direction, currentPlayer));
     return result;
 }