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

目次 通常版

 ペアになったカードを除く処理です。

 追加部分のソースコードです。

    ///ペアを除くボタン押下時処理
    @IBAction func btnPairTouch(_ sender: Any) {
        //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
                    }
                }
            }
            //一人分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 = " "
                }
            }
        }
    }

 4行目で4人分のループをしています。ループ変数は i です。その中の6行目で13枚分のループをしています。ループ変数は j です。その中の13行目で、j +1から14枚目までのループをしています。ループ変数は k です。j 番目のカードと k 番目のカードを比較する為に j は0〜12の13枚分とし、k は j+1〜13の値を取る様にして、j が0の時は、k は1〜13となるので、1番目と2番目から14番目を順番に比較するという動作をしています。そして j 番目のカードと k 番目のカードのナンバー(ナンバーはカード番号%13で取得できます。カード番号はラベルのタグに入っているので、比較部分は20行目のソースの様になります)を比較して、同じだったら、それぞれのカードナンバーを−1にしています。その部分が19行目から27行目です。26行目で break とありますが、これは一番内側のループを抜ける命令です。同じカードが出たら、それを無効カード番号(−1)として、もうそれ以上次のカードと比較する必要はないので一番内側の k のループを抜けます。

 7行目から11行目ですが、カードがジョーカーの場合かカード番号が−1(無効)となっている場合は、10行目の continue 命令で次のループに入ります。ここは j のループの内側なので、もし j が2(3番目のカード)なら j を3(4番目のカード)として、6行目から再開します。この様に continue 命令は、その下の処理を飛ばして、次のループ( j が2だったら次の3)としてループの最初から始めるという動きをします。14行目から18行目も j が k に変わっただけで同じ処理です。

 30行目から41行目は、残っているカードを表にして出し、無効カードを空白にして出す処理です。

 続いて、空いた部分を詰める処理です。

    ///ペアを除くボタン押下時処理
    @IBAction func btnPairTouch(_ sender: Any) {
        //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
                }
            }
            //一人分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 = " "
                }
            }
        }
    }

 30行目から51行目までが追加した部分です。

 31行目で、無効カード(−1)が見つかったか保持する bool型の変数を定義しています。とりあえず初期値は false(見つかっていない)です。無効カードが見つかるまでは、詰める必要はありませんが、無効カードが見つかってからは、それ以降のカードは詰める必要が出てきます。

 33行目で左側のカードを0(1番目)にしています。35行目で、調査するカードを1番目から14番目までループさせています。

 34行目から51行目で無効カードの場合は何もせず、有効カードなら左側に詰めるという動作をします。

 37行目から39行目が調査カード位置に無効カードが見つかった時の処理なのですが、見つかったか保持する変数を true にしています。無効カードの場合は、それ以外の処理をする必要がない(詰める動作も、左側のカードを+1する動作もいらない)ので、それ以外の処理はしていません。40行目から50行目が調査カードが無効カードで無かった場合の処理ですが、ここで、無効カードが見つかったか保持する変数が true(見つかった)だった場合は、左側に詰める動作をしています。k の位置に j の位置のものを移して、j の位置のものは−1(無効)にしています。そして無効カードが見つかっているかどうかに関わらずに k の値を+1しています。有効カードなら次のカードにするし、無効カードなら、その無効カード位置に調査カードを移しているので、こちらも次のカードにする必要があります。

 今回、見直しをして通常版で気になったところを修正します。

    ///配るボタン
    @IBAction func btnGoTouch(_ sender: Any) {
        //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()
                    //カードを表示する
                    eachCard[i][j].text = cardObj.disp(card: eachCard[i][j].tag)
                }
            }
        }
    }

 10行目、2人目から4人目の14枚目のカード、何もしていなかったのですが、無効カードを表す−1を入れるようにしました。まあ普通は無いですが、ペアが全く無い場合にどういう動作をするか分からないので、ここで−1を入れるようにしておきました。

目次 通常版

コメントを残す

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

CAPTCHA