IOS随机卡片游戏 - 火环

Rod*_*kes 0 ios swift

所以我正在创建一款纸牌游戏Ring of Fire.我存储了这样的图像:

var picture:[UIImage] = [
        UIImage(named: "Card2")!,
        UIImage(named: "Card3")!,
        UIImage(named: "Card4")!,
        UIImage(named: "Card5")!,
        UIImage(named: "Card6")!,
        UIImage(named: "Card7")!,
        UIImage(named: "Card8")!,
        UIImage(named: "Card9")!,
        UIImage(named: "Card10")!,
        UIImage(named: "CardJack")!,
        UIImage(named: "CardQueen")!,
        UIImage(named: "CardKing")!,
        UIImage(named: "CardAce")!,
        ]
Run Code Online (Sandbox Code Playgroud)

每张卡片都有当前卡片下方显示的文字:

var name:String = ""

    var files = ["Velg en som må drikke", // 2
                 "Drikk selv", // 3
                 "Alle jenter må drikke", // 4
                 "Tommelen", // 5
                 "Alle gutter må drikke", // 6
                 "Pek på himmelen", // 7
                 "Drikkepartner", // 8
                 "Rim", // 9
                 "Kategori", // 10
                 "Lag en regel", // Jack
                 "Spørsmålsrunde", // Queen
                 "Hell drikke i koppen", // King
                 "Fossefall"] // Ace
Run Code Online (Sandbox Code Playgroud)

这就是我选择随机卡的方式:

func imageTapped(img: AnyObject){
        if(cardsleftLabel.text != "0") {

            let randomNumber = Int(arc4random_uniform(UInt32(files.count)))
            let image = picture[randomNumber]

            cardImage.image = image
            name = files[randomNumber]
        }
        else{
            print("No more cards")
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题是该卡可能出现多次,这是错误的.每张卡有4张,所以如何在游戏中控制它?所以CardJack不出现6次?

vac*_*ama 5

一种方法是生成代表您的卡片的索引数组.随机播放该数组,然后在绘制卡片时从该数组中删除索引.

// 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
Run Code Online (Sandbox Code Playgroud)

这首先创建一个元组数组,其中包含一个0 ... 12的数字和一个随机整数.然后该元素按元组中的随机整数元素排序,然后map用于分离索引数组,为您留下一个Int值为0 ... 12(每个值为四个值)的随机数组.


这是课堂形式.

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]
    }
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • cardscardIndices已经做出private隐藏从用户这些细节Deck.
  • 感谢@ Paulw11的建议,此解决方案现在使用a struct来表示卡片.这样可以将数据保持在一起,并提供可以从中返回的漂亮值drawCard.
  • a的用户Deck可以创建一个Deckwith Deck(),他们可以调用shuffleCards()随机化套牌,检查cardsInDeck属性以找出有多少可用的洗牌,并且他们可以打电话drawCard()从牌组中获取下一张牌.

如何使用

对于控制套牌的viewController,向viewController添加一个属性:

class MyGame: UIViewController {
    var deck = Deck()

    // the rest of the code
 }
Run Code Online (Sandbox Code Playgroud)

然后,当您需要一张卡片时,例如在@IBAction一个按钮内部,只需拨打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()
    }
}
Run Code Online (Sandbox Code Playgroud)

分裂头发:更好的随机播放

我的洗牌程序通过将随机UInt32与每张卡相关联然后按照这些值对牌组进行排序来洗牌.如果为两张牌生成相同的随机数,那么牌组中的早期牌可能比后来的牌更受青睐(反之亦然,取决于排序算法).这真的是分裂的头发,但为了提供最好的洗牌,我提供以下替代方案:

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])
    }
}
Run Code Online (Sandbox Code Playgroud)

该算法基于Fisher-Yates shuffle.