private void clearBoard()
        // Removes all pieces from the board, and disables all squares.
        {
            foreach (ChessSquare square in SQUARES)
            {
                square.Piece = null;
                square.SetEnabled(false);
            }

            // Free resources
            White     = null;
            BlackKing = null;
        }
        private void btnResetOP_Click(object sender, EventArgs e)
        // Restarts game with pieces in their original positions
        {
            if (startData == null)
            {
                MessageBox.Show("No game to reset");
                return;
            }

            clearBoard();
            BlackKing = new BlackKing(startData.Item3);
            White     = new List <ChessPiece>(capacity: startData.Item2.Length);
            for (int i = 0; i < startData.Item1.Length; ++i)
            {
                White.Add(
                    (ChessPiece)(startData.Item1[i]
                                 .GetConstructor(types: new Type[] { typeof(ChessSquare) })
                                 .Invoke(parameters: new object[] { startData.Item2[i] })));
            }
            foreach (ChessPiece piece in White)
            {
                piece.Square.SetEnabled(true);
            }
        }
        public void StartNewGame(Type[] whitePieceTypes)
        // Starts a new game with a Black King and white pieces of Types whitePieceTypes. Each Type
        // in whitePieceTypes must be a subclass of ChessPiece, must not be abstract, and must be
        // white. In case there are already pieces on the board, the board is cleared first.
        {
            // Check whitePieceTypes for argument errors
            foreach (Type type in whitePieceTypes)
            {
                if (!type.IsSubclassOf(typeof(ChessPiece)))
                {
                    throw new ArgumentException(
                              "Each type in whitePieceTypes must be a subclass of ChessPiece.");
                }
                if (type.IsAbstract)
                {
                    throw new ArgumentException("No type in whitePieceTypes may be abstract");
                }
            }

            // Basic setup
            clearBoard();
            numMoves = 0;
            White    = new List <ChessPiece>(capacity: whitePieceTypes.Length);
            byte numPieces = (byte)(whitePieceTypes.Length + 1); // +1 for Black King

            // Put pieces on random squares, but make sure Black King is not in checkmate or
            // stalemate
            ChessSquare[] initSquares = randomSquares(numPieces);
            BlackKing = new BlackKing(initSquares[0]);
            for (int i = 1; i < initSquares.Length; ++i)
            {
                White.Add( // Dis wite heer bout to git complikated :)
                    (ChessPiece)(whitePieceTypes[i - 1]
                                 .GetConstructor(types: new Type[] { typeof(ChessSquare) })
                                 .Invoke(parameters: new object[] { initSquares[i] })));
            }
            AnalyzeAttacks();
            BlackKing.FindMoves(SQUARES);
            while (BlackKing.Square.WhiteAttacked || BlackKing.Moves.Count == 0)
            {
                initSquares = randomSquares(numPieces);
                BlackKing.Move(initSquares[0]);
                for (int i = 1; i < initSquares.Length; ++i)
                {
                    White[i - 1].Move(initSquares[i]);
                }
                AnalyzeAttacks();
                BlackKing.FindMoves(SQUARES);
            }

            // Set startData
            startData = Tuple.Create(whitePieceTypes, new ChessSquare[White.Count], BlackKing.Square);
            for (int i = 0; i < White.Count; ++i)
            {
                startData.Item2[i] = White[i].Square;
            }

            // Enable squares with white pieces
            foreach (ChessPiece piece in White)
            {
                piece.Square.SetEnabled(true);
            }
        }