新Swiftで行こう…第92回「ババ抜き14解説」 田部井保

目次 通常版

 今まで作ってきたものを組み合わせて、ゲームが出来るようにします。

//
//  ViewController.swift
//  baba
//
//  Created by 保 Tabei on 2024/10/12.
//

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        //53枚のカードを並べる
        put53()
    }
    
    ///4人分のカードのラベル
    var eachCard: [[UILabel]] = [[],[],[],[]]
    ///4人の内どれを自分にするかのボタン
    var eachButton: [UIButton] = []
    ///カードクラス、ジョーカー込みで初期化
    var cardObj:Card = Card(cdCnt: Card.EnumCard.joker)
    
    ///53枚のカードを並べる関数
    func put53() {
        //4人分
        for i in 0 ..< 4 {
            //14枚(一人目)か13枚(2〜4人目)
            for j in 0 ..< 14 {
                //ラベルを生成
                let lbl = UILabel(frame: CGRectMake(0, 0, 50, 21))
                //ラベルの中心を設定
                lbl.center = CGPointMake(50 + 40 * CGFloat(j % 7), 150 + 120 * CGFloat(i) +
                                         50 * CGFloat(j / 7))
                //ラベルのテキスト位置を設定
                lbl.textAlignment = NSTextAlignment.center
                //2人目〜4人目の14枚目は空
                if i != 0 && j == 13 {
                    lbl.text = " "
                    //13枚目までと一人目の14枚目
                } else {
                    lbl.text = "⬛️"
                }
                //4人分のカードラベルに追加
                eachCard[i] += [lbl]
                //ラベルをフォームに追加
                self.view.addSubview(lbl)
            }
            //ボタンを生成
            let btn = UIButton(frame: CGRectMake(0, 0, 50, 21)) as UIButton
            //ボタンの中心を設定
            btn.center = CGPointMake(20, 150 + 120 * CGFloat(i) + 25)
            //ボタンの表示文字列を指定(白丸)
            btn.setTitle("⚪️", for: .normal)
            //ボタンのテキストカラーを設定
            btn.setTitleColor(UIColor.black, for: .normal)
            //ボタンが押された時に動作する関数を指定
            btn.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
            //ボタン式別用にタグにiを入れる
            btn.tag = i
            //ボタン配列に加える
            eachButton += [btn]
            //ボタンをフォームに追加
            self.view.addSubview(btn)
        }
        //配る
        share()
        //表示する
        show()
    }
    
    ///自分選択が出来るか
    var btnEnable = true
    
    ///自分選択ボタンが押された時の処理
    @objc func btnTapped(sender: UIButton) {
        //自分選択が出来ない時
        if btnEnable == false {
            //処理終了
            return
        }
        //4人分ループ
        for i in 0 ..< 4 {
            //押されたボタンの場合
            if eachButton[i] == sender {
                //タイトルが白丸なら
                if sender.currentTitle == "⚪️" {
                    //タイトルを黒丸に
                    sender.setTitle("⚫️", for: .normal)
                    //タイトルが黒丸なら
                } else {
                    //タイトルを白丸に
                    sender.setTitle("⚪️", for: .normal)
                }
                //押されたボタン以外
            } else {
                //タイトルを白丸にする
                eachButton[i].setTitle("⚪️", for: .normal)
            }
        }
    }
    
    ///配る
    func share() {
        //自分選択が出来る様に
        btnEnable = true
        //初期状態にする
        cardObj.reset()
        //4人分
        for i in 0 ..< 4 {
            //最大14枚
            for j in 0 ..< 14 {
                //2人〜4人目14枚目
                if i != 0 && j == 13 {
                    //無効カード
                    eachCard[i][j].tag = -1
                } else {
                    //カードを引いてtagに
                    eachCard[i][j].tag = cardObj.put()
                }
            }
        }
    }
    
    ///表示する
    func show() {
        //4人分
        for i in 0 ..< 4 {
            //最大14枚
            for j in 0 ..< 14 {
                //カードのタグが0以上なら
                if eachCard[i][j].tag >= 0 {
                    //カードの表を表示
                    eachCard[i][j].text = cardObj.disp(card: eachCard[i][j].tag)
                    //カードのタグが0より小さいなら
                } else {
                    //カードは空白
                    eachCard[i][j].text = " "
                }
            }
        }
    }
    
    ///再配布ボタン
    @IBAction func btnGoTouch(_ sender: Any) {
        //配る
        share()
        //表示する
        show()
    }
    
    ///ペアを除くボタン押下時処理
    @IBAction func btnPairTouch(_ sender: Any) {
        //選択されているかフラグとりあえず選択されていない
        var selected = false
        //4人分調べる
        for i in 0 ..< 4 {
            //黒丸があったら
            if eachButton[i].currentTitle == "⚫️" {
                //選択されている
                selected = true
                //自分(ユーザー)はi
                mine = i
                //ループを抜ける
                break
            }
        }
        //選択されていない時
        if !selected {
            //アラートを出す
            let alert = UIAlertController()
            alert.title = "選択"
            alert.message = "4組のうちのどれかを選択して下さい。"
            alert.addAction(UIAlertAction(title: "OK", style: .default))
            present(alert, animated: true, completion: nil)
            //処理を抜ける
            return
        }
        //自分選択が出来ない様に
        btnEnable = false
        //4人分ループ
        for i in 0 ..< 4 {
            //最大13枚ループ
            for j in 0 ..< 13 {
                //ジョーカーかカードのタグが−1なら次のjのループへ
                if (eachCard[i][j].tag == 52) || (eachCard[i][j].tag == -1) {
                    //以下の処理は行わず次のjのループへ
                    continue
                }
                //jの次のカードから14枚目までループ
                for k in j + 1 ..< 14 {
                    //ジョーカーかカードのタグが−1なら次のkのループへ
                    if (eachCard[i][k].tag == 52) || (eachCard[i][k].tag == -1) {
                        //以下の処理は行わず次のkのループへ
                        continue
                    }
                    //jの位置のカード番号とkの位置のカード番号が同じなら
                    if (eachCard[i][j].tag % 13) == (eachCard[i][k].tag % 13) {
                        //jの位置のカードのタグを−1に
                        eachCard[i][j].tag = -1
                        //kの位置のカードのタグを−1に
                        eachCard[i][k].tag = -1
                        //kのループは終了
                        break
                    }
                }
            }
            //無効カードが見つかったか保持する変数
            var find = false
            //左側のカード位置
            var k = 0
            //調査するカード位置
            for j in 0 ..< 14 {
                //調査カードが無効カードなら
                if eachCard[i][j].tag == -1 {
                    //無効カードが見つかった
                    find = true
                    //調査カードが無効カードでないなら
                } else {
                    //無効カードが見つかっていたら
                    if find {
                        //カードを左側に詰める
                        eachCard[i][k].tag = eachCard[i][j].tag
                        eachCard[i][j].tag = -1
                    }
                    //左側カード位置を+1する
                    k += 1
                }
            }
        }
        //表示する
        show()
        //現在の順番は0(1人目)
        step = 0
    }
    
    ///i+1番目の人のカードを次の人が引くrandmがtrueならコンピュータ、falseなら人間
    func take(i: Int, randm: Bool) {
        //i+1番目の人のカードの数
        var kl = 14
        //i+1番目の人のカードをチェックする
        for j in 0 ..< 14 {
            //カードが無効なら
            if eachCard[i][j].tag == -1 {
                //1番目の人の最後のカード+1
                kl = j
                break
            }
        }
        //i+1番目の人の次の人が引いたカード
        var k = 0
        //randmがtrueなら
        if randm {
            //引く位置をランダムに指定
            k = Int.random(in: 0 ..< kl)
        } else {
            //i+1番目の人のカード枚数分ループ
            for j in 0 ..< kl {
                //カード選択ボタン配列でタグが1のもの
                if eachCardButton[j].tag == 1 {
                    //ユーザーが引くカード位置決定
                    k = j
                    //ループを抜ける
                    break
                }
            }
        }
        
        //i+1番目の人の次の人
        var ii = 0
        //iが1〜3番目の人の場合はiに1を足したもの
        if i < 3 {
            ii = i + 1
            //iが4番目の人の場合は0
        } else {
            ii = 0
        }
        //引いたカードと同じナンバーのカードがあった
        var stop = false
        //引いたカードがジョーカー以外
        if eachCard[i][k].tag != 52 {
            //ii+1番目の人のカードをチェックする
            for jj in 0 ..< 14 {
                //引いたカードと同じナンバーのカードがあったら、詰める
                if stop {
                    //詰める
                    eachCard[ii][jj - 1].tag = eachCard[ii][jj].tag
                }
                //無効カードだったら
                if eachCard[ii][jj].tag == -1 {
                    //ループを抜ける
                    break
                }
                //ジョーカーなら次のループ
                if eachCard[ii][jj].tag == 52 {
                    //次のループ
                    continue
                }
                //引いたカードと同じナンバーのカードがあったら
                if (eachCard[ii][jj].tag % 13) == (eachCard[i][k].tag % 13) {
                    //フラグを立てる
                    stop = true
                }
            }
        }
        //引いたカードと同じナンバーのカードが無かったら
        if stop == false {
            //2番目の人のカードをチェック
            for jj in 0 ..< 14 {
                //無効カードが見つかったら
                if eachCard[ii][jj].tag == -1 {
                    //引いたカードをそこに置く
                    eachCard[ii][jj].tag = eachCard[i][k].tag
                    break
                }
            }
        }
        //i+1番目の人のカード、次の人が引いたカードより後ろのカードを一つずつ詰める
        for j in k + 1 ..< 14 {
            eachCard[i][j - 1].tag = eachCard[i][j].tag
        }
        //i+1番目の人の最後のカードを無効に
        eachCard[i][13].tag = -1
        //表示する
        show()
    }
    
    ///step+2番目の人がstep+1番目の人のカードを1枚引く
    func hiku() {
        //step+1番目の人のカードをstep+2番目の人が引く
        take(i: step, randm: true)
    }
    
    ///ユーザーが引くカードを選択するボタン配列
    var eachCardButton: [UIButton] = []
    
    ///step+1番目の人のカードをシャッフルする
    func shuffle() {
        //step+1番目の人
        let i = step
        //2番目の人のカード枚数
        var kl = 14
        //2番目の人のカードを取っておく配列
        var cardList: [Int] = []
        //2番目の人のカード、無効カードが出るまで検査
        for j in 0 ..< 14 {
            //無効カードが出たら
            if eachCard[i][j].tag == -1 {
                //2番目の人のカード枚数はj
                kl = j
                //ループを抜ける
                break
            }
            //2番目の人のカードを取っておく
            cardList += [eachCard[i][j].tag]
        }
        
        //2番目の人のカード枚数分ループ
        for j in 0 ..< kl {
            //ランダムにカードを選択、最初は2番目の人のカード枚数、順に1引いてゆく
            let jj = Int.random(in: 0 ..< kl - j)
            //2番目の人のカード、左から順にセットする
            eachCard[i][j].tag = cardList[jj]
            //ランダムに選択したカードを後ろのカードで順に詰める、段々最後のカードが1つ前に行く
            for k in jj ..< kl - j - 1 {
                //次のカードで今のカードを上書き
                cardList[k] = cardList[k + 1]
            }
        }
        //表示する
        show()
    }

    ///ユーザーの前の人のカードにボタンを付けてユーザーが引くカードを選択できる様にする
    func get()
    {
        //step+1番目の人
        let i = step
        //step+1番目の人のカード枚数
        var kl = 14
        //step+1番目の人のカード、無効カードが出るまで検査
        for j in 0 ..< 14 {
            //無効カードが出たら
            if eachCard[i][j].tag == -1 {
                //step+1番目の人のカード枚数はj
                kl = j
                //ループを抜ける
                break
            }
        }

        //step+1番目の人のカードにボタンを付けユーザーが引けるようにする
        //step+1番目の人のカードの数ループ
        for j in 0 ..< kl {
            //ボタンを生成する
            let btn = UIButton(frame: CGRectMake(0, 0, 50, 21))
            //ボタンの中心を指定
            btn.center = CGPointMake(50 + 40 * CGFloat(j % 7), 150 + 120 * CGFloat(i) + 50 * CGFloat(j / 7))
            //四角いマークをボタンのタイトルに
            btn.setTitle("◼︎", for: .normal)
            //ボタンを青に
            btn.setTitleColor(UIColor.blue, for: .normal)
            //ボタンが押された時にcardBtnTapped関数を呼ぶ
            btn.addTarget(self, action: #selector(cardBtnTapped), for: .touchUpInside)
            //タグを0に
            btn.tag = 0
            //ボタン配列に生成したボタンを追加
            eachCardButton += [btn]
            //ボタンを描画
            self.view.addSubview(btn)
        }
    }
    
    //カード選択ボタンが押された時に動作する関数
    @objc func cardBtnTapped(sender: UIButton) {
        //カード選択ボタン配列の全ボタンを青色に
        for cardBtn in eachCardButton {
            cardBtn.setTitleColor(UIColor.blue, for: .normal)
            //タグを0に
            cardBtn.tag = 0
        }
        //選んだボタンを赤色に
        sender.setTitleColor(UIColor.red, for: .normal)
        //タグを1に
        sender.tag = 1
    }
    
    ///ユーザーがstep+1番目の人のカードを引く処理
    func btnHikuTouch() {
        //step+1番目の人のカードをユーザーが引く
        take(i: step, randm: false)
        
        //カード選択ボタンを画面から消す
        for cardBtn in eachCardButton {
            cardBtn.removeFromSuperview()
        }
        //カード選択ボタン配列を消去する
        eachCardButton.removeAll()
    }
    
    //ユーザー並び替えボタン配列
    var eachChangeButton: [UIButton] = []
    
    //ユーザー並び替え開始
    func btnChangeTouch() {
        //ユーザー
        let i = mine
        //ユーザーのカード枚数
        var kl = 14
        //ユーザーのカードをチェックする
        for j in 0 ..< 14 {
            //無効カードだったら
            if eachCard[i][j].tag == -1 {
                //3番目の人のカード枚数はj
                kl = j
                //ループを抜ける
                break
            }
        }
        
        //ユーザーのカード枚数分並べ替えボタンを用意する
        for j in 0 ..< kl {
            //ボタンを生成する
            let btn = UIButton(frame: CGRectMake(0, 0, 50, 21))
            //ボタンの中心をセットする
            btn.center = CGPointMake(50 + 40 * CGFloat(j % 7), 150 + 120 * CGFloat(i) + 50 * CGFloat(j / 7))
            //小さい四角をカードの上に出す
            btn.setTitle("◼︎", for: .normal)
            //小さい四角を青色にする
            btn.setTitleColor(UIColor.blue, for: .normal)
            //ボタンが押された時cardChangeTapped関数を呼ぶ
            btn.addTarget(self, action: #selector(cardChangeTapped), for: .touchUpInside)
            //ボタンのタグを0にする
            btn.tag = 0
            //ユーザー並び替えボタン配列にボタンを追加
            eachChangeButton += [btn]
            //ボタンを画面に出す
            self.view.addSubview(btn)
        }
    }
    
    //ユーザー並び替えボタンのどれかが押された時
    @objc func cardChangeTapped(sender: UIButton) {
        //ユーザー
        let i = mine
        //前に選択していたものがあったらその位置
        var j = 0
        //今選択したボタンの位置
        var k = 0
        //ユーザー並び替えボタン配列分ループ
        for cardBtn in eachChangeButton {
            //今選択したボタンならループを抜ける
            if cardBtn == sender {
                break;
            }
            //位置を+1
            k += 1
        }
        //前に選択していたものがある(最初は無い)
        var dis = false
        //ユーザー並び替えボタン配列分ループ
        for cardBtn in eachChangeButton {
            //前に選択していたものが見つかったら
            if cardBtn.tag == 1 {
                //今の位置のカードをchangeに退避
                let change = eachCard[i][j].tag
                //今の位置のカードを新たに選択したカードで置き換える
                eachCard[i][j].tag = eachCard[i][k].tag
                //新たに選択した位置のカードを退避していたカード番号にする
                eachCard[i][k].tag = change
                //今の位置の選択ボタンの色を青色に
                cardBtn.setTitleColor(UIColor.blue, for: .normal)
                //今の位置の選択ボタンのtagを0に
                cardBtn.tag = 0
                //前に選択していたものがあった
                dis = true
                //表示する
                show()
                //ループを抜ける
                break
            }
            //位置を+1
            j += 1
        }
        //前に選択していたものが無い場合
        if dis == false {
            //新たに選択した位置のボタンを赤に
            sender.setTitleColor(UIColor.red, for: .normal)
            //新たに選択したボタンのtagを1に
            sender.tag = 1
        }
    }

    ///ユーザー並び替え終了後処理
    func changeFinishTouch() {
        //step+2番目の人がstep+1番目の人(ユーザー)のカードを引く
        take(i: step, randm: true)
        
        //ユーザー並び替えボタンを画面から消す
        for changeBtn in eachChangeButton {
            changeBtn.removeFromSuperview()
        }
        //ユーザー並び替えボタン配列クリア
        eachChangeButton.removeAll()
    }
    
    ///現在の順番
    var step = 0
    ///自分の順番
    var mine = 0
    
    ///逐次処理
    @IBAction func btnExecTouch(_ sender: Any) {
        //自分の前の人を特定
        var reMine = mine - 1
        //自分が1番目だったら
        if reMine == -1 {
            //前の人は最後の人
            reMine = 3
        }
        //現在の順番が前の人なら
        if step == reMine {
            //iに前の人を入れる
            let i = step
            //前の人のカード枚数
            var kl = 14
            //前の人のカード調査
            for j in 0 ..< 14 {
                //無効カードが見つかったら
                if eachCard[i][j].tag == -1 {
                    //前の人のカード枚数はj
                    kl = j
                    //ループを抜ける
                    break
                }
            }
            //カード選択ボタンのどれも選択されていない
            var k = true
            //前の人のカード分ループ
            for j in 0 ..< kl {
                //カード選択ボタンが選択されている
                if eachCardButton[j].tag == 1 {
                    //カード選択ボタンが選択されている
                    k = false
                    //ループを抜ける
                    break
                }
            }
            //カード選択ボタンのどれも選択されていない場合
            if k {
                //選択を促すアラートを表示
                let alert = UIAlertController()
                alert.title = "選択"
                alert.message = "引くカードを選択して下さい。"
                alert.addAction(UIAlertAction(title: "OK", style: .default))
                present(alert, animated: true, completion: nil)
                return
            }
            //ユーザーが前の人のカードを引く処理
            btnHikuTouch()
            //現在の順番を進める(ユーザーに)
            step += 1
            if step > 3 {
                step = 0
            }
            //ユーザー並び替え開始
            btnChangeTouch()
        //現在の順番が自分なら
        } else if step == mine {
            //ユーザー並び替え終了後処理
            changeFinishTouch()
            //現在の順番を次の人に
            step += 1
            if step > 3 {
                step = 0
            }
            //次の人のカードをシャッフル
            shuffle()
        //ユーザー、ユーザーの前の人でない場合
        } else {
            //step+2番目の人がstep+1番目の人のカードを引いて
            hiku()
            //現在の順番を次の人に
            step += 1
            if step > 3 {
                step = 0
            }
            //次の人のカードをシャッフル
            shuffle()
        }
        //順番が自分の前の人なら
        if step == reMine {
            //ユーザーの前の人のカードにボタンを付けてユーザーが引くカードを選択できる様にする
            get()
        }
    }
}

 今回の変更はとても難しいです。155行目からのペアを除くボタンの処理ですが、まずユーザーが何番目かを選択したかどうかを調べる処理が入っていました。ここの165行目で、自分が何番目かを設定しています。そして最後の236行目で、現在の順番として0(1人目)をセットしています。

 そして、330行目から

    ///step+2番目の人がstep+1番目の人のカードを1枚引く
    func hiku() {
        //step+1番目の人のカードをstep+2番目の人が引く
        take(i: step, randm: true)
    }

となりました。以前は

    ///2番目の人が1番目の人のカードを1枚引く
    @IBAction func hiku(_ sender: Any) {
        //1番目の人のカードを2番目の人が引く
        take(i: 0, randm: true)
    }

となっていた所です。以前はボタンを押すと動作する関数だったのですが、新しいものは、ただの関数になりました。以前は i に0を送っていたのですが、新しいものは i に step を送っています。ここで step が0の時は、以前のものと全く一緒になります。以前は、1番目の人のカードを2番目の人が引くという限定された処理だったのですが、新しいものは、何番目の人でも対応出来るようになっています。

 そして、339行目から

    ///step+1番目の人のカードをシャッフルする
    func shuffle() {
        //step+1番目の人
        let i = step

となりました。以前は

    ///2番目の人のカードをシャッフルする
    @IBAction func shuffle(_ sender: Any) {
        //2番目の人
        let i = 1

となっていた所です。以前は hiku 関数と同様、ボタンを押すと動作する関数だったのですが、新しいものは、ただの関数になりました。以前は i に1をセットして、2番目の人のカードをシャッフルするものだったのですが、新しいものは、i に step をセットしています。step に1を入れると以前のものと同じ様に2番目の人のカードをシャッフルします。新しいものは、何番目の人のものでもシャッフル出来ます。

 そしてこのシャッフル関数、シャッフルした後に、ユーザーが引くために2番目の人のカードにボタンを置いて、ユーザーにカードを引かせる準備をしていたのですが、今回その部分は切り離しました。以前はユーザーが3番目で2番目の人がシャッフルした後にユーザーが引くという流れだけだったのですが、シャッフル関数が2番目以外でも出来るようになり、ユーザーが引くのは、どこを選択したかに寄るので、get 関数として切り離しました。

    ///ユーザーの前の人のカードにボタンを付けてユーザーが引くカードを選択できる様にする
    func get()
    {
        //step+1番目の人
        let i = step
        //step+1番目の人のカード枚数
        var kl = 14
        //step+1番目の人のカード、無効カードが出るまで検査
        for j in 0 ..< 14 {
            //無効カードが出たら
            if eachCard[i][j].tag == -1 {
                //step+1番目の人のカード枚数はj
                kl = j
                //ループを抜ける
                break
            }
        }

        //step+1番目の人のカードにボタンを付けユーザーが引けるようにする
        //step+1番目の人のカードの数ループ
        for j in 0 ..< kl {
            //ボタンを生成する
            let btn = UIButton(frame: CGRectMake(0, 0, 50, 21))
            //ボタンの中心を指定
            btn.center = CGPointMake(50 + 40 * CGFloat(j % 7), 150 + 120 * CGFloat(i) + 50 * CGFloat(j / 7))
            //四角いマークをボタンのタイトルに
            btn.setTitle("◼︎", for: .normal)
            //ボタンを青に
            btn.setTitleColor(UIColor.blue, for: .normal)
            //ボタンが押された時にcardBtnTapped関数を呼ぶ
            btn.addTarget(self, action: #selector(cardBtnTapped), for: .touchUpInside)
            //タグを0に
            btn.tag = 0
            //ボタン配列に生成したボタンを追加
            eachCardButton += [btn]
            //ボタンを描画
            self.view.addSubview(btn)
        }
    }

 ここの379行目から392行目は、新たに追加した部分です。シャッフル関数で、step + 1 番目の人のカード枚数を求めていたのですが、今回分離した為、ここでもカード枚数を求める処理を追加しました。後半は、step + 1 番目の人のカードにユーザーが引くカードを選択する為のボタンを表示している部分です。step + 1 番目の人はユーザーの前の人になります。

 そして430行目から

    ///ユーザーがstep+1番目の人のカードを引く処理
    func btnHikuTouch() {
        //step+1番目の人のカードをユーザーが引く
        take(i: step, randm: false)

となりました。以前は

    ///ユーザーが2番目の人のカードを引く処理
    @IBAction func btnHikuTouch(_ sender: Any) {
        //2番目の人のカード3番目の人(ユーザー)が引く
        take(i: 1, randm: false)

となっていた所です。こちらも、ただの関数になっています。2番目の人のカードを3番目の人(ユーザー)が引く処理だったのですが、ユーザーが3番目限定ではなくなり、どこでも良くなりました。この後にカード選択ボタンを画面から削除して、配列を初期化しています。

 そして446行目から

    //ユーザー並び替え開始
    func btnChangeTouch() {
        //ユーザー
        let i = mine

となっています。以前は

    //ユーザー並び替え開始ボタン押下時処理
    @IBAction func btnChangeTouch(_ sender: Any) {
        //3番目の人(ユーザー)
        let i = 2

となっていた所です。ただの関数になりました。ユーザーが3番目固定ではなくて、どこでも対応出来るようになりました。

 482行目、以前は i = 2 だったのが i = mine となりました。3番目固定ではなくなりました。

 536行目から

    ///ユーザー並び替え終了後処理
    func changeFinishTouch() {
        //step+2番目の人がstep+1番目の人(ユーザー)のカードを引く
        take(i: step, randm: true)

となっています。以前は

    ///ユーザー並び替え終了後処理
    @IBAction func changeFinishTouch(_ sender: Any) {
        //4番目の人が3番目の人(ユーザー)のカードを引く
        take(i: 2, randm: true)

となっていました。もう説明は不要かと思います。この後では、ユーザー並び替えボタンを画面から消して、配列を初期化しています。

 550行目で、現在の順番を表す、step を定義しています。

 552行目で自分(ユーザー)の順番を表す、mine を定義しています。

 554行目からが、今回の肝となる部分です。結構複雑だと思います。

    ///逐次処理
    @IBAction func btnExecTouch(_ sender: Any) {
        //自分の前の人を特定
        var reMine = mine - 1
        //自分が1番目だったら
        if reMine == -1 {
            //前の人は最後の人
            reMine = 3
        }
        //現在の順番が前の人なら
        if step == reMine {
            //iに前の人を入れる
            let i = step
            //前の人のカード枚数
            var kl = 14
            //前の人のカード調査
            for j in 0 ..< 14 {
                //無効カードが見つかったら
                if eachCard[i][j].tag == -1 {
                    //前の人のカード枚数はj
                    kl = j
                    //ループを抜ける
                    break
                }
            }
            //カード選択ボタンのどれも選択されていない
            var k = true
            //前の人のカード分ループ
            for j in 0 ..< kl {
                //カード選択ボタンが選択されている
                if eachCardButton[j].tag == 1 {
                    //カード選択ボタンが選択されている
                    k = false
                    //ループを抜ける
                    break
                }
            }
            //カード選択ボタンのどれも選択されていない場合
            if k {
                //選択を促すアラートを表示
                let alert = UIAlertController()
                alert.title = "選択"
                alert.message = "引くカードを選択して下さい。"
                alert.addAction(UIAlertAction(title: "OK", style: .default))
                present(alert, animated: true, completion: nil)
                return
            }
            //ユーザーが前の人のカードを引く処理
            btnHikuTouch()
            //現在の順番を進める(ユーザーに)
            step += 1
            if step > 3 {
                step = 0
            }
            //ユーザー並び替え開始
            btnChangeTouch()
        //現在の順番が自分なら
        } else if step == mine {
            //ユーザー並び替え終了後処理
            changeFinishTouch()
            //現在の順番を次の人に
            step += 1
            if step > 3 {
                step = 0
            }
            //次の人のカードをシャッフル
            shuffle()
        //ユーザー、ユーザーの前の人でない場合
        } else {
            //step+2番目の人がstep+1番目の人のカードを引いて
            hiku()
            //現在の順番を次の人に
            step += 1
            if step > 3 {
                step = 0
            }
            //次の人のカードをシャッフル
            shuffle()
        }
        //順番が自分の前の人なら
        if step == reMine {
            //ユーザーの前の人のカードにボタンを付けてユーザーが引くカードを選択できる様にする
            get()
        }
    }

 今まで、色々作ってきたボタンは、最初の2つ「配布」ボタンと「ペア削除」ボタンを残して、ボタンではなくしました。そして、新たに追加したボタンの処理が今回の554行目からです。このボタンを押す毎に処理が一つずつ進みます。本来は、一つずつ止めずに、ユーザーの操作が必要なところで止めれば良いのですが、きちんと動作している事を確かめる為に、一つずつ止めています。また、ユーザーが1番目の時、ユーザーのカードを並べ替える処理をする為に並び替えボタンを出す必要があるのと、2番目の時、ユーザーが1番目の人のカードを引く為に1番目の人のカードを引くためのボタンを出す必要があるのですが、処理が複雑になるので、今回ユーザーは3番目か4番目を選ぶ事にして、単純化しました。ただそれでも複雑です。

 557行目から562行目で、自分の前の人の番号を reMine に入れています。

        //現在の順番が前の人なら
        if step == reMine {
            //iに前の人を入れる
            let i = step
            //前の人のカード枚数
            var kl = 14
            //前の人のカード調査
            for j in 0 ..< 14 {
                //無効カードが見つかったら
                if eachCard[i][j].tag == -1 {
                    //前の人のカード枚数はj
                    kl = j
                    //ループを抜ける
                    break
                }
            }
            //カード選択ボタンのどれも選択されていない
            var k = true
            //前の人のカード分ループ
            for j in 0 ..< kl {
                //カード選択ボタンが選択されている
                if eachCardButton[j].tag == 1 {
                    //カード選択ボタンが選択されている
                    k = false
                    //ループを抜ける
                    break
                }
            }
            //カード選択ボタンのどれも選択されていない場合
            if k {
                //選択を促すアラートを表示
                let alert = UIAlertController()
                alert.title = "選択"
                alert.message = "引くカードを選択して下さい。"
                alert.addAction(UIAlertAction(title: "OK", style: .default))
                present(alert, animated: true, completion: nil)
                return
            }
            //ユーザーが前の人のカードを引く処理
            btnHikuTouch()
            //現在の順番を進める(ユーザーに)
            step += 1
            if step > 3 {
                step = 0
            }
            //ユーザー並び替え開始
            btnChangeTouch()

 564行目からが、順番が前の人だった時の処理で、ここまででカード選択ボタンが出ている前提で、選択ボタンのどれかを選んでいなかったら、アラートを出して選択するように促して、return で処理を終了しています。選択されていたら、ユーザーが引く処理をして、カード選択ボタンを消し(btnHikuTouchの処理)、現在の順番を進めて、ユーザー並び替え処理を行います(btnChangeTouchの処理)。並べ替えボタンを出します。

        //現在の順番が自分なら
        } else if step == mine {
            //ユーザー並び替え終了後処理
            changeFinishTouch()
            //現在の順番を次の人に
            step += 1
            if step > 3 {
                step = 0
            }
            //次の人のカードをシャッフル
            shuffle()

 611行目からが、順番が自分だった時の処理で、ユーザー並び替え終了後処理を行います(changeFinishTouchの処理)。次の人がユーザーのカードを引いて、ユーザーのカード並べ替えボタンを消去する処理です。その後現在の順番を進めて、次の人のカードをシャッフルする処理が入ります。

        //ユーザー、ユーザーの前の人でない場合
        } else {
            //step+2番目の人がstep+1番目の人のカードを引いて
            hiku()
            //現在の順番を次の人に
            step += 1
            if step > 3 {
                step = 0
            }
            //次の人のカードをシャッフル
            shuffle()
        }

 622行目からが、順番が自分でも自分の前の人でもなかった場合で、カードを引いて、現在の順番を進めて、次の人のカードをシャッフルするという処理を行います。

 634行目で、順番が自分の前の人なら、ユーザーの前の人のカードにボタンを付けてユーザーが引くカードを選択できる様にします。

目次 通常版

コメントを残す

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

CAPTCHA