Created
June 5, 2014 15:52
-
-
Save rfunduk/518fe227dbdd60dc0dad to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Darwin | |
extension Array { | |
func shuffle() -> Array { | |
// this will sometimes crash (submitted bug #17127524) | |
self.sort { _,_ in arc4random_uniform(2) == 1 } | |
return self | |
} | |
mutating func removeAtIndexes( indexes:Int... ) { | |
indexes.sort(>) | |
for i in indexes { removeAtIndex(i) } | |
} | |
} | |
class CardSet { | |
struct Card { | |
enum Suit:Int { | |
case Hearts, Diamonds, Clubs, Spades | |
} | |
enum Rank:Int { | |
case Two, Three, Four, Five, Six | |
case Seven, Eight, Nine, Ten | |
case Jack, Queen, King, Ace | |
} | |
let suit:Suit | |
let rank:Rank | |
} | |
var cards:Card[] | |
init() { cards = [] } | |
init( _ cards:Card[] ) { self.cards = cards } | |
var isEmpty:Bool { return cards.isEmpty } | |
} | |
class Deck:CardSet { | |
init() { | |
let indexes = Array(0..52).shuffle() | |
super.init(indexes.map { index in | |
let suit = Card.Suit.fromRaw(index % 4)! | |
let rank = Card.Rank.fromRaw(index % 13)! | |
return Card(suit: suit, rank: rank) | |
}) | |
} | |
func drawCard() -> Card { return cards.removeLast() } | |
} | |
class Hand:CardSet { | |
var canPlay:Bool { | |
return cards.count >= 4 && (ranksMatch() || suitsMatch()) | |
} | |
func play() { | |
if ranksMatch() { cards.removeAtIndexes(3, 2, 1, 0) } | |
else if suitsMatch() { cards.removeAtIndexes(2, 1) } | |
} | |
func add( card:Card ) { cards.insert(card, atIndex: 0) } | |
func ranksMatch() -> Bool { return cards[0].rank == cards[3].rank } | |
func suitsMatch() -> Bool { return cards[1].suit == cards[2].suit } | |
} | |
struct Game { | |
var deck = Deck() | |
var hand = Hand() | |
func play() -> Bool { | |
while !deck.isEmpty { | |
hand.add( deck.drawCard() ) | |
while hand.canPlay { hand.play() } | |
} | |
return hand.isEmpty | |
} | |
} | |
let games = 1000 | |
var wins = 0 | |
for _ in 0..games { if Game().play() { wins++ } } | |
let winningPercentage = Double(wins) / Double(games) | |
println("Played \(games) games, \(wins) (\(winningPercentage)%) wins.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
'Card Game' in Swift
I don't know what this card game is called. I often use it when fiddling with a new language. The rules are:
When you play it by hand you effectively never win, so I have written several of these for various languages (Python, Ruby, JavaScript, Erlang, Go, Clojure, to name a few) and have pretty much settled on an approximate 0.002% chance of winning.
To run this you need Xcode 6 (atm in beta), start a new Command-Line OSX app and paste this code into
main.swift
.