Eine Möglichkeit besteht darin, ein Array von Indizes zu generieren, die Ihre Karten darstellen. Mischen Sie dieses Array und entfernen Sie die Indizes aus diesem Array, während Sie eine Karte zeichnen.
// generate random list of indices from 0...12 four each
var cardIndices = (0...51).map {($0 % 13, arc4random())}.sort{$0.1 < $1.1}.map{$0.0}
// To get a card, remove last card from deck
let last = cardIndices.removeLast()
// use the index to look up the picture
let randomCard = picture[last]
// It's also easy to check how many cards you have left in your deck
let remaining = cardIndices.count
Dies funktioniert, indem zuerst ein Array von Tupeln erstellt wird, die eine Zahl von 0 bis 12 und eine zufällige ganze Zahl enthalten. Dann wird dieses Array nach dem zufälligen Integer-Element im Tupel sortiert, und dann wird map
verwendet, um nur das Array von Indizes zu trennen, wobei Sie ein zufälliges Array von Int
mit Werten von 0 ... 12 (jeweils vier Werte) erhalten.
Hier ist es in der Klassenform.
import UIKit
struct Card {
let image: UIImage
let text: String
}
class Deck {
private let cards:[Card] = [
Card(image: UIImage(named: "Card2")!, text: "Velg en som må drikke"),
Card(image: UIImage(named: "Card3")!, text: "Drikk selv"),
Card(image: UIImage(named: "Card4")!, text: "Alle jenter må drikke"),
Card(image: UIImage(named: "Card5")!, text: "Tommelen"),
Card(image: UIImage(named: "Card6")!, text: "Alle gutter må drikke"),
Card(image: UIImage(named: "Card7")!, text: "Pek på himmelen"),
Card(image: UIImage(named: "Card8")!, text: "Drikkepartner"),
Card(image: UIImage(named: "Card9")!, text: "Rim"),
Card(image: UIImage(named: "Card10")!, text: "Kategori"),
Card(image: UIImage(named: "CardJack")!, text: "Lag en regel"),
Card(image: UIImage(named: "CardQueen")!, text: "Spørsmålsrunde"),
Card(image: UIImage(named: "CardKing")!, text: "Hell drikke i koppen"),
Card(image: UIImage(named: "CardAce")!, text: "Fossefall")
]
private var cardIndices = [Int]()
var cardsInDeck: Int { return cardIndices.count }
func shuffleCards() {
cardIndices = (0...51).map{($0 % 13, arc4random())}.sort{$0.1 < $1.1}.map{$0.0}
}
func drawCard() -> Card {
if cardIndices.count == 0 {
shuffleCards()
}
let last = cardIndices.removeLast()
return cards[last]
}
}
Hinweise:
- Die
cards
und cardIndices
haben private
gemacht worden, diese Angaben von einem Benutzer von Deck
zu verstecken.
- Dank @ Paulw11s Vorschlag verwendet diese Lösung jetzt eine
struct
, um eine Karte darzustellen. Dies hält die Daten zusammen und bietet einen schönen Wert, der von drawCard
zurückgegeben werden kann.
- Der Benutzer eines
Deck
können erstellen Deck
mit Deck()
, können sie shuffleCards()
nennen das Deck, überprüfen Sie die cardsInDeck
Eigenschaft randomisieren, um herauszufinden, wie viele gemischte Karten stehen zur Verfügung, und sie können drawCard()
die nächste Karte aus dem erhalten rufen Deck.
Wie
Für die Viewcontroller verwenden, die das Deck steuert, fügen Sie eine Eigenschaft auf den Viewcontroller:
class MyGame: UIViewController {
var deck = Deck()
// the rest of the code
}
Dann, wenn Sie eine Karte benötigen, beispielsweise innerhalb eines @IBAction
für eine Schaltfläche, rufen Sie einfach deck.drawCard
:
@IBAction func turnOverNextCard(button: UIButton) {
let card = deck.drawCard()
// Use the image and text to update the UI
topCardImageView.image = card.image
topCardLabel.text = card.text
// I'm not going to wait for the deck to shuffle itself
if deck.cardsInDeck < 10 {
deck.shuffleCards()
}
}
Haarspalterei: A Better Shuffle
Meine Shuffle Routine das Deck schlurft durch eine zufällige UInt32
mit jeder Karte zuordnet und dann das Deck von diesen Werten zu sortieren. Wenn dieselbe Zufallszahl für zwei Karten erzeugt wird, ist es möglich, dass frühere Karten im Stapel gegenüber späteren Karten bevorzugt sind (oder umgekehrt, abhängig vom Sortieralgorithmus). Das ist wirklich Haare spalten, sondern im Interesse der beste Shuffle möglich aus, bietet mir die folgende Alternative:
func shuffleCards() {
cardIndices = (0...51).map {$0 % 13}
for i in (1...51).reverse() {
let rand = Int(arc4random_uniform(UInt32(i + 1)))
(cardIndices[i], cardIndices[rand]) = (cardIndices[rand], cardIndices[i])
}
}
Dieser Algorithmus auf die Fisher-Yates shuffle basiert.
Sie haben werden halten Spur von dem, was gezeichnet wurde. –
So kann jede Karte maximal 4 mal zurückgegeben werden, oder? –
@appzYourLife Ja, richtig. Genau wie ein echtes Kartenspiel. –