新Swiftで行こう…第86回「ババ抜き8解説」 田部井保
カードをシャッフルする処理を加えます。とりあえず、一枚引くボタンのようにシャッフルするボタンを加えます。ユーザーが選ぶのは3番目とします。
///2番目の人のカードをシャッフルする
@IBAction func shuffle(_ sender: Any) {
//2番目の人
var i = 1
//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()
}
4行目で、i に1を入れ、2人目という事にしてあります。将来的には、ここを0なら1人目、2なら3人目、3なら4人目となります。
6行目で、2人目のカード枚数を入れる変数を定義しています。前回の反省からここを0ではなく14としました。
8行目で、2番目の人のカードを取っておく配列を定義しています。ここに一式移して、ここからランダムにカードを左詰で入れて行って、選ばれたカードは消して、どんどん列が短くなっていくという操作をします。
10行目からで、カードの枚数を調べる事と、8行目の配列にカードを1枚ずつ入れていくという事をしています。
23行目からで、カードをランダムに並べ替えています。カード枚数分ループしています。25行目で、最初はカード枚数までの乱数を、2回目( j = 1 )はカード枚数−1までの乱数を、3回目( j = 2 )はカード枚数−2までの乱数を発生させています。ストックした配列から1枚ずつ取り出して行くので、全体のカード数は1枚ずつ減っていきます。27行目で、2番目の人の左側のカードから順に引いたカードで埋めていきます。29行目からのループが、取っておいた配列から引いたカードを除いて行って、1枚ずつ減らしてゆく処理です。jj が引いた位置です、そこから最初は kl – 1 まで、このループの最後は kl – 1 に kl のものを入れています。k までとしてしまうと、最後は kl に kl + 1 のものを入れるという、存在しないものを入れてしまう為、kl – 1 としています。実際には kl – j – 1 ですが、最初は j は0です。j が1の2回目のループは、取っておいた配列は、1枚減っていると考えられるので、kl – 1 – 1 までとなります。ここで1枚減らした時に配列を短くしていないのですが、参照される事がない為、そのままにしてあります。ここで、分かりやすく j が0の時、jj が kl – 1 だった時、
for k in jj ..< kl - j - 1 {
は、
for k in kl - 1 ..< kl - 1 {
となり、ループを1回も回りません。それでも最後の1枚は、次回は無視されるので問題ありません。