新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を入れるようにしておきました。