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); }