internal void SetGameState() { Player opponent = WhoseTurn; Player lastPlayer = ChessUtilities.RevertPlayer(opponent); bool isInCheck = ChessUtilities.IsPlayerInCheck(opponent, this); var hasValidMoves = ChessUtilities.GetValidMoves(this).Count > 0; if (isInCheck && !hasValidMoves) { GameState = lastPlayer == Player.White ? GameState.WhiteWinner : GameState.BlackWinner; return; } if (!hasValidMoves) { GameState = GameState.Stalemate; return; } if (isInCheck) { GameState = opponent == Player.White ? GameState.WhiteInCheck : GameState.BlackInCheck; return; } GameState = IsInsufficientMaterial() ? GameState.Draw : GameState.NotCompleted; }
/// <summary>Makes a move in the game.</summary> /// <param name="move">The <see cref="Move"/> you want to make.</param> /// <param name="isMoveValidated">Only pass true when you've already checked that the move is valid.</param> /// <returns>Returns true if the move is made; false otherwise.</returns> /// <exception cref="ArgumentNullException"> /// The <c>move</c> is null. /// </exception> /// <exception cref="InvalidOperationException"> /// The <see cref="Move.Source"/> square of the <c>move</c> doesn't contain a piece. /// </exception> /// <exception cref="ArgumentNullException"> /// The <c>move.PromoteTo</c> is null and the move is a pawn promotion move. /// </exception> public bool MakeMove(Move move, bool isMoveValidated) { if (move == null) { throw new ArgumentNullException(nameof(move)); } Piece piece = this[move.Source]; if (piece == null) { throw new InvalidOperationException("Source square has no piece."); } if (!isMoveValidated && !IsValidMove(move)) { return(false); } SetCastleStatus(move, piece); if (piece is King && move.GetAbsDeltaX() == 2) { // Queen-side castle if (move.Destination.File == File.C) { var rook = this[File.A, move.Source.Rank]; Board[(int)move.Source.Rank, (int)File.A] = null; Board[(int)move.Source.Rank, (int)File.D] = rook; } // King-side castle if (move.Destination.File == File.G) { var rook = this[File.H, move.Source.Rank]; Board[(int)move.Source.Rank, (int)File.H] = null; Board[(int)move.Source.Rank, (int)File.F] = rook; } } if (piece is Pawn) { if ((move.Player == Player.White && move.Destination.Rank == Rank.Eighth) || (move.Player == Player.Black && move.Destination.Rank == Rank.First)) { switch (move.PromoteTo) { case PawnPromotion.Knight: piece = new Knight(piece.Owner); break; case PawnPromotion.Bishop: piece = new Bishop(piece.Owner); break; case PawnPromotion.Rook: piece = new Rook(piece.Owner); break; case PawnPromotion.Queen: piece = new Queen(piece.Owner); break; default: throw new ArgumentNullException(nameof(move.PromoteTo)); } } // Enpassant if (Pawn.GetPawnMoveType(move) == PawnMoveType.Capture && this[move.Destination] == null) { Board[(int)Moves.Last().Destination.Rank, (int)Moves.Last().Destination.File] = null; } } Board[(int)move.Source.Rank, (int)move.Source.File] = null; Board[(int)move.Destination.Rank, (int)move.Destination.File] = piece; Moves.Add(move); WhoseTurn = ChessUtilities.RevertPlayer(move.Player); SetGameState(); return(true); }