2017-02-07 15 views
0

基本的には、シャッフルされた配列があります。配列のようなカードのデッキです:配列シャッフル後の結果の繰り返しなし

var rank = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"] 
var suit = ["♠", "♥","♦","♣"] 
var deck = [String]() 

私は、関数では、私はデッキをシャッフルするために作成した拡張機能を呼び出す

for t in suit { 
     for r in rank { 
      deck.append("\(r)\(t)") 
     } 
    } 

でデッキを作成するために、ループのために持っています。唯一のことは、結果がランダムであるが、私はカードは繰り返したくないんです

 deck.shuffle() 

(これは裏ランダムアソート52枚のカードを私にもたらします)。たとえば、結果が2♠の場合、印刷されたリストの後ろに2♥、2♦、2♣は必要ありません。

ご協力いただきましてありがとうございます。ありがとう!

+0

繰り返しがなくなるまで、これらの52をシャッフルしてみましたか? '52! = 8.065 x 10^67 'の方法でデッキをシャッフルするチャンスがあるので、シャッフルしなければならない回数はかなり小さい –

+0

はい、何が起こるのかは、UILabelがDeck.Firstが何であるかを印刷し、その後シャッフルします。私の唯一の問題は、シャッフルに続いて印刷された注文が繰り返されることを決して望んでいないことです。 –

+0

あなたは本当にデッキをシャッフルしたくありませんか? –

答えて

0

私が進める最善の方法は、変更されたKnuthシャッフルを使用することだと思います。以下のコードは完全な例です。 customshuffle.swiftに内容を保存した後、シェルでswiftc -o customshuffle customshuffle.swift && ./customshuffleを実行するだけです。

import Foundation 

let decksize = 52 


let rankStrings = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"] 
let suitStrings = ["♠", "♥","♦","♣"] 

struct card : Hashable, Equatable, CustomStringConvertible { 
    var rank: Int //1,2...,11,12,13 
    var suit: Int // 1,2,3,4 

    var hashValue: Int { 
     return rank + suit 
    } 
    static func == (lhs: card, rhs: card) -> Bool { 
     return lhs.rank == rhs.rank && lhs.suit == rhs.suit 
    } 

    var description: String { 
     return rankStrings[self.rank - 1] + suitStrings[self.suit - 1] 
    } 
} 

// seems like Swift still lacks a portable random number generator 
func portablerand(_ max: Int)->Int { 
     #if os(Linux) 
      return Int(random() % (max + 1)) // biased but I am in a hurry 
     #else 
      return Int(arc4random_uniform(UInt32(max))) 
     #endif 
} 

// we populate a data structure where the 
// cards are partitioned by rank and then suit (this is not essential) 

var deck = [[card]]() 
for i in 1...13 { 
    var thisset = [card]() 
    for j in 1...4 { 
     thisset.append(card(rank:i,suit:j)) 
    } 
    deck.append(thisset) 
} 

// we write answer in "answer" 
var answer = [card]() 
// we pick a card at random, first card is special 
var rnd = portablerand(decksize) 
answer.append(deck[rnd/4].remove(at: rnd % 4)) 

while answer.count < decksize { 
    // no matter what, we do not want to repeat this rank 
    let lastrank = answer.last!.rank 
    var myindices = [Int](deck.indices) 
    myindices.remove(at: lastrank - 1) 
    var totalchoice = 0 
    var maxbag = -1 
    for i in myindices { 
     totalchoice = totalchoice + deck[i].count 
     if maxbag == -1 || deck[i].count > deck[maxbag].count { 
     maxbag = i 
     } 
    } 
    if 2 * deck[maxbag].count >= totalchoice { 
    // we have to pick from maxbag 
    rnd = portablerand(deck[maxbag].count) 
    answer.append(deck[maxbag].remove(at: rnd)) 
    } else { 
    // any bag will do 
    rnd = portablerand(totalchoice) 
    for i in myindices { 
     if rnd >= deck[i].count { 
      rnd = rnd - deck[i].count 
     } else { 
      answer.append(deck[i].remove(at: rnd)) 
      break 
     } 
    } 
    } 
} 


for card in answer { 
    print(card) 
} 

これは速く計算することができますが、それは合理的に公正ですが、悲しいことではありません。速く走るあなたの拘束を「公正なシャッフル」にするのは難しいかもしれないと思う。

関連する問題