HiveBrain v1.2.0
Get Started
← Back to all entries
patternswiftMinor

Let's play some Swift Poker

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
swiftpokerplayletsome

Problem

Before you can do any sort of card game, you must first write some code to define your deck of cards.

One thing I've noticed in looking at some of Apple's Swift interfaces is that they very much so like to use extensions. This is probably good. In the big picture long term, it's a really good way of allowing ever-expanding classes while actually keeping individual source code files quite tidy.

I also wanted to try something out with Swift enums and iterating through every value in them...

The Basics

enum Suit

enum Suit: String {
    case Clubs = "Clubs"
    case Diamonds = "Diamonds"
    case Hearts = "Hearts"
    case Spades = "Spades"
    case __EXHAUST = ""
}


enum Rank

enum Rank: String {
    case Ace = "Ace"
    case Two = "Two"
    case Three = "Three"
    case Four = "Four"
    case Five = "Five"
    case Six = "Six"
    case Seven = "Seven"
    case Eight = "Eight"
    case Nine = "Nine"
    case Ten = "Ten"
    case Jack = "Jack"
    case Queen = "Queen"
    case King = "King"
    case __EXHAUST = ""
}


struct Card

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


The Extensions

Suit: FowardIndexType

extension Suit: ForwardIndexType {
    func successor() -> Suit {
        switch self {
        case .Clubs: return .Diamonds
        case .Diamonds: return .Hearts
        case .Hearts: return .Spades
        case .Spades: return .__EXHAUST
        case .__EXHAUST: return .__EXHAUST
        }
    }
}


Rank: ForwardIndexType

```
extension Rank: ForwardIndexType {
func successor() -> Rank {
switch self {
case .Ace: return .Two
case .Two: return .Three
case .Three: return .Four
case .Four: return .Five
case .Five: return .Six
case .Six: return .Seven
case .Seven: return .Eight
case .Eight: return .Nine
case .Nine: return .Ten
case .Ten: return .Jack
case .Jack: return .Queen
case .Queen: return .King

Solution

Bearing in mind that I don't know much Swift...

Your Rank enum could save you a lot of typing if you simply made it a plain old autoincrementing integer enumeration:

enum Rank: Int {
    case Ace = 1, Two, Three, Four, Five, Six, Seven,
    Eight, Nine, Ten, Jack, Queen, King, __EXHAUST
}

extension Rank: ForwardIndexType {
    func successor() -> Rank {
        switch self {
        case .__EXHAUST: return .__EXHAUST
        default: return Rank(rawValue: self.rawValue + 1)!
        }
    }
}

extension Rank: Printable, DebugPrintable {
    var description: String {
        get {
            switch (self) {
            case .Ace: return "Ace"
            case .Jack: return "Jack"
            case .Queen: return "Queen"
            case .King: return "King"
            default: return self.rawValue.description
            }
        }
    }
    var debugDescription: String {
        get { return self.description }
    }
}

for i in Rank.Ace ... .King {
    print(i)
}


When testing out this code, please notice that the Printable protocol doesn't work in Playgrounds at the moment.

Also, of course, shuffling the deck 3 times doesn't make the order of the cards any "more random" than shuffling the deck once. But you probably know that, since you went to the bother of implementing copying a correct shuffling algorithm.

To add jokers, the most "C-like" approach would be to add Suit.Joker and Rank.Joker and leave Card alone.
The most "functional-programming" approach would be to change Card from a struct to an enum with a special case for jokers:

enum Card {
    case Regular(Rank, Suit)
    case Joker
}

var c = Card.Regular(.Ace, .Spades)
var j = Card.Joker

Code Snippets

enum Rank: Int {
    case Ace = 1, Two, Three, Four, Five, Six, Seven,
    Eight, Nine, Ten, Jack, Queen, King, __EXHAUST
}

extension Rank: ForwardIndexType {
    func successor() -> Rank {
        switch self {
        case .__EXHAUST: return .__EXHAUST
        default: return Rank(rawValue: self.rawValue + 1)!
        }
    }
}

extension Rank: Printable, DebugPrintable {
    var description: String {
        get {
            switch (self) {
            case .Ace: return "Ace"
            case .Jack: return "Jack"
            case .Queen: return "Queen"
            case .King: return "King"
            default: return self.rawValue.description
            }
        }
    }
    var debugDescription: String {
        get { return self.description }
    }
}

for i in Rank.Ace ... .King {
    print(i)
}
enum Card {
    case Regular(Rank, Suit)
    case Joker
}

var c = Card.Regular(.Ace, .Spades)
var j = Card.Joker

Context

StackExchange Code Review Q#71449, answer score: 5

Revisions (0)

No revisions yet.