public void TakeBlackTurn(out bool gameOver) // Takes Black's turn, moving its king. Checks for and handles checkmate and stalemate. // Handles draw for King vs King but not for any other situation such as King and Bishop // vs King. In checkmate, stalemate, or draw, sets gameOver to true; otherwise, sets it to // false. Does not enable/disable squares. { ++numMoves; AnalyzeAttacks(); BlackKing.FindMoves(this.SQUARES); ChessSquare BlackKingChoice = BlackKing.ChooseMove(); if (BlackKingChoice != null) { if (BlackKingChoice.Piece != null) { White.Remove(BlackKingChoice.Piece); } BlackKing.Move(BlackKingChoice); if (White.Count == 1) // Draw by lack of material { // This would be slightly better with a custom message box with a bigger font. MessageBox.Show("Draw by lack of material 😞\nIn " + numMoves + " moves"); gameOver = true; } else { AnalyzeAttacks(); gameOver = false; } } else // Black King cannot move, is in checkmate or stalemate { if (BlackKing.Square.WhiteAttacked) { MessageBox.Show("Checkmate! 😁\nIn " + numMoves + " moves"); } else { MessageBox.Show("Stalemate 😞\nIn " + numMoves + " moves"); } gameOver = 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); } }