[swift]IOS 随机卡游戏-火环

标签: ios Swift
发布时间: 2017/3/6 22:56:50
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

所以我创建了一个纸牌游戏,火环。我有存储这样的图片︰

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")!,
        ]

每个卡有下当前的卡显示文本︰

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

这是我如何选择一个随机的卡︰

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")
        }
    }

问题是,卡可能会出现多次,,这是错误的。怎么可以在我的游戏控制,有的每个卡,4?因此, CardJack 不出现 6 次?

解决方法 1:

做到这一种方法是生成数组代表您的卡的指标。 洗牌、 该数组,然后从该数组中删除指数作为你抽一张牌。

// 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

这是通过首先创建一个元组包含一个介于 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]
    }
}

备注︰

  • cardscardIndices 进行了 private 要隐藏这些细节从用户的 Deck
  • 由于 @Paulw11 的建议,本解决方案现在使用 struct 来代表一张卡。 这一起保持数据并提供一个很好的值,可以从返回 drawCard
  • 用户的 Deck 可以创建 DeckDeck() ,它们可以调用 shuffleCards() 随机在甲板上,检查 cardsInDeck 属性,以找出多少洗牌卡是可用的和他们可以调用 drawCard() 从甲板上获取下一张卡片。

如何使用

对于 viewController,控制在甲板上,向 viewController 添加一个属性︰

class MyGame: UIViewController {
    var deck = Deck()

    // the rest of the code
 }

然后当你需要一张卡,例如里面的 @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()
    }
}

分裂的头发︰ 更好的洗牌

我洗牌例程通过关联随机洗牌 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])
    }
}

该算法基于Fisher 茨洗牌

官方微信
官方QQ群
31647020