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

目次 通常版

 コンピュータが前の人のカードを引く処理を付け加えます。最初は難しくならないように二番目の組の人が、一番上の組から一枚引く処理を付け加えます。ユーザーは3番目か4番目の組を選ぶ事とします。

 「引く」ボタンを追加しています。

    ///2番目の人が1番目の人のカードを1枚引く
    @IBAction func hiku(_ sender: Any) {
        //1番目の人
        var i = 0
        //1番目の人のカードの数
        var kl = 0
        //1番目の人のカードをチェックする
        for j in 0 ..< 14 {
            //カードが無効なら
            if eachCard[i][j].tag == -1 {
                //1番目の人の最後のカード+1
                kl = j
                break
            }
        }
        //2番目の人が引いたカード
        let k = Int.random(in: 0 ..< kl)
        
        //2番目の人
        var ii = 1
        //引いたカードと同じナンバーのカードがあった
        var stop = false
        //引いたカードがジョーカー以外
        if eachCard[i][k].tag != 52 {
            //2番目の人のカードをチェックする
            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
                }
            }
        }
        //1番目の人のカード、2番目の人が引いたカードより後ろのカードを一つずつ詰める
        for j in k + 1 ..< 14 {
            eachCard[i][j - 1].tag = eachCard[i][j].tag
        }
        //1番目の人の最後のカードを無効に
        eachCard[i][13].tag = -1
        //表示する
        show()
    }

 4行目で、1番目の人を表すのに、i に0を入れています。これは将来的に2番目、3番目、4番目と i に1、2、3を入れる事で、1番目の人意外にも使えるように固定値の0を埋め込むのではなく、i としておいて、拡張に備えています。

 6行目で kl という変数を定義していますが、これは、8行目から15行目で1番目の人のカードの数が入ります。今までの処理で、カードを左詰にしていて、無効カードが出たら、それ以降は無効カードが続くだけなので、こういう処理が可能となっています。

 17行目で、2番目の人が1番目の人のカードを引いています。

 20行目で、2番目の人を表すのに、ii に1を入れています。これは先程説明した i と同じ理由です。

 22行目で、stop 変数を定義しています。引いたカードと同じナンバーのカードがあったら true になります。最初は false です。

 24行目で、ジョーカー以外としています。ジョーカーは52で、52%13=0なので、普通に処理すると、Aと判断されてしまいます。それを避ける為にまずジョーカーか調べています。

 26行目から、2番目の人のカードを調べています。少し飛ばして、33行目、無効カードが出たらループから抜けています。無効カードが出たら以降は無効カードなので、それ以上調べる必要がありません。38行目、ジョーカーだったら、次のループに行きます。43行目、引いたカード(eachCard[i][k])と2番目の人のカードの現在調査中のカード(eachCard[ii][jj])のナンバーが等しかったら stop 変数を true にしています。そこで次の28行目、stop が true だったら、詰める作業をしています。

    eachCard[ii][jj - 1].tag = eachCard[ii][jj].tag

ここで、stop が true になった後、次のループに入っているので、jj の値は+1されています。そこで jj – 1 で、同じナンバーのカードの位置になります。こうすると同じナンバーのカードが塗りつぶされます。一度 stop が true になったら、true のままなので、詰める作業は無効カードが出るまで続きます。

 50行目以降、同じナンバーのカードが無かった場合、最後に引いたカードを付け足しています。

 62行目からで、2番目の人が引いたカードを1番目の人のカードから除いています。

 66行目で、1番目の人の最後のカードを無効にしています。

 ここで解説していて、バグに気づいてしまいました。1番目の人のカードがAからKとJKの全14枚持っていた時に、8行目のループで break を通らずに終了してしまいます。その際 kl が0のままになってしまいます。これを防ぐには、6行目を

        var kl = 14

とすれば良さそうです。

目次 通常版

コメントを残す

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

CAPTCHA