Swiftで行こう…第11回「トランプ3」(もちゃち)

2014-11-11

目次ページへ

ーーーMavericks Xcode6.1ーーー
無限ループを防ぐ方法はいろいろあると思いますが、僕が思いついたのは、カードの残り枚数を数えて、0になったらリセットするという方法と、使ったかどうかで、全部使っているかチェックして使っていたらリセットするという方法です。サンプルを示します。

M011-01

M011-02

カードの残り枚数を数える。
以下ソースコードです。

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]
        }
    }
}

実行してみましょう。

M011-03

M011-04

変数の型を変更しました。こちらの方が良いと思います。
以下ソースコードです。

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]
        }
    }
}

実行してみましょう。

M011-05

M011-06

全部使っているかチェックする。この場合は全部チェックするので、数を間違えて無限ループに入る心配はありません。
以下ソースコードです。

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]
        }
    }
}

実行してみましょう。

M011-07

M011-08

カードの残り枚数を数えて表示するようにしました。
以下ソースコードです。

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]
        }
    }
}

実行してみましょう。

M011-09

M011-10

この場合は、カードの残り枚数を数えていた方がすんなりいきます。
以下ソースコードです。

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]
        }
    }
}

実行してみましょう。

M011-11

M011-12

M011-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枚並べるようにした事で、何かソースコードに問題があった時に、発見しやすいという事で、今回の最後のソースコードを元にして下さい。

目次ページへ

Since1991 © Shimayugu All Rights Reserved.
アップルおよびアップルのロゴは、米国および他の国々で登録されたApple Inc.の商標です。
湘南マッキントッシュユーザーズグループは、独立したユーザグループで、Apple Japan合同会社が権限を与えた団体、支援する団体、またはその他に承認する団体ではありません。