Swiftで行こう…第11回「トランプ3」(もちゃち)
ーーーMavericks Xcode6.1ーーー
無限ループを防ぐ方法はいろいろあると思いますが、僕が思いついたのは、カードの残り枚数を数えて、0になったらリセットするという方法と、使ったかどうかで、全部使っているかチェックして使っていたらリセットするという方法です。サンプルを示します。
カードの残り枚数を数える。
以下ソースコードです。
import UIKit class ViewController: UIViewController { @IBOutlet weak var lblCard: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. for i in 0 ..< cardCount { check += [false] } rest = cardCount } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } let mark: [String] = ["♣️","♦️","♥️","♠️"] let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"] let cardCount: UInt32 = 53 var rest: UInt32 = 0 var check: [Bool] = [] @IBAction func btnGoTouch(sender: AnyObject) { if rest == 0 { for i in 0 ..< Int(cardCount) { check[i] = false } rest = cardCount var alert = UIAlertView() alert.title = "初期化" alert.message = "カードを配り直します" alert.addButtonWithTitle("OK") alert.show() } var card = 0 do { card = Int(arc4random_uniform(cardCount)) } while check[card] check[card] = true rest-- if card == cardCount - 1 { lblCard.text = "JK" } else { lblCard.text = mark[card / 13] + number[card % 13] } } }
実行してみましょう。
変数の型を変更しました。こちらの方が良いと思います。
以下ソースコードです。
import UIKit class ViewController: UIViewController { @IBOutlet weak var lblCard: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. for i in 0 ..< cardCount { check += [false] } rest = cardCount } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } let mark: [String] = ["♣️","♦️","♥️","♠️"] let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"] let cardCount = 53 var rest = 0 var check: [Bool] = [] @IBAction func btnGoTouch(sender: AnyObject) { if rest == 0 { for i in 0 ..< cardCount { check[i] = false } rest = cardCount var alert = UIAlertView() alert.title = "初期化" alert.message = "カードを配り直します" alert.addButtonWithTitle("OK") alert.show() } var card = 0 do { card = Int(arc4random_uniform(UInt32(cardCount))) } while check[card] check[card] = true rest-- if card == cardCount - 1 { lblCard.text = "JK" } else { lblCard.text = mark[card / 13] + number[card % 13] } } }
実行してみましょう。
全部使っているかチェックする。この場合は全部チェックするので、数を間違えて無限ループに入る心配はありません。
以下ソースコードです。
import UIKit class ViewController: UIViewController { @IBOutlet weak var lblCard: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. for i in 0 ..< cardCount { check += [false] } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } let mark: [String] = ["♣️","♦️","♥️","♠️"] let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"] let cardCount = 53 var check: [Bool] = [] @IBAction func btnGoTouch(sender: AnyObject) { var chk: Bool = true for i in 0 ..< cardCount { chk = check[i] if chk == false { break } } if chk { for i in 0 ..< cardCount { check[i] = false } var alert = UIAlertView() alert.title = "初期化" alert.message = "カードを配り直します" alert.addButtonWithTitle("OK") alert.show() } var card = 0 do { card = Int(arc4random_uniform(UInt32(cardCount))) } while check[card] check[card] = true if card == cardCount - 1 { lblCard.text = "JK" } else { lblCard.text = mark[card / 13] + number[card % 13] } } }
実行してみましょう。
カードの残り枚数を数えて表示するようにしました。
以下ソースコードです。
import UIKit class ViewController: UIViewController { @IBOutlet weak var lblCard: UILabel! @IBOutlet weak var lblCount: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. for i in 0 ..< cardCount { check += [false] } count = cardCount } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } let mark: [String] = ["♣️","♦️","♥️","♠️"] let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"] let cardCount = 53 var check: [Bool] = [] var count = 0 @IBAction func btnGoTouch(sender: AnyObject) { var chk: Bool = true for i in 0 ..< cardCount { chk = check[i] if chk == false { break } } if chk { for i in 0 ..< cardCount { check[i] = false } var alert = UIAlertView() alert.title = "初期化" alert.message = "カードを配り直します" alert.addButtonWithTitle("OK") alert.show() count = cardCount } count-- lblCount.text = count.description var card = 0 do { card = Int(arc4random_uniform(UInt32(cardCount))) } while check[card] check[card] = true if card == cardCount - 1 { lblCard.text = "JK" } else { lblCard.text = mark[card / 13] + number[card % 13] } } }
実行してみましょう。
この場合は、カードの残り枚数を数えていた方がすんなりいきます。
以下ソースコードです。
import UIKit class ViewController: UIViewController { @IBOutlet weak var lblCard: UILabel! @IBOutlet weak var lblCount: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. for i in 0 ..< cardCount { check += [false] } count = cardCount } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } let mark: [String] = ["♣️","♦️","♥️","♠️"] let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"] let cardCount = 53 var check: [Bool] = [] var count = 0 @IBAction func btnGoTouch(sender: AnyObject) { if count == 0 { for i in 0 ..< cardCount { check[i] = false } var alert = UIAlertView() alert.title = "初期化" alert.message = "カードを配り直します" alert.addButtonWithTitle("OK") alert.show() count = cardCount } count-- lblCount.text = count.description var card = 0 do { card = Int(arc4random_uniform(UInt32(cardCount))) } while check[card] check[card] = true if card == cardCount - 1 { lblCard.text = "JK" } else { lblCard.text = mark[card / 13] + number[card % 13] } } }
実行してみましょう。
とりあえず♣️だけ、全13枚が配られるか分かるソースコードにしてみます。ラベルを並べるだけでも結構面倒です。
以下ソースコードです。
import UIKit class ViewController: UIViewController { @IBOutlet weak var lblCard: UILabel! @IBOutlet weak var lblCount: UILabel! @IBOutlet weak var lblKA: UILabel! @IBOutlet weak var lblK2: UILabel! @IBOutlet weak var lblK3: UILabel! @IBOutlet weak var lblK4: UILabel! @IBOutlet weak var lblK5: UILabel! @IBOutlet weak var lblK6: UILabel! @IBOutlet weak var lblK7: UILabel! @IBOutlet weak var lblK8: UILabel! @IBOutlet weak var lblK9: UILabel! @IBOutlet weak var lblKT: UILabel! @IBOutlet weak var lblKJ: UILabel! @IBOutlet weak var lblKQ: UILabel! @IBOutlet weak var lblKK: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. for i in 0 ..< cardCount { check += [false] } count = cardCount } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } let mark: [String] = ["♣️","♦️","♥️","♠️"] let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"] let cardCount = 13 var check: [Bool] = [] var count = 0 @IBAction func btnGoTouch(sender: AnyObject) { if count == 0 { for i in 0 ..< cardCount { check[i] = false } lblKA.text = "" lblK2.text = "" lblK3.text = "" lblK4.text = "" lblK5.text = "" lblK6.text = "" lblK7.text = "" lblK8.text = "" lblK9.text = "" lblKT.text = "" lblKJ.text = "" lblKQ.text = "" lblKK.text = "" var alert = UIAlertView() alert.title = "初期化" alert.message = "カードを配り直します" alert.addButtonWithTitle("OK") alert.show() count = cardCount } count-- lblCount.text = count.description var card: Int do { card = Int(arc4random_uniform(UInt32(cardCount))) } while check[card] check[card] = true if card == 52 { lblCard.text = "JK" } else { lblCard.text = mark[card / 13] + number[card % 13] } switch card { case 0: lblKA.text = lblCard.text case 1: lblK2.text = lblCard.text case 2: lblK3.text = lblCard.text case 3: lblK4.text = lblCard.text case 4: lblK5.text = lblCard.text case 5: lblK6.text = lblCard.text case 6: lblK7.text = lblCard.text case 7: lblK8.text = lblCard.text case 8: lblK9.text = lblCard.text case 9: lblKT.text = lblCard.text case 10: lblKJ.text = lblCard.text case 11: lblKQ.text = lblCard.text default: lblKK.text = lblCard.text } } }
実行してみましょう。重複無く配られましたか?
さて問題です。今は、0〜12のランダムな数を発生させて、もし既に出ていたら、もう一度乱数を発生させるという方法を取っています。13枚なら大した事はないのですが、53枚だとある程度、不発が増えて来ます。最近のコンピュータは、演算速度が早いので問題にはなりませんが、少々気持ち悪いものです。一度出ているのでもう一度乱数を発生させるというのを止めさせる事は出来ないでしょうか?53枚だと枚数が多いし、♣️を13枚並べるようにした事で、何かソースコードに問題があった時に、発見しやすいという事で、今回の最後のソースコードを元にして下さい。