新Swiftで行こう…第72回「ポーカー10解説」 田部井保

目次 通常版

 一度しか変更出来ない様にします。

//
//  ViewController.swift
//  Poker
//
//  Created by 保 Tabei on 2024/10/03.
//

import UIKit

class ViewController: UIViewController {
    ///再配布ボタン
    @IBOutlet weak var btnRe: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        //5枚分のラベルを配置する
        for i in 0 ..< 5 {
            //ラベルを生成する
            let lbl = UILabel(frame: CGRectMake(0, 0, 50, 21))
            //ラベルの中心を指定する
            lbl.center = CGPointMake(100 + 50 * CGFloat(i), 250)
            //ラベルのテキスト配置を中央にする
            lbl.textAlignment = NSTextAlignment.center
            //ラベルの表示をカードが裏になっている様にする
            lbl.text = "⬛️"
            //ラベル配列に追加する
            eachCard += [lbl]
            //ラベルを画面上に配置する
            self.view.addSubview(lbl)
 
            //選択ボタンを生成する
            let btn = UIButton(frame: CGRectMake(0, 0, 50, 21)) as UIButton
            //ボタンの中心を指定する
            btn.center = CGPointMake(100 + 50 * CGFloat(i), 300)
            //ボタンのタイトルを「off」にする
            btn.setTitle("off", for: .normal)
            //ボタンのタイトルの色をグレーにする
            btn.setTitleColor(UIColor.systemGray, for: .normal)
            //ボタンが押された時に「btnTapped」関数が呼ばれるようにする
            btn.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
            //ボタンのタグに0から4の目印を付ける
            btn.tag = i
            //選択ボタン配列に追加する
            eachButton += [btn]
            //選択ボタンを画面上に配置する
            self.view.addSubview(btn)
        }
    }

    ///選択ボタンが押された時に動作する関数
    @objc func btnTapped(sender: UIButton) {
        //もしタイトルが「off」なら
        if sender.currentTitle == "off" {
            //タイトルを「on」にして
            sender.setTitle("on", for: .normal)
            //選択ボタンの所のカードを裏にする
            eachCard[sender.tag].text = "⬛️"
        //もしタイトルが「on」なら
        } else {
            //タイトルを「off」にして
            sender.setTitle("off", for: .normal)
            //選択ボタンの所のカードを表にする
            //カード番号はタグに入れてある
            let card = eachCard[sender.tag].tag
            //カード一時保持変数
            var strCard: String
            //ジョーカーの場合
            if card == 52 {
                strCard = "JK"
            //ジョーカー以外の場合
            } else {
                //カード一時保持変数にマークとナンバーを保持
                strCard = mark[card / 13] + number[card % 13]
            }
            //選択ボタンの所のカードを表示
            eachCard[sender.tag].text = strCard
        }
    }

    ///マーク保持配列
    let mark: [String] = ["♣️","♦️","❤️","♠️"]
    ///ナンバー保持配列
    let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"]

    ///カード枚数保持定数
    enum EnumCard {
        static let Count = 52
    }

    ///既に出ているかチェックする、出ていたらtrue
    ///出ていなかったらfalse、とりあえず
    ///EnumCard.Count枚分falseで埋める
    var check = [Bool](repeating: false, count: EnumCard.Count)

    ///残り枚数を保持する変数
    var count = EnumCard.Count

    ///ラベル配列
    var eachCard: [UILabel] = []

    ///選択ボタン配列
    var eachButton: [UIButton] = []

    ///カードを引いてiで指定した位置に出す
    func put(i: Int) {
        //今回引いたカードを特定する変数
        var card = 0
        //乱数を0から残り枚数−1の範囲で発生させる
        let randInt = Int.random(in: 0 ..< count)
        //発生させた乱数分ループ
        for j in 0 ... randInt {
            //カードが既に出ていたらcard + 1
            while check[card] {
                card += 1
            }
            //jがrandIntに達していなければcard + 1
            if j < randInt {
                card += 1
            }
        }
        //新たに出たカード既に出ているとマークする
        check[card] = true
        
        //残り枚数を1減算
        count -= 1
        
        //カード一時保持変数
        var strCard: String
        //ジョーカーの場合
        if card == 52 {
            strCard = "JK"
        //ジョーカー以外の場合
        } else {
            //カード一時保持変数にマークとナンバーを保持
            strCard = mark[card / 13] + number[card % 13]
        }
        //iの値によって表示位置にカード表示
        eachCard[i].text = strCard
        //表示したラベルのtagにcardを保存しておく
        eachCard[i].tag = card
    }

    ///役判定関数
    func flush() {
        //チェック変数
        var ck = 0
        //基準カード
        for i in 0 ..< 4 {
            //比較カード
            for j in i + 1 ..< 5 {
                //ナンバーが同じなら
                if eachCard[i].tag % 13 == eachCard[j].tag % 13 {
                    //チェック変数を+1する
                    ck += 1
                }
            }
        }
        //ペアのメッセージ保持変数
        var msg: String
        //チェック変数の値によりペア名を指定する
        switch ck {
        case 1:
            msg = "ワンペア"
        case 2:
            msg = "ツーペア"
        case 3:
            msg = "スリーカード"
        case 4:
            msg = "フルハウス"
        case 6:
            msg = "フォーカード"
        default:
            msg = ""
        }
        //ペアなら
        if ck > 0 {
            //ペアダイアログを表示
            let alert = UIAlertController()
            alert.title = "ペア"
            alert.message = msg + "です"
            alert.addAction(UIAlertAction(title: "OK", style: .default))
            present(alert, animated: true, completion: nil)
        //ペア以外
        } else {
            //フラッシュ変数とりあえずフラッシュ
            var chk = true
            //1番目(0の位置)のマークを取得(0〜3)
            let mark: Int = eachCard[0].tag / 13
            //2番目から5番目の位置のマークと比較
            for i in 1 ..< 5 {
                //1番目のマークと2〜5番目のマークを比較して違っていたら
                if mark != eachCard[i].tag / 13 {
                    //フラッシュ変数をfalse(フラッシュではない)に
                    chk = false
                    //ループを終了
                    break
                }
            }
            //エースがあるか
            var isAce = false
            //キングがあるか
            var isKing = false
            //5枚のカードについて調べる
            for i in 0 ..< 5 {
                //エースがあったら
                if eachCard[i].tag % 13 == 0 {
                    isAce = true
                }
                //キングがあったら
                if eachCard[i].tag % 13 == 12 {
                    isKing = true
                }
            }
            //エースとキング両方あったらup変数をtrueに
            let up = isAce && isKing
            //最小値変数を宣言
            var min = 0
            //最大値変数を宣言
            var max = 0
            //1番目から5番目までループ
            for i in 0 ..< 5 {
                //変数にそのカードのナンバーを入れる
                var val = eachCard[i].tag % 13
                //エースとキング両方があった場合
                if up {
                    //4以下のカードに
                    if val < 4 {
                        //13加える
                        val = val + 13
                    }
                }
                //1番目ならmin,maxにvalを入れる
                if i == 0 {
                    min = val
                    max = val
                //2番目以降
                } else {
                    //変数が最小値より小さい時
                    if val < min {
                        //最小値を変数に
                        min = val
                    }
                    //変数が最大値より大きい時
                    if max < val {
                        //最大値を変数に
                        max = val
                    }
                }
            }
            //ストレート変数とりあえずストレートでない
            var chk2 = false
            //ロイヤル判定とりあえずロイヤルでない
            var chk3 = false
            //最大値と最小値の差が丁度4の時
            if max - min == 4 {
                //ストレート変数、ストレートに
                chk2 = true
                //最大がエースなら
                if max == 13 {
                    //ロイヤル
                    chk3 = true
                }
            }
            //メッセージ保持変数
            var msg: String = ""
            //ロイヤルなら
            if chk3 {
                msg = "ロイヤル"
            }
            //ストレートなら
            if chk2 {
                //メッセージ変数にストレートを追加する
                msg += "ストレート"
            }
            //フラッシュなら
            if chk {
                //メッセージ変数にフラッシュを追加する
                msg += "フラッシュ"
            }
            //フラッシュ変数がtrueまたはストレート変数がtrue
            if chk || chk2 {
                //ストレート、フラッシュダイアログを表示
                let alert = UIAlertController()
                alert.title = msg
                alert.message = msg + "です"
                alert.addAction(UIAlertAction(title: "OK", style: .default))
                present(alert, animated: true, completion: nil)
            }
        }
    }

    ///開始ボタン押下時処理
    @IBAction func btnGoTouch(_ sender: Any) {
        //リセット
        //全カード出ていない事に
        for i in 0 ..< EnumCard.Count {
            check[i] = false
        }
        //残り枚数52枚
        count = EnumCard.Count
        //5枚引く
        for i in 0 ..< 5 {
            //カードを引いてiの位置に出力する
            put(i: i)
        }
        //役判定
        flush()
        //再配布ボタン有効
        btnRe.isEnabled = true
    }
    
    ///再配布ボタン押下時処理
    @IBAction func btnReTouch(_ sender: Any) {
        //再配布ボタン無効
        btnRe.isEnabled = false
        //5枚分調べる
        for i in 0 ..< 5 {
            //選択ボタンのタイトルがonなら
            if eachButton[i].currentTitle == "on" {
                //カードを引いてiの位置に出力する
                put(i: i)
                //選択ボタンのタイトルをoffにする
                eachButton[i].setTitle("off", for: .normal)
            }
        }
        //役判定
        flush()
    }
}

 再配布ボタンをプログラムで制御できる様にして、配布ボタンが押されたら有効に、再配布ボタンが押されたら無効にするだけです。変更は3箇所だけです。

 賭け点部分を整備します。

