private HashSet<ChessMove> DetermineTranslationalMovements(List<int[]> tranlations, Coordinate fromCoordinate, ChessPiece fromPiece)
 {
     Coordinate potentialCoordinate;
     var legalMoves = new HashSet<ChessMove>();
     foreach (int[] translation in tranlations)
     {
         potentialCoordinate = new Coordinate(fromCoordinate, translation[0], translation[1]);
         if (potentialCoordinate.IsInBoardBounds())
         {
             ChessPiece potentialCoordinatePiece = GetPieceAtCoordinate(potentialCoordinate);
             bool blocked = potentialCoordinatePiece.Type != ChessPieceType.None;
             bool capture = blocked && potentialCoordinatePiece.Color != TurnColor;
             // Only move to blocked square if it is to be captured.
             if (!blocked || capture)
             {
                 // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                 legalMoves.Add(new ChessMove(fromCoordinate, potentialCoordinate, fromPiece.Type, capture, false, false, false, false, false, false));
             }
         }
     }
     return legalMoves;
 }
        // Note that this considers moving one's self into a checked position possible, even though it is not legal. This is to avoid the excessive computation of determining if this is the case. The check will be performed on tryApplyMove instead.
        private HashSet<ChessMove> InitializePossibleMoves(Coordinate fromCoordinate)
        {
            var legalMoves = new HashSet<ChessMove>();
            ChessPiece fromPiece = GetPieceAtCoordinate(fromCoordinate);
            // No valid moves for empty squares or if the color of the piece does not match whose turn it is.
            if (fromPiece.Type == ChessPieceType.None || fromPiece.Color == ChessPieceColor.None || fromPiece.Color != TurnColor)
            {
                // Empty at this point
                return legalMoves;
            }
            Coordinate potentialCoordinate;
            switch (fromPiece.Type)
            {
                case ChessPieceType.Rook:
                    legalMoves.UnionWith(DetermineIndefiniteDirectionalMovements(RookDirections, fromCoordinate, fromPiece));
                    break;

                case ChessPieceType.Knight:
                    legalMoves.UnionWith(DetermineTranslationalMovements(KnightTranslations, fromCoordinate, fromPiece));
                    break;

                case ChessPieceType.Bishop:
                    legalMoves.UnionWith(DetermineIndefiniteDirectionalMovements(BishopDirections, fromCoordinate, fromPiece));
                    break;

                case ChessPieceType.Queen:
                    legalMoves.UnionWith(DetermineIndefiniteDirectionalMovements(QueenDirectionsKingTranslations, fromCoordinate, fromPiece));
                    break;

                case ChessPieceType.King:
                    legalMoves.UnionWith(DetermineTranslationalMovements(QueenDirectionsKingTranslations, fromCoordinate, fromPiece));
                    if (TurnColor == ChessPieceColor.White)
                    {
                        if (WhiteKingsideCastling && BoardGrid[0, 5].Type == ChessPieceType.None && BoardGrid[0, 6].Type == ChessPieceType.None)
                        {
                            // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                            legalMoves.Add(new ChessMove(fromCoordinate, new Coordinate(0, 6), ChessPieceType.King, false, false, false, false, false, true, false));
                        }
                        if (WhiteQueensideCastling && BoardGrid[0, 1].Type == ChessPieceType.None && BoardGrid[0, 2].Type == ChessPieceType.None && BoardGrid[0, 3].Type == ChessPieceType.None)
                        {
                            // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                            legalMoves.Add(new ChessMove(fromCoordinate, new Coordinate(0, 2), ChessPieceType.King, false, false, false, false, false, false, true));
                        }
                    }
                    else
                    {
                        if (BlackKingsideCastling && BoardGrid[7, 5].Type == ChessPieceType.None && BoardGrid[7, 6].Type == ChessPieceType.None)
                        {
                            // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                            legalMoves.Add(new ChessMove(fromCoordinate, new Coordinate(7, 6), ChessPieceType.King, false, false, false, false, false, true, false));
                        }
                        if (BlackQueensideCastling && BoardGrid[7, 1].Type == ChessPieceType.None && BoardGrid[7, 2].Type == ChessPieceType.None && BoardGrid[7, 3].Type == ChessPieceType.None)
                        {
                            legalMoves.Add(new ChessMove(fromCoordinate, new Coordinate(7, 2), ChessPieceType.King, false, false, false, false, false, false, true));
                        }
                    }
                    break;

                case ChessPieceType.Pawn:
                    // 1 if white, -1 if black.
                    int pawnDirection;
                    // How many steps foeward this pawn is allowed to move.
                    int pawnForwardAmountAllowed = 1;
                    if (TurnColor == ChessPieceColor.White)
                    {
                        pawnDirection = 1;
                        // Yet-to-move pawns can move forward two spaces.
                        if (fromCoordinate.Row == 1)
                        {
                            pawnForwardAmountAllowed = 2;
                        }
                    }
                    else
                    {
                        pawnDirection = -1;
                        // Yet-to-move pawns can move forward two spaces.
                        if (fromCoordinate.Row == 6)
                        {
                            pawnForwardAmountAllowed = 2;
                        }
                    }
                    int forwardMoved = 1;
                    // Continue checking the next forward step until the max amount of steps have been taken, or a piece has been encountered.
                    while (forwardMoved <= pawnForwardAmountAllowed)
                    {
                        potentialCoordinate = new Coordinate(fromCoordinate, forwardMoved * pawnDirection, 0);
                        // If the potential coordinate does not go off bounds and does not occupy the location of another piece, allow a move there
                        if (potentialCoordinate.IsInBoardBounds() && GetPieceAtCoordinate(potentialCoordinate).Type == ChessPieceType.None)
                        {
                            // If a white pawn moves to row 7 or a black pawn moves to row 0, a prootion is in order.
                            bool isPromotionToQueen = (potentialCoordinate.Row == (TurnColor == ChessPieceColor.White ? 7 : 0));
                            // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                            legalMoves.Add(new ChessMove(fromCoordinate, potentialCoordinate, fromPiece.Type, false, isPromotionToQueen, false, false, false, false, false));
                        }
                        else
                        {
                            break;
                        }
                        forwardMoved++;
                    }
                    // Check pawn's ability to diagonally capture.
                    // Kingside Diagonal.
                    potentialCoordinate = new Coordinate(fromCoordinate, pawnDirection, 1);
                    if (potentialCoordinate.IsInBoardBounds())
                    {
                        ChessPiece pieceAtPotentialCoordinate = GetPieceAtCoordinate(potentialCoordinate);
                        if (pieceAtPotentialCoordinate.Type != ChessPieceType.None &&
                            TurnColor != pieceAtPotentialCoordinate.Color)
                        {
                            bool isPromotionToQueen = (potentialCoordinate.Row == (TurnColor == ChessPieceColor.White ? 7 : 0));
                            // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                            legalMoves.Add(new ChessMove(fromCoordinate, potentialCoordinate, fromPiece.Type, true, isPromotionToQueen, false, false, false, false, false));
                        }
                        // Kingside Diagonal En Passant.
                        if (EnPassantTarget.IsInBoardBounds() && EnPassantTarget.Equals(potentialCoordinate))
                        {
                            bool isPromotionToQueen = (potentialCoordinate.Row == (TurnColor == ChessPieceColor.White ? 7 : 0));
                            // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                            legalMoves.Add(new ChessMove(fromCoordinate, potentialCoordinate, fromPiece.Type, true, isPromotionToQueen, false, false, false, false, false));
                        }
                    }
                    // Queenside Diagonal.
                    potentialCoordinate = new Coordinate(fromCoordinate, pawnDirection, -1);
                    if (potentialCoordinate.IsInBoardBounds())
                    {
                        ChessPiece pieceAtPotentialCoordinate = GetPieceAtCoordinate(potentialCoordinate);
                        if (pieceAtPotentialCoordinate.Type != ChessPieceType.None &&
                            TurnColor != pieceAtPotentialCoordinate.Color)
                        {
                            bool isPromotionToQueen = (potentialCoordinate.Row == (TurnColor == ChessPieceColor.White ? 7 : 0));
                            // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                            legalMoves.Add(new ChessMove(fromCoordinate, potentialCoordinate, fromPiece.Type, true, isPromotionToQueen, false, false, false, false, false));
                        }
                        // Queenside Diagonal En Passant.
                        if (EnPassantTarget.IsInBoardBounds() && EnPassantTarget.Equals(potentialCoordinate))
                        {
                            bool isPromotionToQueen = (potentialCoordinate.Row == (TurnColor == ChessPieceColor.White ? 7 : 0));
                            // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                            legalMoves.Add(new ChessMove(fromCoordinate, potentialCoordinate, fromPiece.Type, true, isPromotionToQueen, false, false, false, false, false));
                        }
                    }
                    break;

                default:
                    // Already handled before switch
                    break;
            }

            return legalMoves;
        }
 // Determine legal moves for pieces that can move in specific directions until they reach the end of the board or another piece.
 private List<ChessMove> DetermineIndefiniteDirectionalMovements(List<int[]> directions, Coordinate fromCoordinate, ChessPiece fromPiece)
 {
     var legalMoves = new List<ChessMove>();
     Coordinate potentialCoordinate;
     foreach (int[] direction in directions)
     {
         int moved = 1;
         while (true)
         {
             potentialCoordinate = new Coordinate(fromCoordinate, moved * direction[0], moved * direction[1]);
             // If the potential coordinate does not go off bounds, allow a move there.
             if (potentialCoordinate.IsInBoardBounds())
             {
                 ChessPiece potentialCoordinatePiece = GetPieceAtCoordinate(potentialCoordinate);
                 bool blocked = potentialCoordinatePiece.Type != ChessPieceType.None;
                 bool capture = blocked && potentialCoordinatePiece.Color != TurnColor;
                 // Only move to blocked square if it is to be captured.
                 if (!blocked || capture)
                 {
                     // Check and checkmate values will only be verified after a move is chosen, to avoid the heavy processing for each move.
                     legalMoves.Add(new ChessMove(fromCoordinate, potentialCoordinate, fromPiece.Type, capture, false, false, false, false, false, false));
                 }
                 // Cannot move past another piece.
                 if (blocked) { break; }
             }
             else
             {
                 break;
             }
             // Check further in this direction.
             moved++;
         }
     }
     return legalMoves;
 }