新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
とすれば良さそうです。