//
//  ViewController.swift
//  Poker
//
//  Created by 保 Tabei on 2024/10/03.
//

import UIKit

class ViewController: UIViewController {
    ///再配布ボタン
    @IBOutlet weak var btnRe: UIButton!
    ///点数ラベル
    @IBOutlet weak var lblPoint: UILabel!
    ///賭け点ラベル
    @IBOutlet weak var lblBet: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        //ポイント10点
        point = 10
        //賭け点0点
        betPoint = 0
        //点数表示
        display()

        //5枚分のラベルを配置する
        for i in 0 ..< 5 {
            //ラベルを生成する
            let lbl = UILabel(frame: CGRectMake(0, 0, 50, 21))
            //ラベルの中心を指定する
            lbl.center = CGPointMake(100 + 50 * CGFloat(i), 250)
            //ラベルのテキスト配置を中央にする
            lbl.textAlignment = NSTextAlignment.center
            //ラベルの表示をカードが裏になっている様にする
            lbl.text = "⬛️"
            //ラベル配列に追加する
            eachCard += [lbl]
            //ラベルを画面上に配置する
            self.view.addSubview(lbl)
 
            //選択ボタンを生成する
            let btn = UIButton(frame: CGRectMake(0, 0, 50, 21)) as UIButton
            //ボタンの中心を指定する
            btn.center = CGPointMake(100 + 50 * CGFloat(i), 300)
            //ボタンのタイトルを「off」にする
            btn.setTitle("off", for: .normal)
            //ボタンのタイトルの色をグレーにする
            btn.setTitleColor(UIColor.systemGray, for: .normal)
            //ボタンが押された時に「btnTapped」関数が呼ばれるようにする
            btn.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
            //ボタンのタグに0から4の目印を付ける
            btn.tag = i
            //選択ボタン配列に追加する
            eachButton += [btn]
            //選択ボタンを画面上に配置する
            self.view.addSubview(btn)
        }
    }

    ///選択ボタンが押された時に動作する関数
    @objc func btnTapped(sender: UIButton) {
        //もしタイトルが「off」なら
        if sender.currentTitle == "off" {
            //タイトルを「on」にして
            sender.setTitle("on", for: .normal)
            //選択ボタンの所のカードを裏にする
            eachCard[sender.tag].text = "⬛️"
        //もしタイトルが「on」なら
        } else {
            //タイトルを「off」にして
            sender.setTitle("off", for: .normal)
            //選択ボタンの所のカードを表にする
            //カード番号はタグに入れてある
            let card = eachCard[sender.tag].tag
            //カード一時保持変数
            var strCard: String
            //ジョーカーの場合
            if card == 52 {
                strCard = "JK"
            //ジョーカー以外の場合
            } else {
                //カード一時保持変数にマークとナンバーを保持
                strCard = mark[card / 13] + number[card % 13]
            }
            //選択ボタンの所のカードを表示
            eachCard[sender.tag].text = strCard
        }
    }

    ///マーク保持配列
    let mark: [String] = ["♣️","♦️","❤️","♠️"]
    ///ナンバー保持配列
    let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"]

    ///カード枚数保持定数
    enum EnumCard {
        static let Count = 52
    }

    ///既に出ているかチェックする、出ていたらtrue
    ///出ていなかったらfalse、とりあえず
    ///EnumCard.Count枚分falseで埋める
    var check = [Bool](repeating: false, count: EnumCard.Count)

    ///残り枚数を保持する変数
    var count = EnumCard.Count

    ///ラベル配列
    var eachCard: [UILabel] = []

    ///選択ボタン配列
    var eachButton: [UIButton] = []

    ///カードを引いてiで指定した位置に出す
    func put(i: Int) {
        //今回引いたカードを特定する変数
        var card = 0
        //乱数を0から残り枚数−1の範囲で発生させる
        let randInt = Int.random(in: 0 ..< count)
        //発生させた乱数分ループ
        for j in 0 ... randInt {
            //カードが既に出ていたらcard + 1
            while check[card] {
                card += 1
            }
            //jがrandIntに達していなければcard + 1
            if j < randInt {
                card += 1
            }
        }
        //新たに出たカード既に出ているとマークする
        check[card] = true
        
        //残り枚数を1減算
        count -= 1
        
        //カード一時保持変数
        var strCard: String
        //ジョーカーの場合
        if card == 52 {
            strCard = "JK"
        //ジョーカー以外の場合
        } else {
            //カード一時保持変数にマークとナンバーを保持
            strCard = mark[card / 13] + number[card % 13]
        }
        //iの値によって表示位置にカード表示
        eachCard[i].text = strCard
        //表示したラベルのtagにcardを保存しておく
        eachCard[i].tag = card
    }

    ///役判定関数
    func flush() {
        //チェック変数
        var ck = 0
        //基準カード
        for i in 0 ..< 4 {
            //比較カード
            for j in i + 1 ..< 5 {
                //ナンバーが同じなら
                if eachCard[i].tag % 13 == eachCard[j].tag % 13 {
                    //チェック変数を+1する
                    ck += 1
                }
            }
        }
        //ペアのメッセージ保持変数
        var msg: String
        //チェック変数の値によりペア名を指定する
        switch ck {
        case 1:
            msg = "ワンペア"
        case 2:
            msg = "ツーペア"
        case 3:
            msg = "スリーカード"
        case 4:
            msg = "フルハウス"
        case 6:
            msg = "フォーカード"
        default:
            msg = ""
        }
        //ペアなら
        if ck > 0 {
            //ペアダイアログを表示
            let alert = UIAlertController()
            alert.title = "ペア"
            alert.message = msg + "です"
            alert.addAction(UIAlertAction(title: "OK", style: .default))
            present(alert, animated: true, completion: nil)
        //ペア以外
        } else {
            //フラッシュ変数とりあえずフラッシュ
            var chk = true
            //1番目(0の位置)のマークを取得(0〜3)
            let mark: Int = eachCard[0].tag / 13
            //2番目から5番目の位置のマークと比較
            for i in 1 ..< 5 {
                //1番目のマークと2〜5番目のマークを比較して違っていたら
                if mark != eachCard[i].tag / 13 {
                    //フラッシュ変数をfalse(フラッシュではない)に
                    chk = false
                    //ループを終了
                    break
                }
            }
            //エースがあるか
            var isAce = false
            //キングがあるか
            var isKing = false
            //5枚のカードについて調べる
            for i in 0 ..< 5 {
                //エースがあったら
                if eachCard[i].tag % 13 == 0 {
                    isAce = true
                }
                //キングがあったら
                if eachCard[i].tag % 13 == 12 {
                    isKing = true
                }
            }
            //エースとキング両方あったらup変数をtrueに
            let up = isAce && isKing
            //最小値変数を宣言
            var min = 0
            //最大値変数を宣言
            var max = 0
            //1番目から5番目までループ
            for i in 0 ..< 5 {
                //変数にそのカードのナンバーを入れる
                var val = eachCard[i].tag % 13
                //エースとキング両方があった場合
                if up {
                    //4以下のカードに
                    if val < 4 {
                        //13加える
                        val = val + 13
                    }
                }
                //1番目ならmin,maxにvalを入れる
                if i == 0 {
                    min = val
                    max = val
                //2番目以降
                } else {
                    //変数が最小値より小さい時
                    if val < min {
                        //最小値を変数に
                        min = val
                    }
                    //変数が最大値より大きい時
                    if max < val {
                        //最大値を変数に
                        max = val
                    }
                }
            }
            //ストレート変数とりあえずストレートでない
            var chk2 = false
            //ロイヤル判定とりあえずロイヤルでない
            var chk3 = false
            //最大値と最小値の差が丁度4の時
            if max - min == 4 {
                //ストレート変数、ストレートに
                chk2 = true
                //最大がエースなら
                if max == 13 {
                    //ロイヤル
                    chk3 = true
                }
            }
            //メッセージ保持変数
            var msg: String = ""
            //ロイヤルなら
            if chk3 {
                msg = "ロイヤル"
            }
            //ストレートなら
            if chk2 {
                //メッセージ変数にストレートを追加する
                msg += "ストレート"
            }
            //フラッシュなら
            if chk {
                //メッセージ変数にフラッシュを追加する
                msg += "フラッシュ"
            }
            //フラッシュ変数がtrueまたはストレート変数がtrue
            if chk || chk2 {
                //ストレート、フラッシュダイアログを表示
                let alert = UIAlertController()
                alert.title = msg
                alert.message = msg + "です"
                alert.addAction(UIAlertAction(title: "OK", style: .default))
                present(alert, animated: true, completion: nil)
            }
        }
    }

    ///開始ボタン押下時処理
    @IBAction func btnGoTouch(_ sender: Any) {
        //リセット
        //全カード出ていない事に
        for i in 0 ..< EnumCard.Count {
            check[i] = false
        }
        //残り枚数52枚
        count = EnumCard.Count
        //5枚引く
        for i in 0 ..< 5 {
            //カードを引いてiの位置に出力する
            put(i: i)
        }
        //役判定
        flush()
        //再配布ボタン有効
        btnRe.isEnabled = true
    }
    
    ///再配布ボタン押下時処理
    @IBAction func btnReTouch(_ sender: Any) {
        //再配布ボタン無効
        btnRe.isEnabled = false
        //5枚分調べる
        for i in 0 ..< 5 {
            //選択ボタンのタイトルがonなら
            if eachButton[i].currentTitle == "on" {
                //カードを引いてiの位置に出力する
                put(i: i)
                //選択ボタンのタイトルをoffにする
                eachButton[i].setTitle("off", for: .normal)
            }
        }
        //役判定
        flush()
    }
    
    ///ポイント
    var point = 0
    ///賭け点
    var betPoint = 0
    
    ///点数表示
    func display() {
        //ポイント表示
        lblPoint.text = point.description
        //賭け点表示
        lblBet.text = betPoint.description
    }

    ///賭け点プラスボタン押下時処理
    @IBAction func btnPlusTouch(_ sender: Any) {
        //ポイント0点より大の時
        if point > 0 {
            //ポイント−1
            point -= 1
            //賭け点+1
            betPoint += 1
        }
        //点数表示
        display()
    }
    
    ///賭け点マイナスボタン押下時処理
    @IBAction func btnMinusTouch(_ sender: Any) {
        //賭け点0点より大の時
        if betPoint > 0 {
            //賭け点−1
            betPoint -= 1
            //ポイント+1
            point += 1
        }
        //点数表示
        display()
    }
}

 今回の変更は、そんなに難しくないのではと思います。

目次 通常版

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA