Exemplo n.º 1
0
        public (bool IsCheck, bool IsMate) IsCheckOrMate(King king)
        {
            bool isInCheck = false;

            foreach (var piece in this.Instance)
            {
                if (piece != null && piece.Type != PieceTypeEnum.King && piece.Color != king.Color)
                {
                    var pieceMoves = piece.AvailableMoves(this);
                    if (pieceMoves.Contains(new KeyValuePair <int, int>(king.CurrentLocation_x, king.CurrentLocation_y)))
                    {
                        isInCheck = true;
                        // conditions for mate -
                        //   1 - all possible moves for king result in checks
                        //   2 - the piece putting king in check isn't capturable
                        //   3 - no piece can intercept the check path

                        // 1
                        var kingMoves = king.AvailableMoves(this);
                        foreach (var kingMove in kingMoves)
                        {
                            // simulate moves on a board copy to see if it results in check
                            var kingCopy  = (King)this.DeepClone(king);
                            var boardCopy = (Board)this.DeepClone(this);
                            boardCopy.MovePiece(kingCopy, kingMove.Key, kingMove.Value);
                            if (!kingCopy.IsInCheck(boardCopy))
                            {
                                // has an available move, not a mate
                                return(true, false);
                            }
                        }

                        // 2/3
                        var checkPath = piece.GetCheckPath(this);
                        foreach (var defensePiece in this.Instance)
                        {
                            if (defensePiece != null && defensePiece.Color != piece.Color)
                            {
                                var defensePieceMoves = defensePiece.AvailableMoves(this);
                                // 2. see if a defense piece can capture the piece putting king in check
                                if (defensePieceMoves.Contains(new KeyValuePair <int, int>(piece.CurrentLocation_x, piece.CurrentLocation_y)))
                                {
                                    // can capture piece
                                    return(true, false);
                                }
                                // 3. see if any defenses piece can intercept the check path
                                if (defensePieceMoves.Any(x => checkPath.Any(e => e.Key == x.Key && e.Value == x.Value)))
                                {
                                    // can intercept check
                                    return(true, false);
                                }
                            }
                        }
                    }
                }
            }

            return(isInCheck, true);
        }