Использование оператора Switch со структурой с вложенным перечислением - Swift - PullRequest
0 голосов
/ 26 мая 2018

Оператор переключения со структурой с вложенным Enum

Swift 4.1, Xcode 9.3.1

У меня есть очень специфический случай, с которым мне нужно встретиться, но у меня возникают проблемы при его написании (дополнительная информация ниже) .

*** Проверьте комментарии в countHand(_:)


Мой код:

enum Suit {
    case Clubs, Diamonds, Hearts, Spades
}

enum Rank {
    case Jack, Queen, King, Ace
    case Num(Int)
}

struct Card {
    let suit: Suit
    let rank: Rank
}

extension Rank: Equatable {
    static func == (lhs: Rank, rhs: Rank)
        -> Bool {
        switch (lhs, rhs) {
        case (.Jack, .Jack), (.Queen, .Queen), (.King, .King), (.Ace, .Ace):
            return true
        case let (.Num(n1), .Num(n2)) where n1 == n2:
            return true
        default:
            return false
        }
    }
}

extension Suit: Equatable {
    static func == (lhs: Suit, rhs: Suit)
        -> Bool {
        switch (lhs, rhs) {
        case (.Diamonds, .Diamonds), (.Hearts, .Hearts), (.Spades, .Spades), (.Clubs, .Clubs):
            return true
        default:
            return false
        }
    }
}


//Main Function
func countHand(_ cards: [Card]) -> Int {

    var count = 0

    zip(cards, cards[1...]).forEach { card, nextCard in
        let bothCards = (card, nextCard)

        switch bothCards {
        case let (c1, c2) where c1.rank == .Num(5) && c1.suit == .Diamonds && c2.rank == .Ace:
            count += 100

        case let (c1, c2) where c1.suit == .Hearts && ![.Jack, .Queen, .King, .Ace].contains(c2.rank): //I checked the contents of the array as a workaround to determine that the rank is a numeric value 

            //Also, if c2.rank is Rank.Num(let n) where n == 3 || n == 5 || n == 7 || n == 9

            count += n * 2

        default:
            break
        }

    }

    return count


}

Значения карт

Значения карт следующие:

  • Любой туз, которому предшествует 5 бриллиантов, стоит 100 очков.

  • Любая нечетная числовая карта (3, 5, 7, 9) достоинства любой масти, удваивающая его значение ранга в пунктах, когда в руке сразу же предшествует любая карта Червей.Примеры:

    1. Стрелка 3 ♥, 7 ♣ имеет общее значение 14.

    2. Стрелка 3 ♣, 7 of имеет общее значение0.


Требования

Что я хотел бы сделать - в отношении моего второго утверждения случая - я только хочу этовызываться, если первая карта c1 и вторая карта c2 соответствуют следующим критериям:

  1. c1.suit равно .Hearts

  2. c2.rank является числовым (.Num(n)) и n равно 3, 5, 7 или 9

Если оба эти критерия выполнены, Iхотел бы увеличить значение с count до n * 2


Моя проблема

Я глубоко искал, чтобы попытаться найти случай, похожий на мой в Интернете,но, к сожалению, нет ни одного - который я мог бы найти - который соответствовал бы уровню специфичности, который я ищу.

Я попытался добавить его в предикат where, выполнив такие действия, как where ... && c2.rank = .Num(let n)написал if заявление в тОн может изменить значение count, только если оно равно 3, 5, 7 или 9, но это привело к всевозможным ошибкам, и я не чувствую, что это лучший способ реализовать его.Это моя главная проблема, которую я пытаюсь решить.Если я смогу сделать это, я вполне уверен, что смогу обойти мой обходной путь where ... && ![.Jack, .Queen, .King, .Ace].contains(c2.rank).


Заранее всем спасибо за все предложения, решения, отзывы и т. Д., Я действительно ценюпомощь!

1 Ответ

0 голосов
/ 26 мая 2018

Вы не можете выполнить сопоставление с образцом в предложении where, но вместо этого вы можете включить оба свойства обеих карт:

switch (card.suit, card.rank, nextCard.suit, nextCard.rank) {
case (.Diamonds, .Num(5), _, .Ace):
    count += 100
case (.Hearts, _, _, .Num(let n)) where n >= 3 && n % 2 != 0:
    // Or: ... where [3, 5, 7, 9].contains(n):
    count += n * 2
default:
    break
}

Примечание: В соответствии с текущим Руководство по проектированию Swift API , свойства перечисления должны быть строчными:

Имена типов и протоколов UpperCamelCase.Все остальное lowerCamelCase.

...